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.body_builder; | 5 library fasta.body_builder; |
6 | 6 |
7 import '../fasta_codes.dart' | 7 import '../fasta_codes.dart' |
8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; | 8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; |
9 | 9 |
10 import '../parser/parser.dart' show FormalParameterType, optional; | 10 import '../parser/parser.dart' show FormalParameterType, optional; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 Expression popForValue() => toValue(pop()); | 138 Expression popForValue() => toValue(pop()); |
139 | 139 |
140 Expression popForEffect() => toEffect(pop()); | 140 Expression popForEffect() => toEffect(pop()); |
141 | 141 |
142 Expression popForValueIfNotNull(Object value) { | 142 Expression popForValueIfNotNull(Object value) { |
143 return value == null ? null : popForValue(); | 143 return value == null ? null : popForValue(); |
144 } | 144 } |
145 | 145 |
146 @override | 146 @override |
147 Expression toValue(Object node) { | 147 Expression toValue(Object node) { |
148 if (node is UnresolvedIdentifier) { | 148 if (node is FastaAccessor) { |
149 if (isDartLibrary && | |
150 node.name.name == "main" && | |
151 library.uri.path == "_builtin" && | |
152 member?.name == "_getMainClosure") { | |
153 // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 | |
154 return new NullLiteral()..fileOffset = node.fileOffset; | |
155 } | |
156 return throwNoSuchMethodError( | |
157 node.name.name, new Arguments.empty(), node.fileOffset, | |
158 isGetter: true); | |
159 } else if (node is FastaAccessor) { | |
160 return node.buildSimpleRead(); | 149 return node.buildSimpleRead(); |
161 } else if (node is TypeVariableBuilder) { | 150 } else if (node is TypeVariableBuilder) { |
162 TypeParameterType type = node.buildTypesWithBuiltArguments(library, null); | 151 TypeParameterType type = node.buildTypesWithBuiltArguments(library, null); |
163 if (!isInstanceContext && type.parameter.parent is Class) { | 152 if (!isInstanceContext && type.parameter.parent is Class) { |
164 return buildCompileTimeError( | 153 return buildCompileTimeError( |
165 "Type variables can only be used in instance methods."); | 154 "Type variables can only be used in instance methods."); |
166 } else { | 155 } else { |
167 if (constantExpressionRequired) { | 156 if (constantExpressionRequired) { |
168 addCompileTimeError(-1, | 157 addCompileTimeError(-1, |
169 "Type variable can't be used as a constant expression $type."); | 158 "Type variable can't be used as a constant expression $type."); |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 return receiver is StaticAccessor && | 513 return receiver is StaticAccessor && |
525 receiver.readTarget == | 514 receiver.readTarget == |
526 coreTypes.tryGetTopLevelMember("dart:core", null, "identical"); | 515 coreTypes.tryGetTopLevelMember("dart:core", null, "identical"); |
527 } | 516 } |
528 | 517 |
529 if (receiver is FastaAccessor) { | 518 if (receiver is FastaAccessor) { |
530 if (constantExpressionRequired && !isIdentical(receiver)) { | 519 if (constantExpressionRequired && !isIdentical(receiver)) { |
531 addCompileTimeError(charOffset, "Not a constant expression."); | 520 addCompileTimeError(charOffset, "Not a constant expression."); |
532 } | 521 } |
533 return receiver.doInvocation(charOffset, arguments); | 522 return receiver.doInvocation(charOffset, arguments); |
534 } else if (receiver is UnresolvedIdentifier) { | |
535 return throwNoSuchMethodError( | |
536 receiver.name.name, arguments, receiver.fileOffset); | |
537 } else { | 523 } else { |
538 return buildMethodInvocation( | 524 return buildMethodInvocation( |
539 toValue(receiver), callName, arguments, charOffset); | 525 toValue(receiver), callName, arguments, charOffset); |
540 } | 526 } |
541 } | 527 } |
542 | 528 |
543 @override | 529 @override |
544 void beginCascade(Token token) { | 530 void beginCascade(Token token) { |
545 debugEvent("beginCascade"); | 531 debugEvent("beginCascade"); |
546 Expression expression = popForValue(); | 532 Expression expression = popForValue(); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 builderToFirstExpression(Builder builder, String name, int charOffset, | 740 builderToFirstExpression(Builder builder, String name, int charOffset, |
755 {bool isPrefix: false}) { | 741 {bool isPrefix: false}) { |
756 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { | 742 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { |
757 Name n = new Name(name, library.library); | 743 Name n = new Name(name, library.library); |
758 if (!isPrefix && isInstanceContext) { | 744 if (!isPrefix && isInstanceContext) { |
759 assert(builder == null); | 745 assert(builder == null); |
760 if (constantExpressionRequired) { | 746 if (constantExpressionRequired) { |
761 addCompileTimeError(charOffset, "Not a constant expression."); | 747 addCompileTimeError(charOffset, "Not a constant expression."); |
762 } | 748 } |
763 return new ThisPropertyAccessor(this, charOffset, n, null, null); | 749 return new ThisPropertyAccessor(this, charOffset, n, null, null); |
| 750 } else if (isDartLibrary && |
| 751 name == "main" && |
| 752 library.uri.path == "_builtin" && |
| 753 member?.name == "_getMainClosure") { |
| 754 // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 |
| 755 return new NullLiteral()..fileOffset = charOffset; |
764 } else { | 756 } else { |
765 if (constantExpressionRequired) { | 757 return new UnresolvedAccessor(this, n, charOffset); |
766 addCompileTimeError(charOffset, "Not a constant expression."); | |
767 } | |
768 return new UnresolvedIdentifier(n)..fileOffset = charOffset; | |
769 } | 758 } |
770 } else if (builder.isTypeDeclaration) { | 759 } else if (builder.isTypeDeclaration) { |
771 if (constantExpressionRequired && builder.isTypeVariable) { | 760 if (constantExpressionRequired && builder.isTypeVariable) { |
772 addCompileTimeError(charOffset, "Not a constant expression."); | 761 addCompileTimeError(charOffset, "Not a constant expression."); |
773 } | 762 } |
774 return builder; | 763 return builder; |
775 } else if (builder.isLocal) { | 764 } else if (builder.isLocal) { |
776 if (constantExpressionRequired && !builder.isConst) { | 765 if (constantExpressionRequired && !builder.isConst) { |
777 addCompileTimeError(charOffset, "Not a constant expression."); | 766 addCompileTimeError(charOffset, "Not a constant expression."); |
778 } | 767 } |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1298 "Can't be used as a type: '${debugName(prefix, suffix)}'."); | 1287 "Can't be used as a type: '${debugName(prefix, suffix)}'."); |
1299 return; | 1288 return; |
1300 } | 1289 } |
1301 } | 1290 } |
1302 if (name is Identifier) { | 1291 if (name is Identifier) { |
1303 name = name.name; | 1292 name = name.name; |
1304 } | 1293 } |
1305 if (name is FastaAccessor) { | 1294 if (name is FastaAccessor) { |
1306 warning("'${beginToken.lexeme}' isn't a type.", beginToken.charOffset); | 1295 warning("'${beginToken.lexeme}' isn't a type.", beginToken.charOffset); |
1307 push(const DynamicType()); | 1296 push(const DynamicType()); |
1308 } else if (name is UnresolvedIdentifier) { | |
1309 warning("'${name.name}' isn't a type.", beginToken.charOffset); | |
1310 push(const DynamicType()); | |
1311 } else if (name is TypeVariableBuilder) { | 1297 } else if (name is TypeVariableBuilder) { |
1312 if (constantExpressionRequired) { | 1298 if (constantExpressionRequired) { |
1313 addCompileTimeError( | 1299 addCompileTimeError( |
1314 beginToken.charOffset, "Not a constant expression."); | 1300 beginToken.charOffset, "Not a constant expression."); |
1315 } | 1301 } |
1316 push(name.buildTypesWithBuiltArguments(library, arguments)); | 1302 push(name.buildTypesWithBuiltArguments(library, arguments)); |
1317 } else if (name is TypeDeclarationBuilder) { | 1303 } else if (name is TypeDeclarationBuilder) { |
1318 push(name.buildTypesWithBuiltArguments(library, arguments)); | 1304 push(name.buildTypesWithBuiltArguments(library, arguments)); |
1319 } else if (name is TypeBuilder) { | 1305 } else if (name is TypeBuilder) { |
1320 push(name.build(library)); | 1306 push(name.build(library)); |
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2451 return expression; | 2437 return expression; |
2452 } | 2438 } |
2453 | 2439 |
2454 @override | 2440 @override |
2455 void debugEvent(String name) { | 2441 void debugEvent(String name) { |
2456 // printEvent(name); | 2442 // printEvent(name); |
2457 } | 2443 } |
2458 } | 2444 } |
2459 | 2445 |
2460 // TODO(ahe): Shouldn't need to be an expression. | 2446 // TODO(ahe): Shouldn't need to be an expression. |
2461 class UnresolvedIdentifier extends InvalidExpression { | |
2462 final Name name; | |
2463 | |
2464 UnresolvedIdentifier(this.name); | |
2465 | |
2466 String toString() => "unresolved-identifier($name)"; | |
2467 } | |
2468 | |
2469 // TODO(ahe): Shouldn't need to be an expression. | |
2470 class Identifier extends InvalidExpression { | 2447 class Identifier extends InvalidExpression { |
2471 final String name; | 2448 final String name; |
2472 | 2449 |
2473 Identifier(this.name); | 2450 Identifier(this.name); |
2474 | 2451 |
2475 Expression get initializer => null; | 2452 Expression get initializer => null; |
2476 | 2453 |
2477 String toString() => "identifier($name)"; | 2454 String toString() => "identifier($name)"; |
2478 } | 2455 } |
2479 | 2456 |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2910 } | 2887 } |
2911 | 2888 |
2912 String debugName(String className, String name, [String prefix]) { | 2889 String debugName(String className, String name, [String prefix]) { |
2913 String result = name.isEmpty ? className : "$className.$name"; | 2890 String result = name.isEmpty ? className : "$className.$name"; |
2914 return prefix == null ? result : "$prefix.result"; | 2891 return prefix == null ? result : "$prefix.result"; |
2915 } | 2892 } |
2916 | 2893 |
2917 String getNodeName(Object node) { | 2894 String getNodeName(Object node) { |
2918 if (node is Identifier) { | 2895 if (node is Identifier) { |
2919 return node.name; | 2896 return node.name; |
2920 } else if (node is UnresolvedIdentifier) { | |
2921 return node.name.name; | |
2922 } else if (node is TypeDeclarationBuilder) { | 2897 } else if (node is TypeDeclarationBuilder) { |
2923 return node.name; | 2898 return node.name; |
2924 } else if (node is PrefixBuilder) { | 2899 } else if (node is PrefixBuilder) { |
2925 return node.name; | 2900 return node.name; |
2926 } else if (node is ThisAccessor) { | 2901 } else if (node is ThisAccessor) { |
2927 return node.isSuper ? "super" : "this"; | 2902 return node.isSuper ? "super" : "this"; |
2928 } else if (node is FastaAccessor) { | 2903 } else if (node is FastaAccessor) { |
2929 return node.plainNameForRead; | 2904 return node.plainNameForRead; |
2930 } else { | 2905 } else { |
2931 return internalError("Unhandled: ${node.runtimeType}"); | 2906 return internalError("Unhandled: ${node.runtimeType}"); |
2932 } | 2907 } |
2933 } | 2908 } |
OLD | NEW |