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 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
733 } | 733 } |
734 push(new Identifier(name, token.charOffset)); | 734 push(new Identifier(name, token.charOffset)); |
735 } | 735 } |
736 | 736 |
737 /// Look up [name] in [scope] using [charOffset] to report any | 737 /// Look up [name] in [scope] using [charOffset] to report any |
738 /// problems. [isQualified] should be true if [name] is a qualified access | 738 /// problems. [isQualified] should be true if [name] is a qualified access |
739 /// (which implies that it shouldn't be turned into a [ThisPropertyAccessor] | 739 /// (which implies that it shouldn't be turned into a [ThisPropertyAccessor] |
740 /// if the name doesn't resolve in the scope). | 740 /// if the name doesn't resolve in the scope). |
741 @override | 741 @override |
742 scopeLookup(Scope scope, String name, int charOffset, | 742 scopeLookup(Scope scope, String name, int charOffset, |
743 {bool isQualified: false}) { | 743 {bool isQualified: false, PrefixBuilder prefix}) { |
744 Builder builder = scope.lookup(name, charOffset, uri); | 744 Builder builder = scope.lookup(name, charOffset, uri); |
745 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { | 745 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { |
746 Name n = new Name(name, library.library); | 746 Name n = new Name(name, library.library); |
747 if (!isQualified && isInstanceContext) { | 747 if (prefix != null && |
| 748 prefix.deferred && |
| 749 builder == null && |
| 750 "loadLibrary" == name) { |
| 751 return buildCompileTimeError( |
| 752 "Deferred loading isn't implemented yet.", charOffset); |
| 753 } else if (!isQualified && isInstanceContext) { |
748 assert(builder == null); | 754 assert(builder == null); |
749 if (constantExpressionRequired) { | 755 if (constantExpressionRequired) { |
750 return new UnresolvedAccessor(this, n, charOffset); | 756 return new UnresolvedAccessor(this, n, charOffset); |
751 } | 757 } |
752 return new ThisPropertyAccessor(this, charOffset, n, null, null); | 758 return new ThisPropertyAccessor(this, charOffset, n, null, null); |
753 } else if (isDartLibrary && | 759 } else if (isDartLibrary && |
754 name == "main" && | 760 name == "main" && |
755 library.uri.path == "_builtin" && | 761 library.uri.path == "_builtin" && |
756 member?.name == "_getMainClosure") { | 762 member?.name == "_getMainClosure") { |
757 // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 | 763 // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 |
(...skipping 14 matching lines...) Expand all Loading... |
772 } else if (builder.isInstanceMember) { | 778 } else if (builder.isInstanceMember) { |
773 if (constantExpressionRequired) { | 779 if (constantExpressionRequired) { |
774 addCompileTimeError(charOffset, "Not a constant expression."); | 780 addCompileTimeError(charOffset, "Not a constant expression."); |
775 } | 781 } |
776 return new ThisPropertyAccessor( | 782 return new ThisPropertyAccessor( |
777 this, charOffset, new Name(name, library.library), null, null); | 783 this, charOffset, new Name(name, library.library), null, null); |
778 } else if (builder.isRegularMethod) { | 784 } else if (builder.isRegularMethod) { |
779 assert(builder.isStatic || builder.isTopLevel); | 785 assert(builder.isStatic || builder.isTopLevel); |
780 return new StaticAccessor(this, charOffset, builder.target, null); | 786 return new StaticAccessor(this, charOffset, builder.target, null); |
781 } else if (builder is PrefixBuilder) { | 787 } else if (builder is PrefixBuilder) { |
| 788 if (constantExpressionRequired && builder.deferred) { |
| 789 addCompileTimeError( |
| 790 charOffset, |
| 791 "'$name' can't be used in a constant expression because it's " |
| 792 "marked as 'deferred' which means it isn't available until " |
| 793 "loaded.\n" |
| 794 "You might try moving the constant to the deferred library, " |
| 795 "or removing 'deferred' from the import."); |
| 796 } |
782 return builder; | 797 return builder; |
783 } else { | 798 } else { |
784 if (builder.hasProblem && builder is! AccessErrorBuilder) return builder; | 799 if (builder.hasProblem && builder is! AccessErrorBuilder) return builder; |
785 Builder setter; | 800 Builder setter; |
786 if (builder.isSetter) { | 801 if (builder.isSetter) { |
787 setter = builder; | 802 setter = builder; |
788 } else if (builder.isGetter) { | 803 } else if (builder.isGetter) { |
789 setter = scope.lookupSetter(name, charOffset, uri); | 804 setter = scope.lookupSetter(name, charOffset, uri); |
790 } else if (builder.isField && !builder.isFinal) { | 805 } else if (builder.isField && !builder.isFinal) { |
791 setter = builder; | 806 setter = builder; |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1272 suffix = suffix.name; | 1287 suffix = suffix.name; |
1273 } | 1288 } |
1274 Builder builder; | 1289 Builder builder; |
1275 if (prefix is Builder) { | 1290 if (prefix is Builder) { |
1276 builder = prefix; | 1291 builder = prefix; |
1277 } else { | 1292 } else { |
1278 builder = scope.lookup(prefix, beginToken.charOffset, uri); | 1293 builder = scope.lookup(prefix, beginToken.charOffset, uri); |
1279 } | 1294 } |
1280 if (builder is PrefixBuilder) { | 1295 if (builder is PrefixBuilder) { |
1281 name = scopeLookup(builder.exports, suffix, beginToken.charOffset, | 1296 name = scopeLookup(builder.exports, suffix, beginToken.charOffset, |
1282 isQualified: true); | 1297 isQualified: true, prefix: builder); |
1283 } else { | 1298 } else { |
1284 push(const DynamicType()); | 1299 push(const DynamicType()); |
1285 addCompileTimeError(beginToken.charOffset, | 1300 addCompileTimeError(beginToken.charOffset, |
1286 "Can't be used as a type: '${debugName(prefix, suffix)}'."); | 1301 "Can't be used as a type: '${debugName(prefix, suffix)}'."); |
1287 return; | 1302 return; |
1288 } | 1303 } |
1289 } | 1304 } |
1290 if (name is Identifier) { | 1305 if (name is Identifier) { |
1291 name = name.name; | 1306 name = name.name; |
1292 } | 1307 } |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1652 // should be handled later. | 1667 // should be handled later. |
1653 Identifier suffix = popIfNotNull(periodBeforeName); | 1668 Identifier suffix = popIfNotNull(periodBeforeName); |
1654 Identifier identifier; | 1669 Identifier identifier; |
1655 List<DartType> typeArguments = pop(); | 1670 List<DartType> typeArguments = pop(); |
1656 dynamic type = pop(); | 1671 dynamic type = pop(); |
1657 if (type is List) { | 1672 if (type is List) { |
1658 var prefix = type[0]; | 1673 var prefix = type[0]; |
1659 identifier = type[1]; | 1674 identifier = type[1]; |
1660 if (prefix is PrefixBuilder) { | 1675 if (prefix is PrefixBuilder) { |
1661 type = scopeLookup(prefix.exports, identifier.name, start.charOffset, | 1676 type = scopeLookup(prefix.exports, identifier.name, start.charOffset, |
1662 isQualified: true); | 1677 isQualified: true, prefix: prefix); |
1663 identifier = null; | 1678 identifier = null; |
1664 } else if (prefix is ClassBuilder) { | 1679 } else if (prefix is ClassBuilder) { |
1665 type = prefix; | 1680 type = prefix; |
1666 } else { | 1681 } else { |
1667 type = new Identifier(start.lexeme, start.charOffset); | 1682 type = new Identifier(start.lexeme, start.charOffset); |
1668 } | 1683 } |
1669 } | 1684 } |
1670 String name; | 1685 String name; |
1671 if (identifier != null && suffix != null) { | 1686 if (identifier != null && suffix != null) { |
1672 name = "${identifier.name}.${suffix.name}"; | 1687 name = "${identifier.name}.${suffix.name}"; |
(...skipping 1252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2925 } else if (node is PrefixBuilder) { | 2940 } else if (node is PrefixBuilder) { |
2926 return node.name; | 2941 return node.name; |
2927 } else if (node is ThisAccessor) { | 2942 } else if (node is ThisAccessor) { |
2928 return node.isSuper ? "super" : "this"; | 2943 return node.isSuper ? "super" : "this"; |
2929 } else if (node is FastaAccessor) { | 2944 } else if (node is FastaAccessor) { |
2930 return node.plainNameForRead; | 2945 return node.plainNameForRead; |
2931 } else { | 2946 } else { |
2932 return internalError("Unhandled: ${node.runtimeType}"); | 2947 return internalError("Unhandled: ${node.runtimeType}"); |
2933 } | 2948 } |
2934 } | 2949 } |
OLD | NEW |