| 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 '../parser/parser.dart' show FormalParameterType, optional; | 7 import '../parser/parser.dart' show FormalParameterType, optional; |
| 8 | 8 |
| 9 import '../parser/error_kind.dart' show ErrorKind; | 9 import '../parser/error_kind.dart' show ErrorKind; |
| 10 | 10 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 import '../parser/dart_vm_native.dart' show skipNativeClause; | 23 import '../parser/dart_vm_native.dart' show skipNativeClause; |
| 24 | 24 |
| 25 import '../scanner/token.dart' | 25 import '../scanner/token.dart' |
| 26 show BeginGroupToken, Token, isBinaryOperator, isMinusOperator; | 26 show BeginGroupToken, Token, isBinaryOperator, isMinusOperator; |
| 27 | 27 |
| 28 import '../errors.dart' show formatUnexpected, internalError; | 28 import '../errors.dart' show formatUnexpected, internalError; |
| 29 | 29 |
| 30 import '../source/scope_listener.dart' | 30 import '../source/scope_listener.dart' |
| 31 show JumpTargetKind, NullValue, ScopeListener; | 31 show JumpTargetKind, NullValue, ScopeListener; |
| 32 | 32 |
| 33 import '../builder/scope.dart' show AccessErrorBuilder, AmbiguousBuilder, Scope; | 33 import '../builder/scope.dart' show ProblemBuilder, Scope; |
| 34 | 34 |
| 35 import '../source/outline_builder.dart' show asyncMarkerFromTokens; | 35 import '../source/outline_builder.dart' show asyncMarkerFromTokens; |
| 36 | 36 |
| 37 import 'builder_accessors.dart'; | 37 import 'builder_accessors.dart'; |
| 38 | 38 |
| 39 import 'frontend_accessors.dart' show buildIsNull, makeBinary, makeLet; | 39 import 'frontend_accessors.dart' show buildIsNull, makeBinary, makeLet; |
| 40 | 40 |
| 41 import 'builder_accessors.dart' as builder_accessors | 41 import 'builder_accessors.dart' as builder_accessors |
| 42 show throwNoSuchMethodError; | 42 show throwNoSuchMethodError; |
| 43 | 43 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 | 103 |
| 104 final Scope enclosingScope; | 104 final Scope enclosingScope; |
| 105 | 105 |
| 106 final bool isDartLibrary; | 106 final bool isDartLibrary; |
| 107 | 107 |
| 108 @override | 108 @override |
| 109 final Uri uri; | 109 final Uri uri; |
| 110 | 110 |
| 111 Scope formalParameterScope; | 111 Scope formalParameterScope; |
| 112 | 112 |
| 113 bool isFirstIdentifier = false; | |
| 114 | |
| 115 bool inInitializer = false; | 113 bool inInitializer = false; |
| 116 | 114 |
| 117 bool inCatchClause = false; | 115 bool inCatchClause = false; |
| 118 | 116 |
| 119 int functionNestingLevel = 0; | 117 int functionNestingLevel = 0; |
| 120 | 118 |
| 121 Statement compileTimeErrorInTry; | 119 Statement compileTimeErrorInTry; |
| 122 | 120 |
| 123 Statement compileTimeErrorInLoopOrSwitch; | 121 Statement compileTimeErrorInLoopOrSwitch; |
| 124 | 122 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 146 bool get inConstructor { | 144 bool get inConstructor { |
| 147 return functionNestingLevel == 0 && member is KernelConstructorBuilder; | 145 return functionNestingLevel == 0 && member is KernelConstructorBuilder; |
| 148 } | 146 } |
| 149 | 147 |
| 150 bool get isInstanceContext { | 148 bool get isInstanceContext { |
| 151 return isInstanceMember || member is KernelConstructorBuilder; | 149 return isInstanceMember || member is KernelConstructorBuilder; |
| 152 } | 150 } |
| 153 | 151 |
| 154 @override | 152 @override |
| 155 void push(Object node) { | 153 void push(Object node) { |
| 156 isFirstIdentifier = false; | |
| 157 inInitializer = false; | 154 inInitializer = false; |
| 158 super.push(node); | 155 super.push(node); |
| 159 } | 156 } |
| 160 | 157 |
| 161 Expression popForValue() => toValue(pop()); | 158 Expression popForValue() => toValue(pop()); |
| 162 | 159 |
| 163 Expression popForEffect() => toEffect(pop()); | 160 Expression popForEffect() => toEffect(pop()); |
| 164 | 161 |
| 165 Expression popForValueIfNotNull(Object value) { | 162 Expression popForValueIfNotNull(Object value) { |
| 166 return value == null ? null : popForValue(); | 163 return value == null ? null : popForValue(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 190 return new TypeLiteral(type); | 187 return new TypeLiteral(type); |
| 191 } | 188 } |
| 192 } else if (node is TypeDeclarationBuilder) { | 189 } else if (node is TypeDeclarationBuilder) { |
| 193 return new TypeLiteral(node.buildTypesWithBuiltArguments(library, null)); | 190 return new TypeLiteral(node.buildTypesWithBuiltArguments(library, null)); |
| 194 } else if (node is KernelTypeBuilder) { | 191 } else if (node is KernelTypeBuilder) { |
| 195 return new TypeLiteral(node.build(library)); | 192 return new TypeLiteral(node.build(library)); |
| 196 } else if (node is Expression) { | 193 } else if (node is Expression) { |
| 197 return node; | 194 return node; |
| 198 } else if (node is PrefixBuilder) { | 195 } else if (node is PrefixBuilder) { |
| 199 return buildCompileTimeError("A library can't be used as an expression."); | 196 return buildCompileTimeError("A library can't be used as an expression."); |
| 197 } else if (node is ProblemBuilder) { |
| 198 return buildProblemExpression(node, -1); |
| 200 } else { | 199 } else { |
| 201 return internalError("Unhandled: ${node.runtimeType}"); | 200 return internalError("Unhandled: ${node.runtimeType}"); |
| 202 } | 201 } |
| 203 } | 202 } |
| 204 | 203 |
| 205 Expression toEffect(Object node) { | 204 Expression toEffect(Object node) { |
| 206 if (node is BuilderAccessor) return node.buildForEffect(); | 205 if (node is BuilderAccessor) return node.buildForEffect(); |
| 207 return toValue(node); | 206 return toValue(node); |
| 208 } | 207 } |
| 209 | 208 |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 } | 705 } |
| 707 if (cls != null) { | 706 if (cls != null) { |
| 708 for (Constructor constructor in cls.constructors) { | 707 for (Constructor constructor in cls.constructors) { |
| 709 if (constructor.name == name) return constructor; | 708 if (constructor.name == name) return constructor; |
| 710 } | 709 } |
| 711 } | 710 } |
| 712 return null; | 711 return null; |
| 713 } | 712 } |
| 714 | 713 |
| 715 @override | 714 @override |
| 716 void beginExpression(Token token) { | |
| 717 debugEvent("beginExpression"); | |
| 718 isFirstIdentifier = true; | |
| 719 } | |
| 720 | |
| 721 Builder computeSetter( | |
| 722 Builder builder, Scope scope, String name, int charOffset) { | |
| 723 if (builder.isSetter) return builder; | |
| 724 if (builder.isGetter) return scope.lookupSetter(name, charOffset, uri); | |
| 725 return builder.isField ? (builder.isFinal ? null : builder) : null; | |
| 726 } | |
| 727 | |
| 728 @override | |
| 729 void handleIdentifier(Token token, IdentifierContext context) { | 715 void handleIdentifier(Token token, IdentifierContext context) { |
| 730 debugEvent("handleIdentifier"); | 716 debugEvent("handleIdentifier"); |
| 731 String name = token.lexeme; | 717 String name = token.lexeme; |
| 732 if (isFirstIdentifier) { | 718 if (context.isScopeReference) { |
| 733 assert(!inInitializer || | 719 assert(!inInitializer || |
| 734 this.scope == enclosingScope || | 720 this.scope == enclosingScope || |
| 735 this.scope.parent == enclosingScope); | 721 this.scope.parent == enclosingScope); |
| 736 // This deals with this kind of initializer: `C(a) : a = a;` | 722 // This deals with this kind of initializer: `C(a) : a = a;` |
| 737 Scope scope = inInitializer ? enclosingScope : this.scope; | 723 Scope scope = inInitializer ? enclosingScope : this.scope; |
| 738 Builder builder = scope.lookup(name, token.charOffset, uri); | 724 Builder builder = scope.lookup(name, token.charOffset, uri); |
| 739 push(builderToFirstExpression(builder, name, token.charOffset)); | 725 push(builderToFirstExpression(builder, name, token.charOffset)); |
| 740 } else { | 726 } else { |
| 741 push(new Identifier(name)..fileOffset = token.charOffset); | 727 push(new Identifier(name)..fileOffset = token.charOffset); |
| 742 } | 728 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 765 this, charOffset, new Name(name, library.library), null, null); | 751 this, charOffset, new Name(name, library.library), null, null); |
| 766 } else if (builder.isRegularMethod) { | 752 } else if (builder.isRegularMethod) { |
| 767 assert(builder.isStatic || builder.isTopLevel); | 753 assert(builder.isStatic || builder.isTopLevel); |
| 768 return new StaticAccessor(this, charOffset, builder.target, null); | 754 return new StaticAccessor(this, charOffset, builder.target, null); |
| 769 } else if (builder is PrefixBuilder) { | 755 } else if (builder is PrefixBuilder) { |
| 770 return builder; | 756 return builder; |
| 771 } else if (builder is MixedAccessor) { | 757 } else if (builder is MixedAccessor) { |
| 772 return new StaticAccessor( | 758 return new StaticAccessor( |
| 773 this, charOffset, builder.getter.target, builder.setter.target); | 759 this, charOffset, builder.getter.target, builder.setter.target); |
| 774 } else { | 760 } else { |
| 775 if (builder is AccessErrorBuilder) { | 761 if (builder.hasProblem && builder is! AccessErrorBuilder) return builder; |
| 776 AccessErrorBuilder error = builder; | 762 Builder setter; |
| 777 builder = error.builder; | 763 if (builder.isSetter) { |
| 764 setter = builder; |
| 765 } else if (builder.isGetter) { |
| 766 setter = scope.lookupSetter(name, charOffset, uri); |
| 767 } else if (builder.isField && !builder.isFinal) { |
| 768 setter = builder; |
| 778 } | 769 } |
| 779 if (builder.target == null) { | 770 return new StaticAccessor.fromBuilder(this, builder, charOffset, setter); |
| 780 return internalError("Unhandled: ${builder}"); | |
| 781 } | |
| 782 Member getter = builder.target.hasGetter ? builder.target : null; | |
| 783 Member setter = builder.target.hasSetter ? builder.target : null; | |
| 784 setter ??= computeSetter(builder, scope, name, charOffset)?.target; | |
| 785 return new StaticAccessor(this, charOffset, getter, setter); | |
| 786 } | 771 } |
| 787 } | 772 } |
| 788 | 773 |
| 789 @override | 774 @override |
| 790 void handleQualified(Token period) { | 775 void handleQualified(Token period) { |
| 791 debugEvent("Qualified"); | 776 debugEvent("Qualified"); |
| 792 Identifier name = pop(); | 777 Identifier name = pop(); |
| 793 var receiver = pop(); | 778 var receiver = pop(); |
| 794 push([receiver, name]); | 779 push([receiver, name]); |
| 795 } | 780 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 813 Token token = pop(); | 798 Token token = pop(); |
| 814 push(new StringLiteral(unescapeString(token.lexeme))); | 799 push(new StringLiteral(unescapeString(token.lexeme))); |
| 815 } else { | 800 } else { |
| 816 List parts = popList(1 + interpolationCount * 2); | 801 List parts = popList(1 + interpolationCount * 2); |
| 817 Token first = parts.first; | 802 Token first = parts.first; |
| 818 Token last = parts.last; | 803 Token last = parts.last; |
| 819 Quote quote = analyzeQuote(first.lexeme); | 804 Quote quote = analyzeQuote(first.lexeme); |
| 820 List<Expression> expressions = <Expression>[]; | 805 List<Expression> expressions = <Expression>[]; |
| 821 // Contains more than just \' or \". | 806 // Contains more than just \' or \". |
| 822 if (first.lexeme.length > 1) { | 807 if (first.lexeme.length > 1) { |
| 823 expressions | 808 expressions.add( |
| 824 .add(new StringLiteral(unescapeFirstStringPart(first.lexeme, quote))); | 809 new StringLiteral(unescapeFirstStringPart(first.lexeme, quote))); |
| 825 } | 810 } |
| 826 for (int i = 1; i < parts.length - 1; i++) { | 811 for (int i = 1; i < parts.length - 1; i++) { |
| 827 var part = parts[i]; | 812 var part = parts[i]; |
| 828 if (part is Token) { | 813 if (part is Token) { |
| 829 if (part.lexeme.length != 0) { | 814 if (part.lexeme.length != 0) { |
| 830 expressions.add(new StringLiteral(unescape(part.lexeme, quote))); | 815 expressions.add(new StringLiteral(unescape(part.lexeme, quote))); |
| 831 } | 816 } |
| 832 } else { | 817 } else { |
| 833 expressions.add(toValue(part)); | 818 expressions.add(toValue(part)); |
| 834 } | 819 } |
| 835 } | 820 } |
| 836 // Contains more than just \' or \". | 821 // Contains more than just \' or \". |
| 837 if (last.lexeme.length > 1) { | 822 if (last.lexeme.length > 1) { |
| 838 expressions | 823 expressions |
| 839 .add(new StringLiteral(unescapeLastStringPart(last.lexeme, quote))); | 824 .add(new StringLiteral(unescapeLastStringPart(last.lexeme, quote))); |
| 840 } | 825 } |
| 841 push(new StringConcatenation(expressions) | 826 push(new StringConcatenation(expressions) |
| 842 ..fileOffset = endToken.charOffset); | 827 ..fileOffset = endToken.charOffset); |
| 843 } | 828 } |
| 844 } | 829 } |
| 845 | 830 |
| 846 @override | 831 @override |
| 847 void handleScript(Token token) { | 832 void handleScript(Token token) { |
| 848 debugEvent("Script"); | 833 debugEvent("Script"); |
| 849 } | 834 } |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 990 | 975 |
| 991 @override | 976 @override |
| 992 void handleAssignmentExpression(Token token) { | 977 void handleAssignmentExpression(Token token) { |
| 993 debugEvent("AssignmentExpression"); | 978 debugEvent("AssignmentExpression"); |
| 994 Expression value = popForValue(); | 979 Expression value = popForValue(); |
| 995 var accessor = pop(); | 980 var accessor = pop(); |
| 996 if (accessor is TypeDeclarationBuilder) { | 981 if (accessor is TypeDeclarationBuilder) { |
| 997 push(wrapInvalid(new TypeLiteral( | 982 push(wrapInvalid(new TypeLiteral( |
| 998 accessor.buildTypesWithBuiltArguments(library, null)))); | 983 accessor.buildTypesWithBuiltArguments(library, null)))); |
| 999 } else if (accessor is! BuilderAccessor) { | 984 } else if (accessor is! BuilderAccessor) { |
| 985 print(accessor); |
| 1000 push(buildCompileTimeError("Can't assign to this.", token.charOffset)); | 986 push(buildCompileTimeError("Can't assign to this.", token.charOffset)); |
| 1001 } else { | 987 } else { |
| 1002 push(new DelayedAssignment( | 988 push(new DelayedAssignment( |
| 1003 this, token.charOffset, accessor, value, token.stringValue)); | 989 this, token.charOffset, accessor, value, token.stringValue)); |
| 1004 } | 990 } |
| 1005 } | 991 } |
| 1006 | 992 |
| 1007 @override | 993 @override |
| 1008 void enterLoop(int charOffset) { | 994 void enterLoop(int charOffset) { |
| 1009 if (peek() is LabelTarget) { | 995 if (peek() is LabelTarget) { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1152 } | 1138 } |
| 1153 | 1139 |
| 1154 @override | 1140 @override |
| 1155 void endLiteralMapEntry(Token colon, Token endToken) { | 1141 void endLiteralMapEntry(Token colon, Token endToken) { |
| 1156 debugEvent("LiteralMapEntry"); | 1142 debugEvent("LiteralMapEntry"); |
| 1157 Expression value = popForValue(); | 1143 Expression value = popForValue(); |
| 1158 Expression key = popForValue(); | 1144 Expression key = popForValue(); |
| 1159 push(new MapEntry(key, value)); | 1145 push(new MapEntry(key, value)); |
| 1160 } | 1146 } |
| 1161 | 1147 |
| 1162 @override | |
| 1163 void beginLiteralSymbol(Token token) { | |
| 1164 isFirstIdentifier = false; | |
| 1165 } | |
| 1166 | |
| 1167 String symbolPartToString(name) { | 1148 String symbolPartToString(name) { |
| 1168 if (name is Identifier) { | 1149 if (name is Identifier) { |
| 1169 return name.name; | 1150 return name.name; |
| 1170 } else if (name is Operator) { | 1151 } else if (name is Operator) { |
| 1171 return name.name; | 1152 return name.name; |
| 1172 } else { | 1153 } else { |
| 1173 return internalError("Unhandled: ${name.runtimeType}"); | 1154 return internalError("Unhandled: ${name.runtimeType}"); |
| 1174 } | 1155 } |
| 1175 } | 1156 } |
| 1176 | 1157 |
| 1177 @override | 1158 @override |
| 1178 void endLiteralSymbol(Token hashToken, int identifierCount) { | 1159 void endLiteralSymbol(Token hashToken, int identifierCount) { |
| 1179 debugEvent("LiteralSymbol"); | 1160 debugEvent("LiteralSymbol"); |
| 1180 String value; | 1161 String value; |
| 1181 if (identifierCount == 1) { | 1162 if (identifierCount == 1) { |
| 1182 value = symbolPartToString(popForValue()); | 1163 value = symbolPartToString(popForValue()); |
| 1183 } else { | 1164 } else { |
| 1184 List parts = popList(identifierCount); | 1165 List parts = popList(identifierCount); |
| 1185 value = symbolPartToString(parts.first); | 1166 value = symbolPartToString(parts.first); |
| 1186 for (int i = 1; i < parts.length; i++) { | 1167 for (int i = 1; i < parts.length; i++) { |
| 1187 value += ".${symbolPartToString(parts[i])}"; | 1168 value += ".${symbolPartToString(parts[i])}"; |
| 1188 } | 1169 } |
| 1189 } | 1170 } |
| 1190 push(new SymbolLiteral(value)); | 1171 push(new SymbolLiteral(value)); |
| 1191 } | 1172 } |
| 1192 | 1173 |
| 1193 DartType toKernelType(String name, List<DartType> arguments, int charOffset) { | 1174 DartType kernelTypeFromString( |
| 1175 String name, List<DartType> arguments, int charOffset) { |
| 1194 if (identical(name, "void")) return const VoidType(); | 1176 if (identical(name, "void")) return const VoidType(); |
| 1195 if (identical(name, "dynamic")) return const DynamicType(); | 1177 if (identical(name, "dynamic")) return const DynamicType(); |
| 1196 Builder builder = scope.lookup(name, charOffset, uri); | 1178 Builder builder = scope.lookup(name, charOffset, uri); |
| 1179 if (builder == null) { |
| 1180 warning("Type not found: '$name'.", charOffset); |
| 1181 return const DynamicType(); |
| 1182 } else { |
| 1183 return kernelTypeFromBuilder(builder, arguments, charOffset); |
| 1184 } |
| 1185 } |
| 1186 |
| 1187 DartType kernelTypeFromBuilder( |
| 1188 Builder builder, List<DartType> arguments, int charOffset) { |
| 1197 if (builder is TypeDeclarationBuilder) { | 1189 if (builder is TypeDeclarationBuilder) { |
| 1198 return builder.buildTypesWithBuiltArguments(library, arguments); | 1190 return builder.buildTypesWithBuiltArguments(library, arguments); |
| 1199 } | 1191 } else if (builder.hasProblem) { |
| 1200 if (builder == null) { | 1192 ProblemBuilder problem = builder; |
| 1201 warning("Type not found: '$name'.", charOffset); | 1193 addCompileTimeError(charOffset, problem.message); |
| 1202 } else { | 1194 } else { |
| 1203 warning("Not a type: '$name'.", charOffset); | 1195 warning("Not a type: '${builder.fullNameForErrors}'.", charOffset); |
| 1204 } | 1196 } |
| 1205 // TODO(ahe): Create an error somehow. | 1197 // TODO(ahe): Create an error somehow. |
| 1206 return const DynamicType(); | 1198 return const DynamicType(); |
| 1207 } | 1199 } |
| 1208 | 1200 |
| 1209 @override | 1201 @override |
| 1210 void handleType(Token beginToken, Token endToken) { | 1202 void handleType(Token beginToken, Token endToken) { |
| 1211 // TODO(ahe): The scope is wrong for return types of generic functions. | 1203 // TODO(ahe): The scope is wrong for return types of generic functions. |
| 1212 debugEvent("Type"); | 1204 debugEvent("Type"); |
| 1213 List<DartType> arguments = pop(); | 1205 List<DartType> arguments = pop(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1224 if (suffix is Identifier) { | 1216 if (suffix is Identifier) { |
| 1225 suffix = suffix.name; | 1217 suffix = suffix.name; |
| 1226 } | 1218 } |
| 1227 Builder builder; | 1219 Builder builder; |
| 1228 if (prefix is Builder) { | 1220 if (prefix is Builder) { |
| 1229 builder = prefix; | 1221 builder = prefix; |
| 1230 } else { | 1222 } else { |
| 1231 builder = scope.lookup(prefix, beginToken.charOffset, uri); | 1223 builder = scope.lookup(prefix, beginToken.charOffset, uri); |
| 1232 } | 1224 } |
| 1233 if (builder is PrefixBuilder) { | 1225 if (builder is PrefixBuilder) { |
| 1234 name = builder.exports[suffix]; | 1226 name = builderToFirstExpression(builder.exports[suffix], suffix, beginTo
ken.charOffset, isPrefix: true); |
| 1235 } else { | 1227 } else { |
| 1236 push(const DynamicType()); | 1228 push(const DynamicType()); |
| 1237 addCompileTimeError(beginToken.charOffset, | 1229 addCompileTimeError(beginToken.charOffset, |
| 1238 "Can't be used as a type: '${debugName(prefix, suffix)}'."); | 1230 "Can't be used as a type: '${debugName(prefix, suffix)}'."); |
| 1239 return; | 1231 return; |
| 1240 } | 1232 } |
| 1241 } | 1233 } |
| 1242 if (name is Identifier) { | 1234 if (name is Identifier) { |
| 1243 name = name.name; | 1235 name = name.name; |
| 1244 } | 1236 } |
| 1245 if (name is BuilderAccessor) { | 1237 if (name is BuilderAccessor) { |
| 1246 warning("'${beginToken.lexeme}' isn't a type.", beginToken.charOffset); | 1238 warning("'${beginToken.lexeme}' isn't a type.", beginToken.charOffset); |
| 1247 push(const DynamicType()); | 1239 push(const DynamicType()); |
| 1248 } else if (name is UnresolvedIdentifier) { | 1240 } else if (name is UnresolvedIdentifier) { |
| 1249 warning("'${name.name}' isn't a type.", beginToken.charOffset); | 1241 warning("'${name.name}' isn't a type.", beginToken.charOffset); |
| 1250 push(const DynamicType()); | 1242 push(const DynamicType()); |
| 1251 } else if (name is TypeVariableBuilder) { | 1243 } else if (name is TypeVariableBuilder) { |
| 1252 push(name.buildTypesWithBuiltArguments(library, arguments)); | 1244 push(name.buildTypesWithBuiltArguments(library, arguments)); |
| 1253 } else if (name is TypeDeclarationBuilder) { | 1245 } else if (name is TypeDeclarationBuilder) { |
| 1254 push(name.buildTypesWithBuiltArguments(library, arguments)); | 1246 push(name.buildTypesWithBuiltArguments(library, arguments)); |
| 1255 } else if (name is TypeBuilder) { | 1247 } else if (name is TypeBuilder) { |
| 1256 push(name.build(library)); | 1248 push(name.build(library)); |
| 1249 } else if (name is Builder) { |
| 1250 push(kernelTypeFromBuilder(name, arguments, beginToken.charOffset)); |
| 1251 } else if (name is String) { |
| 1252 push(kernelTypeFromString(name, arguments, beginToken.charOffset)); |
| 1257 } else { | 1253 } else { |
| 1258 push(toKernelType(name, arguments, beginToken.charOffset)); | 1254 internalError("Unhandled: '${name.runtimeType}'."); |
| 1259 } | 1255 } |
| 1260 if (peek() is TypeParameterType) { | 1256 if (peek() is TypeParameterType) { |
| 1261 TypeParameterType type = peek(); | 1257 TypeParameterType type = peek(); |
| 1262 if (!isInstanceContext && type.parameter.parent is Class) { | 1258 if (!isInstanceContext && type.parameter.parent is Class) { |
| 1263 pop(); | 1259 pop(); |
| 1264 warning("Type variables can only be used in instance methods.", | 1260 warning("Type variables can only be used in instance methods.", |
| 1265 beginToken.charOffset); | 1261 beginToken.charOffset); |
| 1266 push(const DynamicType()); | 1262 push(const DynamicType()); |
| 1267 } | 1263 } |
| 1268 } | 1264 } |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1627 } | 1623 } |
| 1628 if (target is Constructor) { | 1624 if (target is Constructor) { |
| 1629 return new ConstructorInvocation(target, arguments)..isConst = isConst; | 1625 return new ConstructorInvocation(target, arguments)..isConst = isConst; |
| 1630 } else { | 1626 } else { |
| 1631 return new StaticInvocation(target, arguments)..isConst = isConst; | 1627 return new StaticInvocation(target, arguments)..isConst = isConst; |
| 1632 } | 1628 } |
| 1633 } | 1629 } |
| 1634 | 1630 |
| 1635 bool checkArguments(FunctionNode function, Arguments arguments, | 1631 bool checkArguments(FunctionNode function, Arguments arguments, |
| 1636 List<TypeParameter> typeParameters) { | 1632 List<TypeParameter> typeParameters) { |
| 1637 | |
| 1638 if (arguments.positional.length < function.requiredParameterCount || | 1633 if (arguments.positional.length < function.requiredParameterCount || |
| 1639 arguments.positional.length > function.positionalParameters.length) { | 1634 arguments.positional.length > function.positionalParameters.length) { |
| 1640 return false; | 1635 return false; |
| 1641 } | 1636 } |
| 1642 Map<String, VariableDeclaration> names; | 1637 Map<String, VariableDeclaration> names; |
| 1643 if (function.namedParameters.isNotEmpty) { | 1638 if (function.namedParameters.isNotEmpty) { |
| 1644 names = <String, VariableDeclaration>{}; | 1639 names = <String, VariableDeclaration>{}; |
| 1645 for (VariableDeclaration parameter in function.namedParameters) { | 1640 for (VariableDeclaration parameter in function.namedParameters) { |
| 1646 names[parameter.name] = parameter; | 1641 names[parameter.name] = parameter; |
| 1647 } | 1642 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1724 handleNewExpression(token); | 1719 handleNewExpression(token); |
| 1725 } | 1720 } |
| 1726 | 1721 |
| 1727 @override | 1722 @override |
| 1728 void endTypeArguments(int count, Token beginToken, Token endToken) { | 1723 void endTypeArguments(int count, Token beginToken, Token endToken) { |
| 1729 debugEvent("TypeArguments"); | 1724 debugEvent("TypeArguments"); |
| 1730 push(popList(count)); | 1725 push(popList(count)); |
| 1731 } | 1726 } |
| 1732 | 1727 |
| 1733 @override | 1728 @override |
| 1734 void handleThisExpression(Token token) { | 1729 void handleThisExpression(Token token, IdentifierContext context) { |
| 1735 debugEvent("ThisExpression"); | 1730 debugEvent("ThisExpression"); |
| 1736 if (isFirstIdentifier && isInstanceContext) { | 1731 if (context.isScopeReference && isInstanceContext) { |
| 1737 push(new ThisAccessor(this, token.charOffset, inInitializer)); | 1732 push(new ThisAccessor(this, token.charOffset, inInitializer)); |
| 1738 } else { | 1733 } else { |
| 1739 push(new IncompleteError( | 1734 push(new IncompleteError( |
| 1740 this, token.charOffset, "Expected identifier, but got 'this'.")); | 1735 this, token.charOffset, "Expected identifier, but got 'this'.")); |
| 1741 } | 1736 } |
| 1742 } | 1737 } |
| 1743 | 1738 |
| 1744 @override | 1739 @override |
| 1745 void handleSuperExpression(Token token) { | 1740 void handleSuperExpression(Token token, IdentifierContext context) { |
| 1746 debugEvent("SuperExpression"); | 1741 debugEvent("SuperExpression"); |
| 1747 if (isFirstIdentifier && isInstanceContext) { | 1742 if (context.isScopeReference && isInstanceContext) { |
| 1748 Member member = this.member.target; | 1743 Member member = this.member.target; |
| 1749 member.transformerFlags |= TransformerFlag.superCalls; | 1744 member.transformerFlags |= TransformerFlag.superCalls; |
| 1750 push(new ThisAccessor(this, token.charOffset, inInitializer, | 1745 push(new ThisAccessor(this, token.charOffset, inInitializer, |
| 1751 isSuper: true)); | 1746 isSuper: true)); |
| 1752 } else { | 1747 } else { |
| 1753 push(new IncompleteError( | 1748 push(new IncompleteError( |
| 1754 this, token.charOffset, "Expected identifier, but got 'super'.")); | 1749 this, token.charOffset, "Expected identifier, but got 'super'.")); |
| 1755 } | 1750 } |
| 1756 } | 1751 } |
| 1757 | 1752 |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2261 return new ExpressionStatement(buildCompileTimeError(error, charOffset)); | 2256 return new ExpressionStatement(buildCompileTimeError(error, charOffset)); |
| 2262 } | 2257 } |
| 2263 | 2258 |
| 2264 @override | 2259 @override |
| 2265 Initializer buildCompileTimeErrorIntializer(error, [int charOffset = -1]) { | 2260 Initializer buildCompileTimeErrorIntializer(error, [int charOffset = -1]) { |
| 2266 return new LocalInitializer(new VariableDeclaration.forValue( | 2261 return new LocalInitializer(new VariableDeclaration.forValue( |
| 2267 buildCompileTimeError(error, charOffset))); | 2262 buildCompileTimeError(error, charOffset))); |
| 2268 } | 2263 } |
| 2269 | 2264 |
| 2270 @override | 2265 @override |
| 2271 Expression buildProblemExpression(Builder builder, String name) { | 2266 Expression buildProblemExpression(ProblemBuilder builder, int charOffset) { |
| 2272 if (builder is AmbiguousBuilder) { | 2267 return buildCompileTimeError(builder.message, charOffset); |
| 2273 return buildCompileTimeError("Duplicated named: '$name'."); | |
| 2274 } else if (builder is AccessErrorBuilder) { | |
| 2275 return buildCompileTimeError("Access error: '$name'."); | |
| 2276 } else { | |
| 2277 return internalError("Unhandled: ${builder.runtimeType}"); | |
| 2278 } | |
| 2279 } | 2268 } |
| 2280 | 2269 |
| 2281 @override | 2270 @override |
| 2282 void handleOperator(Token token) { | 2271 void handleOperator(Token token) { |
| 2283 debugEvent("Operator"); | 2272 debugEvent("Operator"); |
| 2284 push(new Operator(token.stringValue)..fileOffset = token.charOffset); | 2273 push(new Operator(token.stringValue)..fileOffset = token.charOffset); |
| 2285 } | 2274 } |
| 2286 | 2275 |
| 2287 @override | 2276 @override |
| 2288 void handleSymbolVoid(Token token) { | 2277 void handleSymbolVoid(Token token) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2388 | 2377 |
| 2389 final int charOffset; | 2378 final int charOffset; |
| 2390 | 2379 |
| 2391 final BuilderAccessor accessor; | 2380 final BuilderAccessor accessor; |
| 2392 | 2381 |
| 2393 ContextAccessor(this.helper, this.charOffset, this.accessor); | 2382 ContextAccessor(this.helper, this.charOffset, this.accessor); |
| 2394 | 2383 |
| 2395 String get plainNameForRead => internalError("Unsupported operation."); | 2384 String get plainNameForRead => internalError("Unsupported operation."); |
| 2396 | 2385 |
| 2397 Expression doInvocation(int charOffset, Arguments arguments) { | 2386 Expression doInvocation(int charOffset, Arguments arguments) { |
| 2398 print("$uri:$charOffset: Internal error: Unhandled: ${runtimeType}"); | 2387 return internalError("Unhandled: ${runtimeType}", uri, charOffset); |
| 2399 return internalError("Unhandled: ${runtimeType}"); | |
| 2400 } | 2388 } |
| 2401 | 2389 |
| 2402 Expression buildSimpleRead(); | 2390 Expression buildSimpleRead(); |
| 2403 | 2391 |
| 2404 Expression buildForEffect(); | 2392 Expression buildForEffect(); |
| 2405 | 2393 |
| 2406 Expression buildAssignment(Expression value, {bool voidContext: false}) { | 2394 Expression buildAssignment(Expression value, {bool voidContext: false}) { |
| 2407 return makeInvalidWrite(value); | 2395 return makeInvalidWrite(value); |
| 2408 } | 2396 } |
| 2409 | 2397 |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2584 users.clear(); | 2572 users.clear(); |
| 2585 } | 2573 } |
| 2586 | 2574 |
| 2587 void resolveGotos(SwitchCase target) { | 2575 void resolveGotos(SwitchCase target) { |
| 2588 assert(isGotoTarget); | 2576 assert(isGotoTarget); |
| 2589 for (ContinueSwitchStatement user in users) { | 2577 for (ContinueSwitchStatement user in users) { |
| 2590 user.target = target; | 2578 user.target = target; |
| 2591 } | 2579 } |
| 2592 users.clear(); | 2580 users.clear(); |
| 2593 } | 2581 } |
| 2582 |
| 2583 @override |
| 2584 String get fullNameForErrors => "<jump-target>"; |
| 2594 } | 2585 } |
| 2595 | 2586 |
| 2596 class LabelTarget extends Builder implements JumpTarget { | 2587 class LabelTarget extends Builder implements JumpTarget { |
| 2597 final JumpTarget breakTarget; | 2588 final JumpTarget breakTarget; |
| 2598 | 2589 |
| 2599 final JumpTarget continueTarget; | 2590 final JumpTarget continueTarget; |
| 2600 | 2591 |
| 2601 final int functionNestingLevel; | 2592 final int functionNestingLevel; |
| 2602 | 2593 |
| 2603 LabelTarget(MemberBuilder member, this.functionNestingLevel, int charOffset) | 2594 LabelTarget(MemberBuilder member, this.functionNestingLevel, int charOffset) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2635 breakTarget.resolveBreaks(target); | 2626 breakTarget.resolveBreaks(target); |
| 2636 } | 2627 } |
| 2637 | 2628 |
| 2638 void resolveContinues(LabeledStatement target) { | 2629 void resolveContinues(LabeledStatement target) { |
| 2639 continueTarget.resolveContinues(target); | 2630 continueTarget.resolveContinues(target); |
| 2640 } | 2631 } |
| 2641 | 2632 |
| 2642 void resolveGotos(SwitchCase target) { | 2633 void resolveGotos(SwitchCase target) { |
| 2643 internalError("Unsupported operation."); | 2634 internalError("Unsupported operation."); |
| 2644 } | 2635 } |
| 2636 |
| 2637 @override |
| 2638 String get fullNameForErrors => "<label-target>"; |
| 2645 } | 2639 } |
| 2646 | 2640 |
| 2647 class OptionalFormals { | 2641 class OptionalFormals { |
| 2648 final FormalParameterType kind; | 2642 final FormalParameterType kind; |
| 2649 | 2643 |
| 2650 final List<VariableDeclaration> formals; | 2644 final List<VariableDeclaration> formals; |
| 2651 | 2645 |
| 2652 OptionalFormals(this.kind, this.formals); | 2646 OptionalFormals(this.kind, this.formals); |
| 2653 } | 2647 } |
| 2654 | 2648 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2749 } else if (node is PrefixBuilder) { | 2743 } else if (node is PrefixBuilder) { |
| 2750 return node.name; | 2744 return node.name; |
| 2751 } else if (node is ThisAccessor) { | 2745 } else if (node is ThisAccessor) { |
| 2752 return node.isSuper ? "super" : "this"; | 2746 return node.isSuper ? "super" : "this"; |
| 2753 } else if (node is BuilderAccessor) { | 2747 } else if (node is BuilderAccessor) { |
| 2754 return node.plainNameForRead; | 2748 return node.plainNameForRead; |
| 2755 } else { | 2749 } else { |
| 2756 return internalError("Unhandled: ${node.runtimeType}"); | 2750 return internalError("Unhandled: ${node.runtimeType}"); |
| 2757 } | 2751 } |
| 2758 } | 2752 } |
| OLD | NEW |