Chromium Code Reviews| Index: pkg/analyzer/lib/src/fasta/ast_builder.dart |
| diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart |
| index 6f7f95a97f69c147f2ee11a9bf26a21a1b8f60cf..8396f26ca1f006fdb6d0a3b7f023c1b172f09a74 100644 |
| --- a/pkg/analyzer/lib/src/fasta/ast_builder.dart |
| +++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart |
| @@ -394,7 +394,8 @@ class AstBuilder extends ScopeListener { |
| Statement elsePart = popIfNotNull(elseToken); |
| Statement thenPart = pop(); |
| Expression condition = pop(); |
| - analyzer.BeginToken leftParenthesis = ifToken.next; |
| + analyzer.BeginToken leftParenthesis = |
| + unsafeToken(ifToken.next, TokenType.OPEN_PAREN); |
| push(ast.ifStatement(ifToken, ifToken.next, condition, |
| leftParenthesis.endGroup, thenPart, elseToken, elsePart)); |
| } |
| @@ -556,7 +557,8 @@ class AstBuilder extends ScopeListener { |
| exitLocalScope(); |
| exitContinueTarget(); |
| exitBreakTarget(); |
| - analyzer.BeginToken leftParenthesis = forKeyword.next; |
| + analyzer.BeginToken leftParenthesis = |
| + unsafeToken(forKeyword.next, TokenType.OPEN_PAREN); |
| VariableDeclarationList variableList; |
| Expression initializer; |
| @@ -584,7 +586,7 @@ class AstBuilder extends ScopeListener { |
| condition, |
| rightSeparator, |
| updates, |
| - leftParenthesis.endGroup, |
| + leftParenthesis?.endGroup, |
| body)); |
| } |
| @@ -846,7 +848,7 @@ class AstBuilder extends ScopeListener { |
| covariantKeyword: covariantKeyword, |
| type: typeOrFunctionTypedParameter.returnType, |
| thisKeyword: thisKeyword, |
| - period: thisKeyword.next, |
| + period: unsafeToken(thisKeyword.next, TokenType.PERIOD), |
| typeParameters: typeOrFunctionTypedParameter.typeParameters, |
| parameters: typeOrFunctionTypedParameter.parameters); |
| } |
| @@ -1060,6 +1062,7 @@ class AstBuilder extends ScopeListener { |
| if (identical('native', token.stringValue) && parser != null) { |
| Token nativeKeyword = token; |
| Token semicolon = parser.parseLiteralString(token.next); |
| + // TODO(brianwilkerson) Should this be using ensureSemicolon? |
|
danrubel
2017/08/31 17:27:50
Just FYI... I'm working on removing this code beca
Brian Wilkerson
2017/08/31 17:29:37
Agreed.
|
| token = parser.expectSemicolon(semicolon); |
| StringLiteral name = pop(); |
| pop(); // star |
| @@ -1167,8 +1170,7 @@ class AstBuilder extends ScopeListener { |
| Token semicolon) { |
| debugEvent("Import"); |
| List<Combinator> combinators = pop(); |
| - SimpleIdentifier prefix; |
| - if (asKeyword != null) prefix = pop(); |
| + SimpleIdentifier prefix = popIfNotNull(asKeyword); |
| List<Configuration> configurations = pop(); |
| StringLiteral uri = pop(); |
| List<Annotation> metadata = pop(); |
| @@ -1227,19 +1229,17 @@ class AstBuilder extends ScopeListener { |
| void endConditionalUri(Token ifKeyword, Token equalitySign) { |
| debugEvent("ConditionalUri"); |
| StringLiteral libraryUri = pop(); |
| - StringLiteral value; |
| - if (equalitySign != null) { |
| - value = pop(); |
| - } |
| + StringLiteral value = popIfNotNull(equalitySign); |
| DottedName name = pop(); |
| // TODO(paulberry,ahe): what if there is no `(` token due to an error in the |
| // file being parsed? It seems like we need the parser to do adequate error |
| // recovery and then report both the ifKeyword and leftParen tokens to the |
| // listener. |
| - Token leftParen = ifKeyword.next; |
| + Token leftParen = unsafeToken(ifKeyword.next, TokenType.OPEN_PAREN); |
| // TODO(paulberry,ahe): the parser should report the right paren token to |
| // the listener. |
| - Token rightParen = name.endToken.next; |
| + Token lastToken = value?.endToken ?? equalitySign ?? name?.endToken; |
| + Token rightParen = unsafeToken(lastToken.next, TokenType.CLOSE_PAREN); |
| push(ast.configuration(ifKeyword, leftParen, name, equalitySign, value, |
| rightParen, libraryUri)); |
| } |
| @@ -1452,7 +1452,7 @@ class AstBuilder extends ScopeListener { |
| } |
| // TODO(paulberry,ahe): seems hacky. It would be nice if the parser passed |
| // in a reference to the "of" keyword. |
| - var ofKeyword = partKeyword.next; |
| + var ofKeyword = unsafeToken(partKeyword.next, analyzer.Keyword.OF); |
| List<Annotation> metadata = pop(); |
| Comment comment = pop(); |
| directives.add(ast.partOfDirective( |
| @@ -1719,10 +1719,12 @@ class AstBuilder extends ScopeListener { |
| debugEvent("Enum"); |
| List<EnumConstantDeclaration> constants = popList(count); |
| // TODO(paulberry,ahe): the parser should pass in the openBrace token. |
| - var openBrace = enumKeyword.next.next as analyzer.BeginToken; |
| + var openBrace = |
| + unsafeToken(enumKeyword.next.next, TokenType.OPEN_CURLY_BRACKET) |
| + as analyzer.BeginToken; |
| // TODO(paulberry): what if the '}' is missing and the parser has performed |
| // error recovery? |
| - Token closeBrace = openBrace.endGroup; |
| + Token closeBrace = openBrace?.endGroup; |
| SimpleIdentifier name = pop(); |
| List<Annotation> metadata = pop(); |
| Comment comment = pop(); |
| @@ -1956,6 +1958,14 @@ class AstBuilder extends ScopeListener { |
| } |
| library.addCompileTimeError(message, charOffset, uri); |
| } |
| + |
| + /// A marker method used to mark locations where a token is being located in |
| + /// an unsafe way. In all such cases the parser needs to be fixed to pass in |
| + /// the token. |
| + Token unsafeToken(Token token, TokenType tokenType) { |
| + // TODO(brianwilkerson) Eliminate the need for this method. |
| + return token.type == tokenType ? token : null; |
| + } |
| } |
| /// Data structure placed on the stack to represent a class body. |