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 |