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 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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}) { |
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 (!isQualified && isInstanceContext) { |
748 assert(builder == null); | 748 assert(builder == null); |
749 if (constantExpressionRequired) { | 749 if (constantExpressionRequired) { |
750 addCompileTimeError(charOffset, "Not a constant expression."); | 750 return new UnresolvedAccessor(this, n, charOffset); |
751 } | 751 } |
752 return new ThisPropertyAccessor(this, charOffset, n, null, null); | 752 return new ThisPropertyAccessor(this, charOffset, n, null, null); |
753 } else if (isDartLibrary && | 753 } else if (isDartLibrary && |
754 name == "main" && | 754 name == "main" && |
755 library.uri.path == "_builtin" && | 755 library.uri.path == "_builtin" && |
756 member?.name == "_getMainClosure") { | 756 member?.name == "_getMainClosure") { |
757 // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 | 757 // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 |
758 return new NullLiteral()..fileOffset = charOffset; | 758 return new NullLiteral()..fileOffset = charOffset; |
759 } else { | 759 } else { |
760 return new UnresolvedAccessor(this, n, charOffset); | 760 return new UnresolvedAccessor(this, n, charOffset); |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1129 void handleLiteralList( | 1129 void handleLiteralList( |
1130 int count, Token beginToken, Token constKeyword, Token endToken) { | 1130 int count, Token beginToken, Token constKeyword, Token endToken) { |
1131 debugEvent("LiteralList"); | 1131 debugEvent("LiteralList"); |
1132 List<Expression> expressions = popListForValue(count); | 1132 List<Expression> expressions = popListForValue(count); |
1133 List<DartType> typeArguments = pop(); | 1133 List<DartType> typeArguments = pop(); |
1134 DartType typeArgument = const DynamicType(); | 1134 DartType typeArgument = const DynamicType(); |
1135 if (typeArguments != null) { | 1135 if (typeArguments != null) { |
1136 typeArgument = typeArguments.first; | 1136 typeArgument = typeArguments.first; |
1137 if (typeArguments.length > 1) { | 1137 if (typeArguments.length > 1) { |
1138 typeArgument = const DynamicType(); | 1138 typeArgument = const DynamicType(); |
1139 warning( | 1139 warningNotError( |
1140 "Too many type arguments on List literal.", beginToken.charOffset); | 1140 "Too many type arguments on List literal.", beginToken.charOffset); |
1141 } | 1141 } |
1142 } | 1142 } |
1143 push(new ListLiteral(expressions, | 1143 push(new ListLiteral(expressions, |
1144 typeArgument: typeArgument, isConst: constKeyword != null) | 1144 typeArgument: typeArgument, isConst: constKeyword != null) |
1145 ..fileOffset = constKeyword?.charOffset ?? beginToken.charOffset); | 1145 ..fileOffset = constKeyword?.charOffset ?? beginToken.charOffset); |
1146 } | 1146 } |
1147 | 1147 |
1148 @override | 1148 @override |
1149 void handleLiteralBool(Token token) { | 1149 void handleLiteralBool(Token token) { |
(...skipping 21 matching lines...) Expand all Loading... |
1171 int count, Token beginToken, Token constKeyword, Token endToken) { | 1171 int count, Token beginToken, Token constKeyword, Token endToken) { |
1172 debugEvent("LiteralMap"); | 1172 debugEvent("LiteralMap"); |
1173 List<MapEntry> entries = popList(count) ?? <MapEntry>[]; | 1173 List<MapEntry> entries = popList(count) ?? <MapEntry>[]; |
1174 List<DartType> typeArguments = pop(); | 1174 List<DartType> typeArguments = pop(); |
1175 DartType keyType = const DynamicType(); | 1175 DartType keyType = const DynamicType(); |
1176 DartType valueType = const DynamicType(); | 1176 DartType valueType = const DynamicType(); |
1177 if (typeArguments != null) { | 1177 if (typeArguments != null) { |
1178 if (typeArguments.length != 2) { | 1178 if (typeArguments.length != 2) { |
1179 keyType = const DynamicType(); | 1179 keyType = const DynamicType(); |
1180 valueType = const DynamicType(); | 1180 valueType = const DynamicType(); |
1181 warning( | 1181 warningNotError( |
1182 "Map literal requires two type arguments.", beginToken.charOffset); | 1182 "Map literal requires two type arguments.", beginToken.charOffset); |
1183 } else { | 1183 } else { |
1184 keyType = typeArguments[0]; | 1184 keyType = typeArguments[0]; |
1185 valueType = typeArguments[1]; | 1185 valueType = typeArguments[1]; |
1186 } | 1186 } |
1187 } | 1187 } |
1188 push(new MapLiteral(entries, | 1188 push(new MapLiteral(entries, |
1189 keyType: keyType, valueType: valueType, isConst: constKeyword != null) | 1189 keyType: keyType, valueType: valueType, isConst: constKeyword != null) |
1190 ..fileOffset = constKeyword?.charOffset ?? beginToken.charOffset); | 1190 ..fileOffset = constKeyword?.charOffset ?? beginToken.charOffset); |
1191 } | 1191 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 Builder builder, List<DartType> arguments, int charOffset) { | 1239 Builder builder, List<DartType> arguments, int charOffset) { |
1240 if (constantExpressionRequired && builder is TypeVariableBuilder) { | 1240 if (constantExpressionRequired && builder is TypeVariableBuilder) { |
1241 addCompileTimeError(charOffset, "Not a constant expression."); | 1241 addCompileTimeError(charOffset, "Not a constant expression."); |
1242 } | 1242 } |
1243 if (builder is TypeDeclarationBuilder) { | 1243 if (builder is TypeDeclarationBuilder) { |
1244 return builder.buildTypesWithBuiltArguments(library, arguments); | 1244 return builder.buildTypesWithBuiltArguments(library, arguments); |
1245 } else if (builder.hasProblem) { | 1245 } else if (builder.hasProblem) { |
1246 ProblemBuilder problem = builder; | 1246 ProblemBuilder problem = builder; |
1247 addCompileTimeError(charOffset, problem.message); | 1247 addCompileTimeError(charOffset, problem.message); |
1248 } else { | 1248 } else { |
1249 warning("Not a type: '${builder.fullNameForErrors}'.", charOffset); | 1249 warningNotError( |
| 1250 "Not a type: '${builder.fullNameForErrors}'.", charOffset); |
1250 } | 1251 } |
1251 // TODO(ahe): Create an error somehow. | 1252 // TODO(ahe): Create an error somehow. |
1252 return const DynamicType(); | 1253 return const DynamicType(); |
1253 } | 1254 } |
1254 | 1255 |
1255 @override | 1256 @override |
1256 void handleType(Token beginToken, Token endToken) { | 1257 void handleType(Token beginToken, Token endToken) { |
1257 // TODO(ahe): The scope is wrong for return types of generic functions. | 1258 // TODO(ahe): The scope is wrong for return types of generic functions. |
1258 debugEvent("Type"); | 1259 debugEvent("Type"); |
1259 List<DartType> arguments = pop(); | 1260 List<DartType> arguments = pop(); |
(...skipping 23 matching lines...) Expand all Loading... |
1283 push(const DynamicType()); | 1284 push(const DynamicType()); |
1284 addCompileTimeError(beginToken.charOffset, | 1285 addCompileTimeError(beginToken.charOffset, |
1285 "Can't be used as a type: '${debugName(prefix, suffix)}'."); | 1286 "Can't be used as a type: '${debugName(prefix, suffix)}'."); |
1286 return; | 1287 return; |
1287 } | 1288 } |
1288 } | 1289 } |
1289 if (name is Identifier) { | 1290 if (name is Identifier) { |
1290 name = name.name; | 1291 name = name.name; |
1291 } | 1292 } |
1292 if (name is FastaAccessor) { | 1293 if (name is FastaAccessor) { |
1293 warning("'${beginToken.lexeme}' isn't a type.", beginToken.charOffset); | 1294 warningNotError( |
| 1295 "'${beginToken.lexeme}' isn't a type.", beginToken.charOffset); |
1294 push(const DynamicType()); | 1296 push(const DynamicType()); |
1295 } else if (name is TypeVariableBuilder) { | 1297 } else if (name is TypeVariableBuilder) { |
1296 if (constantExpressionRequired) { | 1298 if (constantExpressionRequired) { |
1297 addCompileTimeError( | 1299 addCompileTimeError( |
1298 beginToken.charOffset, "Not a constant expression."); | 1300 beginToken.charOffset, "Not a constant expression."); |
1299 } | 1301 } |
1300 push(name.buildTypesWithBuiltArguments(library, arguments)); | 1302 push(name.buildTypesWithBuiltArguments(library, arguments)); |
1301 } else if (name is TypeDeclarationBuilder) { | 1303 } else if (name is TypeDeclarationBuilder) { |
1302 push(name.buildTypesWithBuiltArguments(library, arguments)); | 1304 push(name.buildTypesWithBuiltArguments(library, arguments)); |
1303 } else if (name is TypeBuilder) { | 1305 } else if (name is TypeBuilder) { |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1745 } | 1747 } |
1746 | 1748 |
1747 @override | 1749 @override |
1748 void beginConstExpression(Token token) { | 1750 void beginConstExpression(Token token) { |
1749 debugEvent("beginConstExpression"); | 1751 debugEvent("beginConstExpression"); |
1750 super.push(constantExpressionRequired); | 1752 super.push(constantExpressionRequired); |
1751 constantExpressionRequired = true; | 1753 constantExpressionRequired = true; |
1752 } | 1754 } |
1753 | 1755 |
1754 @override | 1756 @override |
| 1757 void beginConstLiteral(Token token) { |
| 1758 debugEvent("beginConstLiteral"); |
| 1759 super.push(constantExpressionRequired); |
| 1760 constantExpressionRequired = true; |
| 1761 } |
| 1762 |
| 1763 @override |
| 1764 void endConstLiteral(Token token) { |
| 1765 debugEvent("endConstLiteral"); |
| 1766 var literal = pop(); |
| 1767 constantExpressionRequired = pop(); |
| 1768 push(literal); |
| 1769 } |
| 1770 |
| 1771 @override |
1755 void endNewExpression(Token token) { | 1772 void endNewExpression(Token token) { |
1756 debugEvent("NewExpression"); | 1773 debugEvent("NewExpression"); |
1757 Token nameToken = token.next; | 1774 Token nameToken = token.next; |
1758 Arguments arguments = pop(); | 1775 Arguments arguments = pop(); |
1759 String name = pop(); | 1776 String name = pop(); |
1760 List<DartType> typeArguments = pop(); | 1777 List<DartType> typeArguments = pop(); |
1761 var type = pop(); | 1778 var type = pop(); |
1762 bool savedConstantExpressionRequired = pop(); | 1779 bool savedConstantExpressionRequired = pop(); |
1763 () { | 1780 () { |
1764 if (arguments == null) { | 1781 if (arguments == null) { |
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2416 | 2433 |
2417 @override | 2434 @override |
2418 void warning(String message, [int charOffset = -1]) { | 2435 void warning(String message, [int charOffset = -1]) { |
2419 if (constantExpressionRequired) { | 2436 if (constantExpressionRequired) { |
2420 addCompileTimeError(charOffset, message); | 2437 addCompileTimeError(charOffset, message); |
2421 } else { | 2438 } else { |
2422 super.warning(message, charOffset); | 2439 super.warning(message, charOffset); |
2423 } | 2440 } |
2424 } | 2441 } |
2425 | 2442 |
| 2443 void warningNotError(String message, [int charOffset = -1]) { |
| 2444 super.warning(message, charOffset); |
| 2445 } |
| 2446 |
2426 Expression evaluateArgumentsBefore( | 2447 Expression evaluateArgumentsBefore( |
2427 Arguments arguments, Expression expression) { | 2448 Arguments arguments, Expression expression) { |
2428 if (arguments == null) return expression; | 2449 if (arguments == null) return expression; |
2429 List<Expression> expressions = | 2450 List<Expression> expressions = |
2430 new List<Expression>.from(arguments.positional); | 2451 new List<Expression>.from(arguments.positional); |
2431 for (NamedExpression named in arguments.named) { | 2452 for (NamedExpression named in arguments.named) { |
2432 expressions.add(named.value); | 2453 expressions.add(named.value); |
2433 } | 2454 } |
2434 for (Expression argument in expressions.reversed) { | 2455 for (Expression argument in expressions.reversed) { |
2435 expression = new Let( | 2456 expression = new Let( |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2904 } else if (node is PrefixBuilder) { | 2925 } else if (node is PrefixBuilder) { |
2905 return node.name; | 2926 return node.name; |
2906 } else if (node is ThisAccessor) { | 2927 } else if (node is ThisAccessor) { |
2907 return node.isSuper ? "super" : "this"; | 2928 return node.isSuper ? "super" : "this"; |
2908 } else if (node is FastaAccessor) { | 2929 } else if (node is FastaAccessor) { |
2909 return node.plainNameForRead; | 2930 return node.plainNameForRead; |
2910 } else { | 2931 } else { |
2911 return internalError("Unhandled: ${node.runtimeType}"); | 2932 return internalError("Unhandled: ${node.runtimeType}"); |
2912 } | 2933 } |
2913 } | 2934 } |
OLD | NEW |