Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: pkg/analyzer/lib/src/fasta/ast_builder.dart

Issue 3012663002: Mark unsafe token access in AstBuilder (Closed)
Patch Set: Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library fasta.analyzer.ast_builder; 5 library fasta.analyzer.ast_builder;
6 6
7 import 'package:analyzer/analyzer.dart'; 7 import 'package:analyzer/analyzer.dart';
8 import 'package:analyzer/dart/ast/ast_factory.dart' show AstFactory; 8 import 'package:analyzer/dart/ast/ast_factory.dart' show AstFactory;
9 import 'package:analyzer/dart/ast/standard_ast_factory.dart' as standard; 9 import 'package:analyzer/dart/ast/standard_ast_factory.dart' as standard;
10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; 10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType;
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 bool hasExpression, Token beginToken, Token endToken) { 387 bool hasExpression, Token beginToken, Token endToken) {
388 debugEvent("ReturnStatement"); 388 debugEvent("ReturnStatement");
389 Expression expression = hasExpression ? pop() : null; 389 Expression expression = hasExpression ? pop() : null;
390 push(ast.returnStatement(beginToken, expression, endToken)); 390 push(ast.returnStatement(beginToken, expression, endToken));
391 } 391 }
392 392
393 void endIfStatement(Token ifToken, Token elseToken) { 393 void endIfStatement(Token ifToken, Token elseToken) {
394 Statement elsePart = popIfNotNull(elseToken); 394 Statement elsePart = popIfNotNull(elseToken);
395 Statement thenPart = pop(); 395 Statement thenPart = pop();
396 Expression condition = pop(); 396 Expression condition = pop();
397 analyzer.BeginToken leftParenthesis = ifToken.next; 397 analyzer.BeginToken leftParenthesis =
398 unsafeToken(ifToken.next, TokenType.OPEN_PAREN);
398 push(ast.ifStatement(ifToken, ifToken.next, condition, 399 push(ast.ifStatement(ifToken, ifToken.next, condition,
399 leftParenthesis.endGroup, thenPart, elseToken, elsePart)); 400 leftParenthesis.endGroup, thenPart, elseToken, elsePart));
400 } 401 }
401 402
402 void handleNoInitializers() { 403 void handleNoInitializers() {
403 debugEvent("NoInitializers"); 404 debugEvent("NoInitializers");
404 if (!isFullAst) return; 405 if (!isFullAst) return;
405 push(NullValue.ConstructorInitializerSeparator); 406 push(NullValue.ConstructorInitializerSeparator);
406 push(NullValue.ConstructorInitializers); 407 push(NullValue.ConstructorInitializers);
407 } 408 }
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 void endForStatement(Token forKeyword, Token leftSeparator, 550 void endForStatement(Token forKeyword, Token leftSeparator,
550 int updateExpressionCount, Token endToken) { 551 int updateExpressionCount, Token endToken) {
551 debugEvent("ForStatement"); 552 debugEvent("ForStatement");
552 Statement body = pop(); 553 Statement body = pop();
553 List<Expression> updates = popList(updateExpressionCount); 554 List<Expression> updates = popList(updateExpressionCount);
554 Statement conditionStatement = pop(); 555 Statement conditionStatement = pop();
555 Object initializerPart = pop(); 556 Object initializerPart = pop();
556 exitLocalScope(); 557 exitLocalScope();
557 exitContinueTarget(); 558 exitContinueTarget();
558 exitBreakTarget(); 559 exitBreakTarget();
559 analyzer.BeginToken leftParenthesis = forKeyword.next; 560 analyzer.BeginToken leftParenthesis =
561 unsafeToken(forKeyword.next, TokenType.OPEN_PAREN);
560 562
561 VariableDeclarationList variableList; 563 VariableDeclarationList variableList;
562 Expression initializer; 564 Expression initializer;
563 if (initializerPart is VariableDeclarationStatement) { 565 if (initializerPart is VariableDeclarationStatement) {
564 variableList = initializerPart.variables; 566 variableList = initializerPart.variables;
565 } else { 567 } else {
566 initializer = initializerPart as Expression; 568 initializer = initializerPart as Expression;
567 } 569 }
568 570
569 Expression condition; 571 Expression condition;
570 Token rightSeparator; 572 Token rightSeparator;
571 if (conditionStatement is ExpressionStatement) { 573 if (conditionStatement is ExpressionStatement) {
572 condition = conditionStatement.expression; 574 condition = conditionStatement.expression;
573 rightSeparator = conditionStatement.semicolon; 575 rightSeparator = conditionStatement.semicolon;
574 } else { 576 } else {
575 rightSeparator = (conditionStatement as EmptyStatement).semicolon; 577 rightSeparator = (conditionStatement as EmptyStatement).semicolon;
576 } 578 }
577 579
578 push(ast.forStatement( 580 push(ast.forStatement(
579 forKeyword, 581 forKeyword,
580 leftParenthesis, 582 leftParenthesis,
581 variableList, 583 variableList,
582 initializer, 584 initializer,
583 leftSeparator, 585 leftSeparator,
584 condition, 586 condition,
585 rightSeparator, 587 rightSeparator,
586 updates, 588 updates,
587 leftParenthesis.endGroup, 589 leftParenthesis?.endGroup,
588 body)); 590 body));
589 } 591 }
590 592
591 void handleLiteralList( 593 void handleLiteralList(
592 int count, Token beginToken, Token constKeyword, Token endToken) { 594 int count, Token beginToken, Token constKeyword, Token endToken) {
593 debugEvent("LiteralList"); 595 debugEvent("LiteralList");
594 List<Expression> expressions = popList(count); 596 List<Expression> expressions = popList(count);
595 TypeArgumentList typeArguments = pop(); 597 TypeArgumentList typeArguments = pop();
596 push(ast.listLiteral( 598 push(ast.listLiteral(
597 constKeyword, typeArguments, beginToken, expressions, endToken)); 599 constKeyword, typeArguments, beginToken, expressions, endToken));
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 returnType: typeOrFunctionTypedParameter.returnType, 841 returnType: typeOrFunctionTypedParameter.returnType,
840 typeParameters: typeOrFunctionTypedParameter.typeParameters, 842 typeParameters: typeOrFunctionTypedParameter.typeParameters,
841 parameters: typeOrFunctionTypedParameter.parameters); 843 parameters: typeOrFunctionTypedParameter.parameters);
842 } else { 844 } else {
843 node = ast.fieldFormalParameter2( 845 node = ast.fieldFormalParameter2(
844 identifier: name, 846 identifier: name,
845 comment: comment, 847 comment: comment,
846 covariantKeyword: covariantKeyword, 848 covariantKeyword: covariantKeyword,
847 type: typeOrFunctionTypedParameter.returnType, 849 type: typeOrFunctionTypedParameter.returnType,
848 thisKeyword: thisKeyword, 850 thisKeyword: thisKeyword,
849 period: thisKeyword.next, 851 period: unsafeToken(thisKeyword.next, TokenType.PERIOD),
850 typeParameters: typeOrFunctionTypedParameter.typeParameters, 852 typeParameters: typeOrFunctionTypedParameter.typeParameters,
851 parameters: typeOrFunctionTypedParameter.parameters); 853 parameters: typeOrFunctionTypedParameter.parameters);
852 } 854 }
853 } else { 855 } else {
854 TypeAnnotation type = typeOrFunctionTypedParameter; 856 TypeAnnotation type = typeOrFunctionTypedParameter;
855 if (thisKeyword == null) { 857 if (thisKeyword == null) {
856 node = ast.simpleFormalParameter2( 858 node = ast.simpleFormalParameter2(
857 comment: comment, 859 comment: comment,
858 covariantKeyword: covariantKeyword, 860 covariantKeyword: covariantKeyword,
859 keyword: keyword, 861 keyword: keyword,
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 void handleInvalidFunctionBody(Token token) { 1055 void handleInvalidFunctionBody(Token token) {
1054 debugEvent("InvalidFunctionBody"); 1056 debugEvent("InvalidFunctionBody");
1055 } 1057 }
1056 1058
1057 @override 1059 @override
1058 Token handleUnrecoverableError(Token token, Message message) { 1060 Token handleUnrecoverableError(Token token, Message message) {
1059 if (message.code == codeExpectedFunctionBody) { 1061 if (message.code == codeExpectedFunctionBody) {
1060 if (identical('native', token.stringValue) && parser != null) { 1062 if (identical('native', token.stringValue) && parser != null) {
1061 Token nativeKeyword = token; 1063 Token nativeKeyword = token;
1062 Token semicolon = parser.parseLiteralString(token.next); 1064 Token semicolon = parser.parseLiteralString(token.next);
1065 // 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.
1063 token = parser.expectSemicolon(semicolon); 1066 token = parser.expectSemicolon(semicolon);
1064 StringLiteral name = pop(); 1067 StringLiteral name = pop();
1065 pop(); // star 1068 pop(); // star
1066 pop(); // async 1069 pop(); // async
1067 push(ast.nativeFunctionBody(nativeKeyword, name, semicolon)); 1070 push(ast.nativeFunctionBody(nativeKeyword, name, semicolon));
1068 return token; 1071 return token;
1069 } 1072 }
1070 } else if (message.code == codeExpectedExpression) { 1073 } else if (message.code == codeExpectedExpression) {
1071 String lexeme = token.lexeme; 1074 String lexeme = token.lexeme;
1072 if (identical('async', lexeme) || identical('yield', lexeme)) { 1075 if (identical('async', lexeme) || identical('yield', lexeme)) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 checkEmpty(endToken.charOffset); 1163 checkEmpty(endToken.charOffset);
1161 1164
1162 push(ast.compilationUnit( 1165 push(ast.compilationUnit(
1163 beginToken, scriptTag, directives, declarations, endToken)); 1166 beginToken, scriptTag, directives, declarations, endToken));
1164 } 1167 }
1165 1168
1166 void endImport(Token importKeyword, Token deferredKeyword, Token asKeyword, 1169 void endImport(Token importKeyword, Token deferredKeyword, Token asKeyword,
1167 Token semicolon) { 1170 Token semicolon) {
1168 debugEvent("Import"); 1171 debugEvent("Import");
1169 List<Combinator> combinators = pop(); 1172 List<Combinator> combinators = pop();
1170 SimpleIdentifier prefix; 1173 SimpleIdentifier prefix = popIfNotNull(asKeyword);
1171 if (asKeyword != null) prefix = pop();
1172 List<Configuration> configurations = pop(); 1174 List<Configuration> configurations = pop();
1173 StringLiteral uri = pop(); 1175 StringLiteral uri = pop();
1174 List<Annotation> metadata = pop(); 1176 List<Annotation> metadata = pop();
1175 assert(metadata == null); // TODO(paulberry): fix. 1177 assert(metadata == null); // TODO(paulberry): fix.
1176 Comment comment = pop(); 1178 Comment comment = pop();
1177 directives.add(ast.importDirective( 1179 directives.add(ast.importDirective(
1178 comment, 1180 comment,
1179 metadata, 1181 metadata,
1180 importKeyword, 1182 importKeyword,
1181 uri, 1183 uri,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1220 whileKeyword, 1222 whileKeyword,
1221 condition.leftParenthesis, 1223 condition.leftParenthesis,
1222 condition.expression, 1224 condition.expression,
1223 condition.rightParenthesis, 1225 condition.rightParenthesis,
1224 semicolon)); 1226 semicolon));
1225 } 1227 }
1226 1228
1227 void endConditionalUri(Token ifKeyword, Token equalitySign) { 1229 void endConditionalUri(Token ifKeyword, Token equalitySign) {
1228 debugEvent("ConditionalUri"); 1230 debugEvent("ConditionalUri");
1229 StringLiteral libraryUri = pop(); 1231 StringLiteral libraryUri = pop();
1230 StringLiteral value; 1232 StringLiteral value = popIfNotNull(equalitySign);
1231 if (equalitySign != null) {
1232 value = pop();
1233 }
1234 DottedName name = pop(); 1233 DottedName name = pop();
1235 // TODO(paulberry,ahe): what if there is no `(` token due to an error in the 1234 // TODO(paulberry,ahe): what if there is no `(` token due to an error in the
1236 // file being parsed? It seems like we need the parser to do adequate error 1235 // file being parsed? It seems like we need the parser to do adequate error
1237 // recovery and then report both the ifKeyword and leftParen tokens to the 1236 // recovery and then report both the ifKeyword and leftParen tokens to the
1238 // listener. 1237 // listener.
1239 Token leftParen = ifKeyword.next; 1238 Token leftParen = unsafeToken(ifKeyword.next, TokenType.OPEN_PAREN);
1240 // TODO(paulberry,ahe): the parser should report the right paren token to 1239 // TODO(paulberry,ahe): the parser should report the right paren token to
1241 // the listener. 1240 // the listener.
1242 Token rightParen = name.endToken.next; 1241 Token lastToken = value?.endToken ?? equalitySign ?? name?.endToken;
1242 Token rightParen = unsafeToken(lastToken.next, TokenType.CLOSE_PAREN);
1243 push(ast.configuration(ifKeyword, leftParen, name, equalitySign, value, 1243 push(ast.configuration(ifKeyword, leftParen, name, equalitySign, value,
1244 rightParen, libraryUri)); 1244 rightParen, libraryUri));
1245 } 1245 }
1246 1246
1247 @override 1247 @override
1248 void endConditionalUris(int count) { 1248 void endConditionalUris(int count) {
1249 debugEvent("ConditionalUris"); 1249 debugEvent("ConditionalUris");
1250 push(popList(count) ?? NullValue.ConditionalUris); 1250 push(popList(count) ?? NullValue.ConditionalUris);
1251 } 1251 }
1252 1252
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1445 var libraryNameOrUri = pop(); 1445 var libraryNameOrUri = pop();
1446 LibraryIdentifier name; 1446 LibraryIdentifier name;
1447 StringLiteral uri; 1447 StringLiteral uri;
1448 if (libraryNameOrUri is StringLiteral) { 1448 if (libraryNameOrUri is StringLiteral) {
1449 uri = libraryNameOrUri; 1449 uri = libraryNameOrUri;
1450 } else { 1450 } else {
1451 name = ast.libraryIdentifier(libraryNameOrUri); 1451 name = ast.libraryIdentifier(libraryNameOrUri);
1452 } 1452 }
1453 // TODO(paulberry,ahe): seems hacky. It would be nice if the parser passed 1453 // TODO(paulberry,ahe): seems hacky. It would be nice if the parser passed
1454 // in a reference to the "of" keyword. 1454 // in a reference to the "of" keyword.
1455 var ofKeyword = partKeyword.next; 1455 var ofKeyword = unsafeToken(partKeyword.next, analyzer.Keyword.OF);
1456 List<Annotation> metadata = pop(); 1456 List<Annotation> metadata = pop();
1457 Comment comment = pop(); 1457 Comment comment = pop();
1458 directives.add(ast.partOfDirective( 1458 directives.add(ast.partOfDirective(
1459 comment, metadata, partKeyword, ofKeyword, uri, name, semicolon)); 1459 comment, metadata, partKeyword, ofKeyword, uri, name, semicolon));
1460 } 1460 }
1461 1461
1462 @override 1462 @override
1463 void endFunctionExpression(Token beginToken, Token token) { 1463 void endFunctionExpression(Token beginToken, Token token) {
1464 // TODO(paulberry): set up scopes properly to resolve parameters and type 1464 // TODO(paulberry): set up scopes properly to resolve parameters and type
1465 // variables. Note that this is tricky due to the handling of initializers 1465 // variables. Note that this is tricky due to the handling of initializers
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1712 declarations.add(ast.genericTypeAlias(comment, metadata, typedefKeyword, 1712 declarations.add(ast.genericTypeAlias(comment, metadata, typedefKeyword,
1713 name, templateParameters, equals, type, endToken)); 1713 name, templateParameters, equals, type, endToken));
1714 } 1714 }
1715 } 1715 }
1716 1716
1717 @override 1717 @override
1718 void endEnum(Token enumKeyword, Token endBrace, int count) { 1718 void endEnum(Token enumKeyword, Token endBrace, int count) {
1719 debugEvent("Enum"); 1719 debugEvent("Enum");
1720 List<EnumConstantDeclaration> constants = popList(count); 1720 List<EnumConstantDeclaration> constants = popList(count);
1721 // TODO(paulberry,ahe): the parser should pass in the openBrace token. 1721 // TODO(paulberry,ahe): the parser should pass in the openBrace token.
1722 var openBrace = enumKeyword.next.next as analyzer.BeginToken; 1722 var openBrace =
1723 unsafeToken(enumKeyword.next.next, TokenType.OPEN_CURLY_BRACKET)
1724 as analyzer.BeginToken;
1723 // TODO(paulberry): what if the '}' is missing and the parser has performed 1725 // TODO(paulberry): what if the '}' is missing and the parser has performed
1724 // error recovery? 1726 // error recovery?
1725 Token closeBrace = openBrace.endGroup; 1727 Token closeBrace = openBrace?.endGroup;
1726 SimpleIdentifier name = pop(); 1728 SimpleIdentifier name = pop();
1727 List<Annotation> metadata = pop(); 1729 List<Annotation> metadata = pop();
1728 Comment comment = pop(); 1730 Comment comment = pop();
1729 declarations.add(ast.enumDeclaration(comment, metadata, enumKeyword, name, 1731 declarations.add(ast.enumDeclaration(comment, metadata, enumKeyword, name,
1730 openBrace, constants, closeBrace)); 1732 openBrace, constants, closeBrace));
1731 } 1733 }
1732 1734
1733 @override 1735 @override
1734 void endTypeArguments(int count, Token beginToken, Token endToken) { 1736 void endTypeArguments(int count, Token beginToken, Token endToken) {
1735 debugEvent("TypeArguments"); 1737 debugEvent("TypeArguments");
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1949 } else { 1951 } else {
1950 errorReporter?.reportErrorForOffset(ParserErrorCode.UNEXPECTED_TOKEN, 1952 errorReporter?.reportErrorForOffset(ParserErrorCode.UNEXPECTED_TOKEN,
1951 charOffset, text.length, [text]); 1953 charOffset, text.length, [text]);
1952 } 1954 }
1953 return; 1955 return;
1954 default: 1956 default:
1955 // fall through 1957 // fall through
1956 } 1958 }
1957 library.addCompileTimeError(message, charOffset, uri); 1959 library.addCompileTimeError(message, charOffset, uri);
1958 } 1960 }
1961
1962 /// A marker method used to mark locations where a token is being located in
1963 /// an unsafe way. In all such cases the parser needs to be fixed to pass in
1964 /// the token.
1965 Token unsafeToken(Token token, TokenType tokenType) {
1966 // TODO(brianwilkerson) Eliminate the need for this method.
1967 return token.type == tokenType ? token : null;
1968 }
1959 } 1969 }
1960 1970
1961 /// Data structure placed on the stack to represent a class body. 1971 /// Data structure placed on the stack to represent a class body.
1962 /// 1972 ///
1963 /// This is needed because analyzer has no separate AST representation of a 1973 /// This is needed because analyzer has no separate AST representation of a
1964 /// class body; it simply stores all of the relevant data in the 1974 /// class body; it simply stores all of the relevant data in the
1965 /// [ClassDeclaration] object. 1975 /// [ClassDeclaration] object.
1966 class _ClassBody { 1976 class _ClassBody {
1967 final Token beginToken; 1977 final Token beginToken;
1968 1978
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2056 } else if (identical('var', s)) { 2066 } else if (identical('var', s)) {
2057 finalConstOrVarKeyword = token; 2067 finalConstOrVarKeyword = token;
2058 } else if (identical('covariant', s)) { 2068 } else if (identical('covariant', s)) {
2059 covariantKeyword = token; 2069 covariantKeyword = token;
2060 } else { 2070 } else {
2061 unhandled("$s", "modifier", token.charOffset, null); 2071 unhandled("$s", "modifier", token.charOffset, null);
2062 } 2072 }
2063 } 2073 }
2064 } 2074 }
2065 } 2075 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698