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/ast/token.dart' show Token, TokenType; | 11 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; |
12 import 'package:analyzer/dart/element/element.dart' show Element; | |
13 import 'package:front_end/src/fasta/parser/parser.dart' | 12 import 'package:front_end/src/fasta/parser/parser.dart' |
14 show Assert, FormalParameterType, MemberKind, Parser; | 13 show Assert, FormalParameterType, MemberKind, Parser; |
15 import 'package:front_end/src/fasta/scanner/string_scanner.dart'; | 14 import 'package:front_end/src/fasta/scanner/string_scanner.dart'; |
16 import 'package:front_end/src/fasta/scanner/token.dart' show CommentToken; | 15 import 'package:front_end/src/fasta/scanner/token.dart' show CommentToken; |
17 import 'package:front_end/src/scanner/token.dart' as analyzer; | 16 import 'package:front_end/src/scanner/token.dart' as analyzer; |
18 | 17 |
19 import 'package:front_end/src/fasta/problems.dart' show unexpected, unhandled; | 18 import 'package:front_end/src/fasta/problems.dart' show unhandled; |
20 import 'package:front_end/src/fasta/messages.dart' | 19 import 'package:front_end/src/fasta/messages.dart' |
21 show Code, Message, codeExpectedExpression, codeExpectedFunctionBody; | 20 show Code, Message, codeExpectedExpression, codeExpectedFunctionBody; |
22 import 'package:front_end/src/fasta/kernel/kernel_builder.dart' | 21 import 'package:front_end/src/fasta/kernel/kernel_builder.dart' |
23 show Builder, KernelLibraryBuilder, ProcedureBuilder, Scope; | 22 show Builder, KernelLibraryBuilder, Scope; |
24 import 'package:front_end/src/fasta/parser/identifier_context.dart' | 23 import 'package:front_end/src/fasta/parser/identifier_context.dart' |
25 show IdentifierContext; | 24 show IdentifierContext; |
26 import 'package:front_end/src/fasta/quote.dart'; | 25 import 'package:front_end/src/fasta/quote.dart'; |
27 import 'package:front_end/src/fasta/source/scope_listener.dart' | 26 import 'package:front_end/src/fasta/source/scope_listener.dart' |
28 show JumpTargetKind, NullValue, ScopeListener; | 27 show JumpTargetKind, NullValue, ScopeListener; |
29 import 'analyzer.dart' show toKernel; | |
30 import 'element_store.dart' | |
31 show | |
32 AnalyzerLocalVariableElemment, | |
33 AnalyzerParameterElement, | |
34 ElementStore, | |
35 KernelClassElement; | |
36 import 'package:analyzer/src/dart/error/syntactic_errors.dart'; | 28 import 'package:analyzer/src/dart/error/syntactic_errors.dart'; |
37 | 29 |
38 class AstBuilder extends ScopeListener { | 30 class AstBuilder extends ScopeListener { |
39 final AstFactory ast = standard.astFactory; | 31 final AstFactory ast = standard.astFactory; |
40 | 32 |
41 final ErrorReporter errorReporter; | 33 final ErrorReporter errorReporter; |
42 final KernelLibraryBuilder library; | 34 final KernelLibraryBuilder library; |
43 final Builder member; | 35 final Builder member; |
44 final ElementStore elementStore; | |
45 | 36 |
46 @override | 37 @override |
47 final Uri uri; | 38 final Uri uri; |
48 | 39 |
49 /** | 40 /** |
50 * The [Parser] that uses this listener, used to parse optional parts, e.g. | 41 * The [Parser] that uses this listener, used to parse optional parts, e.g. |
51 * `native` support. | 42 * `native` support. |
52 */ | 43 */ |
53 Parser parser; | 44 Parser parser; |
54 | 45 |
55 bool parseGenericMethodComments = false; | 46 bool parseGenericMethodComments = false; |
56 | 47 |
57 /// The name of the class currently being parsed, or `null` if no class is | 48 /// The name of the class currently being parsed, or `null` if no class is |
58 /// being parsed. | 49 /// being parsed. |
59 String className; | 50 String className; |
60 | 51 |
61 /// If true, this is building a full AST. Otherwise, only create method | 52 /// If true, this is building a full AST. Otherwise, only create method |
62 /// bodies. | 53 /// bodies. |
63 final bool isFullAst; | 54 final bool isFullAst; |
64 | 55 |
65 final bool generateKernel; | 56 AstBuilder(this.errorReporter, this.library, this.member, Scope scope, |
66 | 57 this.isFullAst, |
67 AstBuilder(this.errorReporter, this.library, this.member, this.elementStore, | |
68 Scope scope, this.isFullAst, this.generateKernel, | |
69 [Uri uri]) | 58 [Uri uri]) |
70 : uri = uri ?? library.fileUri, | 59 : uri = uri ?? library.fileUri, |
71 super(scope); | 60 super(scope); |
72 | 61 |
73 createJumpTarget(JumpTargetKind kind, int charOffset) { | 62 createJumpTarget(JumpTargetKind kind, int charOffset) { |
74 // TODO(ahe): Implement jump targets. | 63 // TODO(ahe): Implement jump targets. |
75 return null; | 64 return null; |
76 } | 65 } |
77 | 66 |
78 void beginLiteralString(Token token) { | 67 void beginLiteralString(Token token) { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 } else { | 199 } else { |
211 push(identifier); | 200 push(identifier); |
212 } | 201 } |
213 } else if (context == IdentifierContext.enumValueDeclaration) { | 202 } else if (context == IdentifierContext.enumValueDeclaration) { |
214 // TODO(paulberry): analyzer's ASTs allow for enumerated values to have | 203 // TODO(paulberry): analyzer's ASTs allow for enumerated values to have |
215 // metadata, but the spec doesn't permit it. | 204 // metadata, but the spec doesn't permit it. |
216 List<Annotation> metadata; | 205 List<Annotation> metadata; |
217 Comment comment = _toAnalyzerComment(token.precedingComments); | 206 Comment comment = _toAnalyzerComment(token.precedingComments); |
218 push(ast.enumConstantDeclaration(comment, metadata, identifier)); | 207 push(ast.enumConstantDeclaration(comment, metadata, identifier)); |
219 } else { | 208 } else { |
220 if (context.isScopeReference) { | |
221 String name = token.lexeme; | |
222 Builder builder = scope.lookup(name, token.charOffset, uri); | |
223 if (builder != null) { | |
224 Element element = elementStore[builder]; | |
225 assert(element != null); | |
226 identifier.staticElement = element; | |
227 } | |
228 } | |
229 push(identifier); | 209 push(identifier); |
230 } | 210 } |
231 } | 211 } |
232 | 212 |
233 void endSend(Token beginToken, Token endToken) { | 213 void endSend(Token beginToken, Token endToken) { |
234 debugEvent("Send"); | 214 debugEvent("Send"); |
235 MethodInvocation arguments = pop(); | 215 MethodInvocation arguments = pop(); |
236 TypeArgumentList typeArguments = pop(); | 216 TypeArgumentList typeArguments = pop(); |
237 if (arguments != null) { | 217 if (arguments != null) { |
238 doInvocation(endToken, typeArguments, arguments); | 218 doInvocation(endToken, typeArguments, arguments); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 void finishFunction(annotations, formals, asyncModifier, FunctionBody body) { | 273 void finishFunction(annotations, formals, asyncModifier, FunctionBody body) { |
294 debugEvent("finishFunction"); | 274 debugEvent("finishFunction"); |
295 Statement bodyStatement; | 275 Statement bodyStatement; |
296 if (body is EmptyFunctionBody) { | 276 if (body is EmptyFunctionBody) { |
297 bodyStatement = ast.emptyStatement(body.semicolon); | 277 bodyStatement = ast.emptyStatement(body.semicolon); |
298 } else if (body is ExpressionFunctionBody) { | 278 } else if (body is ExpressionFunctionBody) { |
299 bodyStatement = ast.returnStatement(null, body.expression, null); | 279 bodyStatement = ast.returnStatement(null, body.expression, null); |
300 } else { | 280 } else { |
301 bodyStatement = (body as BlockFunctionBody).block; | 281 bodyStatement = (body as BlockFunctionBody).block; |
302 } | 282 } |
303 if (generateKernel) { | 283 // TODO(paulberry): what do we need to do with bodyStatement at this point? |
304 var kernel = | 284 bodyStatement; // Suppress "unused local variable" hint |
305 toKernel(bodyStatement, elementStore, library.library, scope); | |
306 if (member is ProcedureBuilder) { | |
307 ProcedureBuilder builder = member; | |
308 builder.body = kernel; | |
309 } else { | |
310 unexpected( | |
311 "procedure", "${member.runtimeType}", member.charOffset, uri); | |
312 } | |
313 } | |
314 } | 285 } |
315 | 286 |
316 void beginCascade(Token token) { | 287 void beginCascade(Token token) { |
317 debugEvent("beginCascade"); | 288 debugEvent("beginCascade"); |
318 Expression expression = pop(); | 289 Expression expression = pop(); |
319 push(token); | 290 push(token); |
320 if (expression is CascadeExpression) { | 291 if (expression is CascadeExpression) { |
321 push(expression); | 292 push(expression); |
322 } else { | 293 } else { |
323 push(ast.cascadeExpression(expression, <Expression>[])); | 294 push(ast.cascadeExpression(expression, <Expression>[])); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 // SimpleIdentifier into a VariableDeclaration, and then when this code was | 490 // SimpleIdentifier into a VariableDeclaration, and then when this code was |
520 // reached, node would always be a VariableDeclaration. | 491 // reached, node would always be a VariableDeclaration. |
521 if (node is VariableDeclaration) { | 492 if (node is VariableDeclaration) { |
522 variable = node; | 493 variable = node; |
523 } else if (node is SimpleIdentifier) { | 494 } else if (node is SimpleIdentifier) { |
524 variable = ast.variableDeclaration(node, null, null); | 495 variable = ast.variableDeclaration(node, null, null); |
525 } else { | 496 } else { |
526 unhandled("${node.runtimeType}", "identifier", nameToken.charOffset, uri); | 497 unhandled("${node.runtimeType}", "identifier", nameToken.charOffset, uri); |
527 } | 498 } |
528 push(variable); | 499 push(variable); |
529 scope.declare( | |
530 variable.name.name, | |
531 variable.name.staticElement = | |
532 new AnalyzerLocalVariableElemment(variable), | |
533 nameToken.charOffset, | |
534 uri); | |
535 } | 500 } |
536 | 501 |
537 void endVariablesDeclaration(int count, Token endToken) { | 502 void endVariablesDeclaration(int count, Token endToken) { |
538 debugEvent("VariablesDeclaration"); | 503 debugEvent("VariablesDeclaration"); |
539 List<VariableDeclaration> variables = popList(count); | 504 List<VariableDeclaration> variables = popList(count); |
540 TypeAnnotation type = pop(); | 505 TypeAnnotation type = pop(); |
541 _Modifiers modifiers = pop(); | 506 _Modifiers modifiers = pop(); |
542 Token keyword = modifiers?.finalConstOrVarKeyword; | 507 Token keyword = modifiers?.finalConstOrVarKeyword; |
543 List<Annotation> metadata = pop(); | 508 List<Annotation> metadata = pop(); |
544 Comment comment = pop(); | 509 Comment comment = pop(); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
672 @override | 637 @override |
673 void handleThisExpression(Token token, IdentifierContext context) { | 638 void handleThisExpression(Token token, IdentifierContext context) { |
674 debugEvent("ThisExpression"); | 639 debugEvent("ThisExpression"); |
675 push(ast.thisExpression(token)); | 640 push(ast.thisExpression(token)); |
676 } | 641 } |
677 | 642 |
678 void handleType(Token beginToken, Token endToken) { | 643 void handleType(Token beginToken, Token endToken) { |
679 debugEvent("Type"); | 644 debugEvent("Type"); |
680 TypeArgumentList arguments = pop(); | 645 TypeArgumentList arguments = pop(); |
681 Identifier name = pop(); | 646 Identifier name = pop(); |
682 // TODO(paulberry,ahe): what if the type doesn't resolve to a class | 647 push(ast.typeName(name, arguments)); |
683 // element? Try to share code with BodyBuilder.builderToFirstExpression. | |
684 KernelClassElement cls = name.staticElement; | |
685 push(ast.typeName(name, arguments)..type = cls?.rawType); | |
686 } | 648 } |
687 | 649 |
688 @override | 650 @override |
689 void endAssert(Token assertKeyword, Assert kind, Token leftParenthesis, | 651 void endAssert(Token assertKeyword, Assert kind, Token leftParenthesis, |
690 Token comma, Token rightParenthesis, Token semicolon) { | 652 Token comma, Token rightParenthesis, Token semicolon) { |
691 debugEvent("Assert"); | 653 debugEvent("Assert"); |
692 Expression message = popIfNotNull(comma); | 654 Expression message = popIfNotNull(comma); |
693 Expression condition = pop(); | 655 Expression condition = pop(); |
694 push(ast.assertStatement(assertKeyword, leftParenthesis, condition, comma, | 656 push(ast.assertStatement(assertKeyword, leftParenthesis, condition, comma, |
695 message, rightParenthesis, semicolon)); | 657 message, rightParenthesis, semicolon)); |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
888 period: thisKeyword.next, | 850 period: thisKeyword.next, |
889 identifier: name); | 851 identifier: name); |
890 } | 852 } |
891 } | 853 } |
892 | 854 |
893 ParameterKind analyzerKind = _toAnalyzerParameterKind(kind); | 855 ParameterKind analyzerKind = _toAnalyzerParameterKind(kind); |
894 if (analyzerKind != ParameterKind.REQUIRED) { | 856 if (analyzerKind != ParameterKind.REQUIRED) { |
895 node = ast.defaultFormalParameter( | 857 node = ast.defaultFormalParameter( |
896 node, analyzerKind, defaultValue?.separator, defaultValue?.value); | 858 node, analyzerKind, defaultValue?.separator, defaultValue?.value); |
897 } | 859 } |
898 | |
899 if (name != null) { | |
900 scope.declare( | |
901 name.name, | |
902 name.staticElement = new AnalyzerParameterElement(node), | |
903 name.offset, | |
904 uri); | |
905 } | |
906 push(node); | 860 push(node); |
907 } | 861 } |
908 | 862 |
909 @override | 863 @override |
910 void endFunctionTypedFormalParameter() { | 864 void endFunctionTypedFormalParameter() { |
911 debugEvent("FunctionTypedFormalParameter"); | 865 debugEvent("FunctionTypedFormalParameter"); |
912 | 866 |
913 FormalParameterList formalParameters = pop(); | 867 FormalParameterList formalParameters = pop(); |
914 TypeAnnotation returnType = pop(); | 868 TypeAnnotation returnType = pop(); |
915 TypeParameterList typeParameters = pop(); | 869 TypeParameterList typeParameters = pop(); |
(...skipping 1111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2027 } else if (identical('var', s)) { | 1981 } else if (identical('var', s)) { |
2028 finalConstOrVarKeyword = token; | 1982 finalConstOrVarKeyword = token; |
2029 } else if (identical('covariant', s)) { | 1983 } else if (identical('covariant', s)) { |
2030 covariantKeyword = token; | 1984 covariantKeyword = token; |
2031 } else { | 1985 } else { |
2032 unhandled("$s", "modifier", token.charOffset, null); | 1986 unhandled("$s", "modifier", token.charOffset, null); |
2033 } | 1987 } |
2034 } | 1988 } |
2035 } | 1989 } |
2036 } | 1990 } |
OLD | NEW |