blob: 389c2300e4b3817eb1c29d3312170e75547b5f5a [file] [log] [blame]
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of analyzer.parser;
/**
* Proxy implementation of the analyzer parser, implemented in terms of the
* Fasta parser.
*/
abstract class ParserAdapter implements Parser {
@override
Token currentToken;
/**
* The fasta parser being wrapped.
*/
final fasta.Parser fastaParser;
/**
* The builder which creates the analyzer AST data structures
* based on the Fasta parser.
*/
final AstBuilder astBuilder;
ParserAdapter(this.currentToken, ErrorReporter errorReporter, Uri fileUri,
{bool allowNativeClause: false})
: fastaParser = new fasta.Parser(null),
astBuilder = new AstBuilder(errorReporter, fileUri, true) {
fastaParser.enableSetLiterals = IsEnabledByDefault.set_literals;
fastaParser.listener = astBuilder;
astBuilder.parser = fastaParser;
astBuilder.allowNativeClause = allowNativeClause;
}
@override
set allowNativeClause(bool value) {
astBuilder.allowNativeClause = value;
}
/// Enables or disables non-nullable by default.
void set enableNonNullable(bool value) {
if (IsExpired.non_nullable && value != IsEnabledByDefault.non_nullable) {
throw new StateError(
'non_nullable may only be set to ${IsEnabledByDefault.non_nullable}');
}
astBuilder.enableNonNullable = value;
}
@override
bool get enableOptionalNewAndConst => false;
@override
void set enableOptionalNewAndConst(bool enable) {}
@override
void set enableSetLiterals(bool value) {
if (IsExpired.set_literals && value != IsEnabledByDefault.set_literals) {
throw new StateError(
'set_literals may only be set to ${IsEnabledByDefault.set_literals}');
}
fastaParser.enableSetLiterals = value;
}
@override
void set parseFunctionBodies(bool parseFunctionBodies) {
astBuilder.parseFunctionBodies = parseFunctionBodies;
}
@override
set parseGenericMethods(_) {}
/// Append the given token to the end of the token stream,
/// and update the token's offset.
appendToken(Token token, Token newToken) {
while (!token.next.isEof) {
token = token.next;
}
newToken
..offset = token.end
..setNext(token.next);
token.setNext(newToken);
}
@override
Expression parseAdditiveExpression() => parseExpression2();
@override
Annotation parseAnnotation() {
currentToken = fastaParser
.parseMetadata(fastaParser.syntheticPreviousToken(currentToken))
.next;
return astBuilder.pop();
}
@override
Expression parseArgument() {
currentToken = new SimpleToken(TokenType.OPEN_PAREN, 0)
..setNext(currentToken);
appendToken(currentToken, new SimpleToken(TokenType.CLOSE_PAREN, 0));
currentToken = fastaParser
.parseArguments(fastaParser.syntheticPreviousToken(currentToken))
.next;
MethodInvocation invocation = astBuilder.pop();
return invocation.argumentList.arguments[0];
}
@override
ArgumentList parseArgumentList() {
currentToken = fastaParser
.parseArguments(fastaParser.syntheticPreviousToken(currentToken))
.next;
var result = astBuilder.pop();
return result is MethodInvocation ? result.argumentList : result;
}
@override
Expression parseAssignableExpression(bool primaryAllowed) =>
parseExpression2();
@override
Expression parseBitwiseAndExpression() => parseExpression2();
@override
Expression parseBitwiseOrExpression() => parseExpression2();
@override
Expression parseBitwiseXorExpression() => parseExpression2();
@override
ClassMember parseClassMember(String className) {
astBuilder.classDeclaration = astFactory.classDeclaration(
null,
null,
null,
new Token(Keyword.CLASS, 0),
astFactory.simpleIdentifier(
new fasta.StringToken.fromString(TokenType.IDENTIFIER, className, 6)),
null,
null,
null,
null,
null /* leftBracket */,
<ClassMember>[],
null /* rightBracket */,
);
currentToken = fastaParser.parseClassOrMixinMember(currentToken);
ClassDeclaration declaration = astBuilder.classDeclaration;
astBuilder.classDeclaration = null;
return declaration.members.isNotEmpty ? declaration.members[0] : null;
}
@override
List<Combinator> parseCombinators() {
currentToken = fastaParser
.parseCombinatorStar(fastaParser.syntheticPreviousToken(currentToken))
.next;
return astBuilder.pop();
}
@override
CompilationUnit parseCompilationUnit(Token token) {
currentToken = token;
return parseCompilationUnit2();
}
@override
CompilationUnit parseCompilationUnit2() {
currentToken = fastaParser.parseUnit(currentToken);
CompilationUnitImpl compilationUnit = astBuilder.pop();
compilationUnit.localDeclarations = astBuilder.localDeclarations;
compilationUnit.hasPragmaAnalyzerNonNullable =
astBuilder.hasPragmaAnalyzerNonNullable;
return compilationUnit;
}
@override
Expression parseConditionalExpression() => parseExpression2();
@override
Configuration parseConfiguration() {
currentToken = fastaParser
.parseConditionalUri(fastaParser.syntheticPreviousToken(currentToken))
.next;
return astBuilder.pop();
}
@override
Expression parseConstExpression() => parseExpression2();
@override
CompilationUnit parseDirectives(Token token) {
currentToken = token;
return parseDirectives2();
}
@override
CompilationUnit parseDirectives2() {
currentToken = fastaParser.parseDirectives(currentToken);
return astBuilder.pop();
}
@override
DottedName parseDottedName() {
currentToken = fastaParser
.parseDottedName(fastaParser.syntheticPreviousToken(currentToken))
.next;
return astBuilder.pop();
}
@override
Expression parseEqualityExpression() => parseExpression2();
@override
Expression parseExpression(Token token) {
currentToken = token;
return parseExpression2();
}
@override
Expression parseExpression2() {
currentToken = fastaParser
.parseExpression(fastaParser.syntheticPreviousToken(currentToken))
.next;
return astBuilder.pop();
}
@override
Expression parseExpressionWithoutCascade() => parseExpression2();
@override
FormalParameterList parseFormalParameterList({bool inFunctionType: false}) {
currentToken = fastaParser
.parseFormalParametersRequiredOpt(
fastaParser.syntheticPreviousToken(currentToken),
inFunctionType
? fasta.MemberKind.GeneralizedFunctionType
: fasta.MemberKind.NonStaticMethod)
.next;
return astBuilder.pop();
}
@override
FunctionBody parseFunctionBody(
bool mayBeEmpty, ParserErrorCode emptyErrorCode, bool inExpression) {
currentToken = fastaParser.parseAsyncModifierOpt(
fastaParser.syntheticPreviousToken(currentToken));
currentToken =
fastaParser.parseFunctionBody(currentToken, inExpression, mayBeEmpty);
return astBuilder.pop();
}
@override
FunctionExpression parseFunctionExpression() => parseExpression2();
@override
Expression parseLogicalAndExpression() => parseExpression2();
@override
Expression parseLogicalOrExpression() => parseExpression2();
@override
Expression parseMultiplicativeExpression() => parseExpression2();
@override
InstanceCreationExpression parseNewExpression() => parseExpression2();
@override
Expression parsePostfixExpression() => parseExpression2();
@override
Identifier parsePrefixedIdentifier() => parseExpression2();
@override
Expression parsePrimaryExpression() {
currentToken = fastaParser
.parsePrimary(fastaParser.syntheticPreviousToken(currentToken),
fasta.IdentifierContext.expression)
.next;
return astBuilder.pop();
}
@override
Expression parseRelationalExpression() => parseExpression2();
@override
Expression parseRethrowExpression() => parseExpression2();
@override
Expression parseShiftExpression() => parseExpression2();
@override
SimpleIdentifier parseSimpleIdentifier(
{bool allowKeyword: false, bool isDeclaration: false}) =>
parseExpression2();
@override
Statement parseStatement(Token token) {
currentToken = token;
return parseStatement2();
}
@override
Statement parseStatement2() {
currentToken = fastaParser
.parseStatement(fastaParser.syntheticPreviousToken(currentToken))
.next;
return astBuilder.pop();
}
@override
StringLiteral parseStringLiteral() => parseExpression2();
@override
SymbolLiteral parseSymbolLiteral() => parseExpression2();
@override
Expression parseThrowExpression() => parseExpression2();
@override
Expression parseThrowExpressionWithoutCascade() => parseExpression2();
AnnotatedNode parseTopLevelDeclaration(bool isDirective) {
currentToken = fastaParser.parseTopLevelDeclaration(currentToken);
return (isDirective ? astBuilder.directives : astBuilder.declarations)
.removeLast();
}
@override
TypeAnnotation parseTypeAnnotation(bool inExpression) {
Token previous = fastaParser.syntheticPreviousToken(currentToken);
currentToken = fasta
.computeType(previous, true, !inExpression)
.parseType(previous, fastaParser)
.next;
return astBuilder.pop();
}
@override
TypeArgumentList parseTypeArgumentList() {
Token previous = fastaParser.syntheticPreviousToken(currentToken);
currentToken = fasta
.computeTypeParamOrArg(previous)
.parseArguments(previous, fastaParser)
.next;
return astBuilder.pop();
}
@override
TypeName parseTypeName(bool inExpression) {
Token previous = fastaParser.syntheticPreviousToken(currentToken);
currentToken = fasta
.computeType(previous, true, !inExpression)
.parseType(previous, fastaParser)
.next;
return astBuilder.pop();
}
@override
TypeParameter parseTypeParameter() {
currentToken = new SyntheticBeginToken(TokenType.LT, 0)
..endGroup = new SyntheticToken(TokenType.GT, 0)
..setNext(currentToken);
appendToken(currentToken, currentToken.endGroup);
TypeParameterList typeParams = parseTypeParameterList();
return typeParams.typeParameters[0];
}
@override
TypeParameterList parseTypeParameterList() {
Token token = fastaParser.syntheticPreviousToken(currentToken);
currentToken = fasta
.computeTypeParamOrArg(token, true)
.parseVariables(token, fastaParser)
.next;
return astBuilder.pop();
}
@override
Expression parseUnaryExpression() => parseExpression2();
}
/**
* Replacement parser based on Fasta.
*/
class _Parser2 extends ParserAdapter {
/**
* The source being parsed.
*/
final Source _source;
@override
bool enableUriInPartOf = true;
factory _Parser2(Source source, AnalysisErrorListener errorListener,
{bool allowNativeClause: false}) {
var errorReporter = new ErrorReporter(errorListener, source);
return new _Parser2._(source, errorReporter, source.uri,
allowNativeClause: allowNativeClause);
}
_Parser2._(this._source, ErrorReporter errorReporter, Uri fileUri,
{bool allowNativeClause: false})
: super(null, errorReporter, fileUri,
allowNativeClause: allowNativeClause);
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}