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