| OLD | NEW |
| 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' as analyzer show Token; | 10 import 'package:analyzer/dart/ast/token.dart' as analyzer show Token; |
| 11 import 'package:analyzer/dart/element/element.dart' show Element; | 11 import 'package:analyzer/dart/element/element.dart' show Element; |
| 12 import 'package:front_end/src/fasta/parser/parser.dart' | 12 import 'package:front_end/src/fasta/parser/parser.dart' |
| 13 show FormalParameterType; | 13 show FormalParameterType; |
| 14 import 'package:front_end/src/fasta/scanner/token.dart' | 14 import 'package:front_end/src/fasta/scanner/token.dart' |
| 15 show BeginGroupToken, Token; | 15 show BeginGroupToken, Token; |
| 16 import 'package:kernel/ast.dart' show AsyncMarker; | |
| 17 | 16 |
| 18 import '../errors.dart' show internalError; | 17 import '../errors.dart' show internalError; |
| 19 import '../kernel/kernel_builder.dart' | 18 import '../kernel/kernel_builder.dart' |
| 20 show Builder, KernelLibraryBuilder, ProcedureBuilder; | 19 show Builder, KernelLibraryBuilder, ProcedureBuilder; |
| 21 import '../parser/identifier_context.dart' show IdentifierContext; | 20 import '../parser/identifier_context.dart' show IdentifierContext; |
| 22 import '../quote.dart'; | 21 import '../quote.dart'; |
| 23 import '../source/outline_builder.dart' show asyncMarkerFromTokens; | |
| 24 import '../source/scope_listener.dart' | 22 import '../source/scope_listener.dart' |
| 25 show JumpTargetKind, NullValue, Scope, ScopeListener; | 23 show JumpTargetKind, NullValue, Scope, ScopeListener; |
| 26 import 'analyzer.dart' show toKernel; | 24 import 'analyzer.dart' show toKernel; |
| 27 import 'element_store.dart' | 25 import 'element_store.dart' |
| 28 show | 26 show |
| 29 AnalyzerLocalVariableElemment, | 27 AnalyzerLocalVariableElemment, |
| 30 AnalyzerParameterElement, | 28 AnalyzerParameterElement, |
| 31 ElementStore, | 29 ElementStore, |
| 32 KernelClassElement; | 30 KernelClassElement; |
| 33 import 'token_utils.dart' show toAnalyzerToken; | 31 import 'token_utils.dart' show toAnalyzerToken; |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 debugEvent("ExpressionStatement"); | 218 debugEvent("ExpressionStatement"); |
| 221 push(ast.expressionStatement(pop(), toAnalyzerToken(token))); | 219 push(ast.expressionStatement(pop(), toAnalyzerToken(token))); |
| 222 } | 220 } |
| 223 | 221 |
| 224 void endFunctionBody(int count, Token beginToken, Token endToken) { | 222 void endFunctionBody(int count, Token beginToken, Token endToken) { |
| 225 debugEvent("FunctionBody"); | 223 debugEvent("FunctionBody"); |
| 226 List statements = popList(count); | 224 List statements = popList(count); |
| 227 if (beginToken != null) { | 225 if (beginToken != null) { |
| 228 exitLocalScope(); | 226 exitLocalScope(); |
| 229 } | 227 } |
| 230 push(ast.block( | 228 Block block = ast.block( |
| 231 toAnalyzerToken(beginToken), statements, toAnalyzerToken(endToken))); | 229 toAnalyzerToken(beginToken), statements, toAnalyzerToken(endToken)); |
| 230 analyzer.Token star = pop(); |
| 231 analyzer.Token asyncKeyword = pop(); |
| 232 push(ast.blockFunctionBody(asyncKeyword, star, block)); |
| 232 } | 233 } |
| 233 | 234 |
| 234 void finishFunction(formals, asyncModifier, Statement body) { | 235 void finishFunction(formals, asyncModifier, FunctionBody body) { |
| 235 debugEvent("finishFunction"); | 236 debugEvent("finishFunction"); |
| 236 var kernel = toKernel(body, elementStore, library.library, scope); | 237 Statement bodyStatement; |
| 238 if (body is ExpressionFunctionBody) { |
| 239 bodyStatement = ast.returnStatement(null, body.expression, null); |
| 240 } else { |
| 241 bodyStatement = (body as BlockFunctionBody).block; |
| 242 } |
| 243 var kernel = toKernel(bodyStatement, elementStore, library.library, scope); |
| 237 if (member is ProcedureBuilder) { | 244 if (member is ProcedureBuilder) { |
| 238 ProcedureBuilder builder = member; | 245 ProcedureBuilder builder = member; |
| 239 builder.body = kernel; | 246 builder.body = kernel; |
| 240 } else { | 247 } else { |
| 241 internalError("Internal error: expected procedure, but got: $member"); | 248 internalError("Internal error: expected procedure, but got: $member"); |
| 242 } | 249 } |
| 243 } | 250 } |
| 244 | 251 |
| 245 void beginCascade(Token token) { | 252 void beginCascade(Token token) { |
| 246 debugEvent("beginCascade"); | 253 debugEvent("beginCascade"); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 internalError( | 304 internalError( |
| 298 "Unhandled property access: ${identifierOrInvoke.runtimeType}"); | 305 "Unhandled property access: ${identifierOrInvoke.runtimeType}"); |
| 299 } | 306 } |
| 300 } | 307 } |
| 301 | 308 |
| 302 void handleLiteralInt(Token token) { | 309 void handleLiteralInt(Token token) { |
| 303 debugEvent("LiteralInt"); | 310 debugEvent("LiteralInt"); |
| 304 push(ast.integerLiteral(toAnalyzerToken(token), int.parse(token.value))); | 311 push(ast.integerLiteral(toAnalyzerToken(token), int.parse(token.value))); |
| 305 } | 312 } |
| 306 | 313 |
| 314 void endExpressionFunctionBody(Token arrowToken, Token endToken) { |
| 315 debugEvent("ExpressionFunctionBody"); |
| 316 Expression expression = pop(); |
| 317 analyzer.Token star = pop(); |
| 318 analyzer.Token asyncKeyword = pop(); |
| 319 assert(star == null); |
| 320 push(ast.expressionFunctionBody(asyncKeyword, toAnalyzerToken(arrowToken), |
| 321 expression, toAnalyzerToken(endToken))); |
| 322 } |
| 323 |
| 307 void endReturnStatement( | 324 void endReturnStatement( |
| 308 bool hasExpression, Token beginToken, Token endToken) { | 325 bool hasExpression, Token beginToken, Token endToken) { |
| 309 debugEvent("ReturnStatement"); | 326 debugEvent("ReturnStatement"); |
| 310 Expression expression = hasExpression ? pop() : null; | 327 Expression expression = hasExpression ? pop() : null; |
| 311 push(ast.returnStatement( | 328 push(ast.returnStatement( |
| 312 toAnalyzerToken(beginToken), expression, toAnalyzerToken(endToken))); | 329 toAnalyzerToken(beginToken), expression, toAnalyzerToken(endToken))); |
| 313 } | 330 } |
| 314 | 331 |
| 315 void endIfStatement(Token ifToken, Token elseToken) { | 332 void endIfStatement(Token ifToken, Token elseToken) { |
| 316 Statement elsePart = popIfNotNull(elseToken); | 333 Statement elsePart = popIfNotNull(elseToken); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 int count, Token beginToken, Token constKeyword, Token endToken) { | 445 int count, Token beginToken, Token constKeyword, Token endToken) { |
| 429 debugEvent("LiteralList"); | 446 debugEvent("LiteralList"); |
| 430 List<Expression> expressions = popList(count); | 447 List<Expression> expressions = popList(count); |
| 431 TypeArgumentList typeArguments = pop(); | 448 TypeArgumentList typeArguments = pop(); |
| 432 push(ast.listLiteral(toAnalyzerToken(constKeyword), typeArguments, | 449 push(ast.listLiteral(toAnalyzerToken(constKeyword), typeArguments, |
| 433 toAnalyzerToken(beginToken), expressions, toAnalyzerToken(endToken))); | 450 toAnalyzerToken(beginToken), expressions, toAnalyzerToken(endToken))); |
| 434 } | 451 } |
| 435 | 452 |
| 436 void handleAsyncModifier(Token asyncToken, Token starToken) { | 453 void handleAsyncModifier(Token asyncToken, Token starToken) { |
| 437 debugEvent("AsyncModifier"); | 454 debugEvent("AsyncModifier"); |
| 438 push(asyncMarkerFromTokens(asyncToken, starToken)); | 455 push(toAnalyzerToken(asyncToken) ?? NullValue.FunctionBodyAsyncToken); |
| 456 push(toAnalyzerToken(starToken) ?? NullValue.FunctionBodyStarToken); |
| 439 } | 457 } |
| 440 | 458 |
| 441 void endAwaitExpression(Token beginToken, Token endToken) { | 459 void endAwaitExpression(Token beginToken, Token endToken) { |
| 442 debugEvent("AwaitExpression"); | 460 debugEvent("AwaitExpression"); |
| 443 push(ast.awaitExpression(toAnalyzerToken(beginToken), pop())); | 461 push(ast.awaitExpression(toAnalyzerToken(beginToken), pop())); |
| 444 } | 462 } |
| 445 | 463 |
| 446 void handleLiteralBool(Token token) { | 464 void handleLiteralBool(Token token) { |
| 447 debugEvent("LiteralBool"); | 465 debugEvent("LiteralBool"); |
| 448 bool value = identical(token.stringValue, "true"); | 466 bool value = identical(token.stringValue, "true"); |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 void handleModifier(Token token) { | 777 void handleModifier(Token token) { |
| 760 debugEvent("Modifier"); | 778 debugEvent("Modifier"); |
| 761 push(token); | 779 push(token); |
| 762 } | 780 } |
| 763 | 781 |
| 764 void handleModifiers(int count) { | 782 void handleModifiers(int count) { |
| 765 debugEvent("Modifiers"); | 783 debugEvent("Modifiers"); |
| 766 push(popList(count) ?? const <Token>[]); | 784 push(popList(count) ?? const <Token>[]); |
| 767 } | 785 } |
| 768 | 786 |
| 769 FunctionBody _endFunctionBody() { | |
| 770 AstNode body = pop(); | |
| 771 // TODO(paulberry): asyncMarker should have a type that allows constructing | |
| 772 // the necessary analyzer AST data structures. | |
| 773 AsyncMarker asyncMarker = pop(); | |
| 774 assert(asyncMarker == AsyncMarker.Sync); | |
| 775 analyzer.Token asyncKeyword = null; | |
| 776 analyzer.Token star = null; | |
| 777 if (body is Block) { | |
| 778 return ast.blockFunctionBody(asyncKeyword, star, body); | |
| 779 } else if (body is ReturnStatement) { | |
| 780 assert(star == null); | |
| 781 return ast.expressionFunctionBody( | |
| 782 asyncKeyword, body.returnKeyword, body.expression, body.semicolon); | |
| 783 } else { | |
| 784 return internalError( | |
| 785 'Unexpected function body type: ${body.runtimeType}'); | |
| 786 } | |
| 787 } | |
| 788 | |
| 789 void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) { | 787 void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) { |
| 790 // TODO(paulberry): set up scopes properly to resolve parameters and type | 788 // TODO(paulberry): set up scopes properly to resolve parameters and type |
| 791 // variables. | 789 // variables. |
| 792 debugEvent("TopLevelMethod"); | 790 debugEvent("TopLevelMethod"); |
| 793 FunctionBody body = _endFunctionBody(); | 791 FunctionBody body = pop(); |
| 794 FormalParameterList parameters = pop(); | 792 FormalParameterList parameters = pop(); |
| 795 TypeParameterList typeParameters = pop(); | 793 TypeParameterList typeParameters = pop(); |
| 796 SimpleIdentifier name = pop(); | 794 SimpleIdentifier name = pop(); |
| 797 analyzer.Token propertyKeyword = toAnalyzerToken(getOrSet); | 795 analyzer.Token propertyKeyword = toAnalyzerToken(getOrSet); |
| 798 TypeAnnotation returnType = pop(); | 796 TypeAnnotation returnType = pop(); |
| 799 Token externalKeyword = _popOptionalSingleModifier(); | 797 Token externalKeyword = _popOptionalSingleModifier(); |
| 800 List<Annotation> metadata = pop(); | 798 List<Annotation> metadata = pop(); |
| 801 // TODO(paulberry): capture doc comments. See dartbug.com/28851. | 799 // TODO(paulberry): capture doc comments. See dartbug.com/28851. |
| 802 Comment comment = null; | 800 Comment comment = null; |
| 803 push(ast.functionDeclaration( | 801 push(ast.functionDeclaration( |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1105 push(ast.partOfDirective(comment, metadata, toAnalyzerToken(partKeyword), | 1103 push(ast.partOfDirective(comment, metadata, toAnalyzerToken(partKeyword), |
| 1106 toAnalyzerToken(ofKeyword), uri, name, toAnalyzerToken(semicolon))); | 1104 toAnalyzerToken(ofKeyword), uri, name, toAnalyzerToken(semicolon))); |
| 1107 } | 1105 } |
| 1108 | 1106 |
| 1109 void endUnnamedFunction(Token token) { | 1107 void endUnnamedFunction(Token token) { |
| 1110 // TODO(paulberry): set up scopes properly to resolve parameters and type | 1108 // TODO(paulberry): set up scopes properly to resolve parameters and type |
| 1111 // variables. Note that this is tricky due to the handling of initializers | 1109 // variables. Note that this is tricky due to the handling of initializers |
| 1112 // in constructors, so the logic should be shared with BodyBuilder as much | 1110 // in constructors, so the logic should be shared with BodyBuilder as much |
| 1113 // as possible. | 1111 // as possible. |
| 1114 debugEvent("UnnamedFunction"); | 1112 debugEvent("UnnamedFunction"); |
| 1115 var body = _endFunctionBody(); | 1113 FunctionBody body = pop(); |
| 1116 FormalParameterList parameters = pop(); | 1114 FormalParameterList parameters = pop(); |
| 1117 TypeParameterList typeParameters = pop(); | 1115 TypeParameterList typeParameters = pop(); |
| 1118 push(ast.functionExpression(typeParameters, parameters, body)); | 1116 push(ast.functionExpression(typeParameters, parameters, body)); |
| 1119 } | 1117 } |
| 1120 | 1118 |
| 1121 @override | 1119 @override |
| 1122 void handleNoFieldInitializer(Token token) { | 1120 void handleNoFieldInitializer(Token token) { |
| 1123 debugEvent("NoFieldInitializer"); | 1121 debugEvent("NoFieldInitializer"); |
| 1124 SimpleIdentifier name = pop(); | 1122 SimpleIdentifier name = pop(); |
| 1125 push(ast.variableDeclaration(name, null, null)); | 1123 push(ast.variableDeclaration(name, null, null)); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1167 void endTypeVariables(int count, Token beginToken, Token endToken) { | 1165 void endTypeVariables(int count, Token beginToken, Token endToken) { |
| 1168 debugEvent("TypeVariables"); | 1166 debugEvent("TypeVariables"); |
| 1169 List<TypeParameter> typeParameters = popList(count); | 1167 List<TypeParameter> typeParameters = popList(count); |
| 1170 push(ast.typeParameterList(toAnalyzerToken(beginToken), typeParameters, | 1168 push(ast.typeParameterList(toAnalyzerToken(beginToken), typeParameters, |
| 1171 toAnalyzerToken(endToken))); | 1169 toAnalyzerToken(endToken))); |
| 1172 } | 1170 } |
| 1173 | 1171 |
| 1174 @override | 1172 @override |
| 1175 void endMethod(Token getOrSet, Token beginToken, Token endToken) { | 1173 void endMethod(Token getOrSet, Token beginToken, Token endToken) { |
| 1176 debugEvent("Method"); | 1174 debugEvent("Method"); |
| 1177 FunctionBody body = _endFunctionBody(); | 1175 FunctionBody body = pop(); |
| 1178 ConstructorName redirectedConstructor = null; // TODO(paulberry) | 1176 ConstructorName redirectedConstructor = null; // TODO(paulberry) |
| 1179 List<ConstructorInitializer> initializers = null; // TODO(paulberry) | 1177 List<ConstructorInitializer> initializers = null; // TODO(paulberry) |
| 1180 Token separator = null; // TODO(paulberry) | 1178 Token separator = null; // TODO(paulberry) |
| 1181 FormalParameterList parameters = pop(); | 1179 FormalParameterList parameters = pop(); |
| 1182 TypeParameterList typeParameters = pop(); // TODO(paulberry) | 1180 TypeParameterList typeParameters = pop(); // TODO(paulberry) |
| 1183 var name = pop(); | 1181 var name = pop(); |
| 1184 TypeAnnotation returnType = pop(); // TODO(paulberry) | 1182 TypeAnnotation returnType = pop(); // TODO(paulberry) |
| 1185 Token modifierKeyword = null; // TODO(paulberry) | 1183 Token modifierKeyword = null; // TODO(paulberry) |
| 1186 Token externalKeyword = null; | 1184 Token externalKeyword = null; |
| 1187 Token constKeyword = null; | 1185 Token constKeyword = null; |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1432 } | 1430 } |
| 1433 | 1431 |
| 1434 /// Data structure placed on the stack to represent the keyword "operator" | 1432 /// Data structure placed on the stack to represent the keyword "operator" |
| 1435 /// followed by a token. | 1433 /// followed by a token. |
| 1436 class _OperatorName { | 1434 class _OperatorName { |
| 1437 final Token operatorKeyword; | 1435 final Token operatorKeyword; |
| 1438 final SimpleIdentifier name; | 1436 final SimpleIdentifier name; |
| 1439 | 1437 |
| 1440 _OperatorName(this.operatorKeyword, this.name); | 1438 _OperatorName(this.operatorKeyword, this.name); |
| 1441 } | 1439 } |
| OLD | NEW |