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. |