Chromium Code Reviews

Side by Side Diff: pkg/front_end/lib/src/fasta/kernel/body_builder.dart

Issue 2765283002: Various errors on constant expressions. (Closed)
Patch Set: Update status files. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
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 170 matching lines...)
181 node.name.name, new Arguments.empty(), node.fileOffset, 181 node.name.name, new Arguments.empty(), node.fileOffset,
182 isGetter: true); 182 isGetter: true);
183 } else if (node is BuilderAccessor) { 183 } else if (node is BuilderAccessor) {
184 return node.buildSimpleRead(); 184 return node.buildSimpleRead();
185 } else if (node is TypeVariableBuilder) { 185 } else if (node is TypeVariableBuilder) {
186 TypeParameterType type = node.buildTypesWithBuiltArguments(library, null); 186 TypeParameterType type = node.buildTypesWithBuiltArguments(library, null);
187 if (!isInstanceContext && type.parameter.parent is Class) { 187 if (!isInstanceContext && type.parameter.parent is Class) {
188 return buildCompileTimeError( 188 return buildCompileTimeError(
189 "Type variables can only be used in instance methods."); 189 "Type variables can only be used in instance methods.");
190 } else { 190 } else {
191 if (constantExpressionRequired) {
192 addCompileTimeError(-1,
193 "Type variable can't be used as a constant expression $type.");
194 }
191 return new TypeLiteral(type); 195 return new TypeLiteral(type);
192 } 196 }
193 } else if (node is TypeDeclarationBuilder) { 197 } else if (node is TypeDeclarationBuilder) {
194 return new TypeLiteral(node.buildTypesWithBuiltArguments(library, null)); 198 return new TypeLiteral(node.buildTypesWithBuiltArguments(library, null));
195 } else if (node is KernelTypeBuilder) { 199 } else if (node is KernelTypeBuilder) {
196 return new TypeLiteral(node.build(library)); 200 return new TypeLiteral(node.build(library));
197 } else if (node is Expression) { 201 } else if (node is Expression) {
198 return node; 202 return node;
199 } else if (node is PrefixBuilder) { 203 } else if (node is PrefixBuilder) {
200 return buildCompileTimeError("A library can't be used as an expression."); 204 return buildCompileTimeError("A library can't be used as an expression.");
(...skipping 332 matching lines...)
533 } else if (arguments == null) { 537 } else if (arguments == null) {
534 push(receiver); 538 push(receiver);
535 } else { 539 } else {
536 push(finishSend(receiver, arguments, beginToken.charOffset)); 540 push(finishSend(receiver, arguments, beginToken.charOffset));
537 } 541 }
538 } 542 }
539 543
540 @override 544 @override
541 finishSend(Object receiver, Arguments arguments, int charOffset) { 545 finishSend(Object receiver, Arguments arguments, int charOffset) {
542 if (receiver is BuilderAccessor) { 546 if (receiver is BuilderAccessor) {
547 if (constantExpressionRequired) {
548 addCompileTimeError(charOffset, "Not a constant expression.");
549 }
543 return receiver.doInvocation(charOffset, arguments); 550 return receiver.doInvocation(charOffset, arguments);
544 } else if (receiver is UnresolvedIdentifier) { 551 } else if (receiver is UnresolvedIdentifier) {
545 return throwNoSuchMethodError( 552 return throwNoSuchMethodError(
546 receiver.name.name, arguments, receiver.fileOffset); 553 receiver.name.name, arguments, receiver.fileOffset);
547 } else { 554 } else {
548 return buildMethodInvocation( 555 return buildMethodInvocation(
549 toValue(receiver), callName, arguments, charOffset); 556 toValue(receiver), callName, arguments, charOffset);
550 } 557 }
551 } 558 }
552 559
(...skipping 187 matching lines...)
740 String name = token.lexeme; 747 String name = token.lexeme;
741 if (context.isScopeReference) { 748 if (context.isScopeReference) {
742 assert(!inInitializer || 749 assert(!inInitializer ||
743 this.scope == enclosingScope || 750 this.scope == enclosingScope ||
744 this.scope.parent == enclosingScope); 751 this.scope.parent == enclosingScope);
745 // This deals with this kind of initializer: `C(a) : a = a;` 752 // This deals with this kind of initializer: `C(a) : a = a;`
746 Scope scope = inInitializer ? enclosingScope : this.scope; 753 Scope scope = inInitializer ? enclosingScope : this.scope;
747 Builder builder = scope.lookup(name, token.charOffset, uri); 754 Builder builder = scope.lookup(name, token.charOffset, uri);
748 push(builderToFirstExpression(builder, name, token.charOffset)); 755 push(builderToFirstExpression(builder, name, token.charOffset));
749 } else { 756 } else {
757 if (constantExpressionRequired) {
758 if (context != IdentifierContext.namedArgumentReference &&
759 context != IdentifierContext.constructorReferenceContinuation &&
760 context != IdentifierContext.expressionContinuation &&
761 context != IdentifierContext.typeReferenceContinuation &&
762 context != IdentifierContext.localVariableDeclaration &&
763 context !=
764 IdentifierContext
765 .constructorReferenceContinuationAfterTypeArguments) {
766 addCompileTimeError(
767 token.charOffset, "Not a constant expression: $context");
768 }
769 }
750 push(new Identifier(name)..fileOffset = token.charOffset); 770 push(new Identifier(name)..fileOffset = token.charOffset);
751 } 771 }
752 } 772 }
753 773
754 @override 774 @override
755 builderToFirstExpression(Builder builder, String name, int charOffset, 775 builderToFirstExpression(Builder builder, String name, int charOffset,
756 {bool isPrefix: false}) { 776 {bool isPrefix: false}) {
757 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { 777 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) {
758 Name n = new Name(name, library.library); 778 Name n = new Name(name, library.library);
759 if (!isPrefix && isInstanceContext) { 779 if (!isPrefix && isInstanceContext) {
760 assert(builder == null); 780 assert(builder == null);
781 if (constantExpressionRequired) {
782 addCompileTimeError(charOffset, "Not a constant expression.");
783 }
761 return new ThisPropertyAccessor(this, charOffset, n, null, null); 784 return new ThisPropertyAccessor(this, charOffset, n, null, null);
762 } else { 785 } else {
786 if (constantExpressionRequired) {
787 addCompileTimeError(charOffset, "Not a constant expression.");
788 }
763 return new UnresolvedIdentifier(n)..fileOffset = charOffset; 789 return new UnresolvedIdentifier(n)..fileOffset = charOffset;
764 } 790 }
765 } else if (builder.isTypeDeclaration) { 791 } else if (builder.isTypeDeclaration) {
792 if (constantExpressionRequired && builder.isTypeVariable) {
793 addCompileTimeError(charOffset, "Not a constant expression.");
794 }
766 return builder; 795 return builder;
767 } else if (builder.isLocal) { 796 } else if (builder.isLocal) {
797 if (constantExpressionRequired && !builder.isConst) {
798 addCompileTimeError(charOffset, "Not a constant expression.");
799 }
768 return new VariableAccessor(this, charOffset, builder.target); 800 return new VariableAccessor(this, charOffset, builder.target);
769 } else if (builder.isInstanceMember) { 801 } else if (builder.isInstanceMember) {
802 if (constantExpressionRequired) {
803 addCompileTimeError(charOffset, "Not a constant expression.");
804 }
770 return new ThisPropertyAccessor( 805 return new ThisPropertyAccessor(
771 this, charOffset, new Name(name, library.library), null, null); 806 this, charOffset, new Name(name, library.library), null, null);
772 } else if (builder.isRegularMethod) { 807 } else if (builder.isRegularMethod) {
773 assert(builder.isStatic || builder.isTopLevel); 808 assert(builder.isStatic || builder.isTopLevel);
774 return new StaticAccessor(this, charOffset, builder.target, null); 809 return new StaticAccessor(this, charOffset, builder.target, null);
775 } else if (builder is PrefixBuilder) { 810 } else if (builder is PrefixBuilder) {
776 return builder; 811 return builder;
777 } else if (builder is MixedAccessor) { 812 } else if (builder is MixedAccessor) {
813 if (constantExpressionRequired && !builder.getter.target.isConst) {
814 addCompileTimeError(charOffset, "Not a constant expression.");
815 }
778 return new StaticAccessor( 816 return new StaticAccessor(
779 this, charOffset, builder.getter.target, builder.setter.target); 817 this, charOffset, builder.getter.target, builder.setter.target);
780 } else { 818 } else {
781 if (builder.hasProblem && builder is! AccessErrorBuilder) return builder; 819 if (builder.hasProblem && builder is! AccessErrorBuilder) return builder;
782 Builder setter; 820 Builder setter;
783 if (builder.isSetter) { 821 if (builder.isSetter) {
784 setter = builder; 822 setter = builder;
785 } else if (builder.isGetter) { 823 } else if (builder.isGetter) {
786 setter = scope.lookupSetter(name, charOffset, uri); 824 setter = scope.lookupSetter(name, charOffset, uri);
787 } else if (builder.isField && !builder.isFinal) { 825 } else if (builder.isField && !builder.isFinal) {
788 setter = builder; 826 setter = builder;
789 } 827 }
790 return new StaticAccessor.fromBuilder(this, builder, charOffset, setter); 828 StaticAccessor accessor =
829 new StaticAccessor.fromBuilder(this, builder, charOffset, setter);
830 if (constantExpressionRequired) {
831 Member readTarget = accessor.readTarget;
832 if (!(readTarget is Field && readTarget.isConst)) {
833 addCompileTimeError(charOffset, "Not a constant expression.");
834 }
835 }
836 return accessor;
791 } 837 }
792 } 838 }
793 839
794 @override 840 @override
795 void handleQualified(Token period) { 841 void handleQualified(Token period) {
796 debugEvent("Qualified"); 842 debugEvent("Qualified");
797 Identifier name = pop(); 843 Identifier name = pop();
798 var receiver = pop(); 844 var receiver = pop();
799 push([receiver, name]); 845 push([receiver, name]);
800 } 846 }
(...skipping 407 matching lines...)
1208 if (builder == null) { 1254 if (builder == null) {
1209 warning("Type not found: '$name'.", charOffset); 1255 warning("Type not found: '$name'.", charOffset);
1210 return const DynamicType(); 1256 return const DynamicType();
1211 } else { 1257 } else {
1212 return kernelTypeFromBuilder(builder, arguments, charOffset); 1258 return kernelTypeFromBuilder(builder, arguments, charOffset);
1213 } 1259 }
1214 } 1260 }
1215 1261
1216 DartType kernelTypeFromBuilder( 1262 DartType kernelTypeFromBuilder(
1217 Builder builder, List<DartType> arguments, int charOffset) { 1263 Builder builder, List<DartType> arguments, int charOffset) {
1264 if (constantExpressionRequired && builder is TypeVariableBuilder) {
1265 addCompileTimeError(charOffset, "Not a constant expression.");
1266 }
1218 if (builder is TypeDeclarationBuilder) { 1267 if (builder is TypeDeclarationBuilder) {
1219 return builder.buildTypesWithBuiltArguments(library, arguments); 1268 return builder.buildTypesWithBuiltArguments(library, arguments);
1220 } else if (builder.hasProblem) { 1269 } else if (builder.hasProblem) {
1221 ProblemBuilder problem = builder; 1270 ProblemBuilder problem = builder;
1222 addCompileTimeError(charOffset, problem.message); 1271 addCompileTimeError(charOffset, problem.message);
1223 } else { 1272 } else {
1224 warning("Not a type: '${builder.fullNameForErrors}'.", charOffset); 1273 warning("Not a type: '${builder.fullNameForErrors}'.", charOffset);
1225 } 1274 }
1226 // TODO(ahe): Create an error somehow. 1275 // TODO(ahe): Create an error somehow.
1227 return const DynamicType(); 1276 return const DynamicType();
(...skipping 37 matching lines...)
1265 if (name is Identifier) { 1314 if (name is Identifier) {
1266 name = name.name; 1315 name = name.name;
1267 } 1316 }
1268 if (name is BuilderAccessor) { 1317 if (name is BuilderAccessor) {
1269 warning("'${beginToken.lexeme}' isn't a type.", beginToken.charOffset); 1318 warning("'${beginToken.lexeme}' isn't a type.", beginToken.charOffset);
1270 push(const DynamicType()); 1319 push(const DynamicType());
1271 } else if (name is UnresolvedIdentifier) { 1320 } else if (name is UnresolvedIdentifier) {
1272 warning("'${name.name}' isn't a type.", beginToken.charOffset); 1321 warning("'${name.name}' isn't a type.", beginToken.charOffset);
1273 push(const DynamicType()); 1322 push(const DynamicType());
1274 } else if (name is TypeVariableBuilder) { 1323 } else if (name is TypeVariableBuilder) {
1324 if (constantExpressionRequired) {
1325 addCompileTimeError(
1326 beginToken.charOffset, "Not a constant expression.");
1327 }
1275 push(name.buildTypesWithBuiltArguments(library, arguments)); 1328 push(name.buildTypesWithBuiltArguments(library, arguments));
1276 } else if (name is TypeDeclarationBuilder) { 1329 } else if (name is TypeDeclarationBuilder) {
1277 push(name.buildTypesWithBuiltArguments(library, arguments)); 1330 push(name.buildTypesWithBuiltArguments(library, arguments));
1278 } else if (name is TypeBuilder) { 1331 } else if (name is TypeBuilder) {
1279 push(name.build(library)); 1332 push(name.build(library));
1280 } else if (name is Builder) { 1333 } else if (name is Builder) {
1281 push(kernelTypeFromBuilder(name, arguments, beginToken.charOffset)); 1334 push(kernelTypeFromBuilder(name, arguments, beginToken.charOffset));
1282 } else if (name is String) { 1335 } else if (name is String) {
1283 push(kernelTypeFromString(name, arguments, beginToken.charOffset)); 1336 push(kernelTypeFromString(name, arguments, beginToken.charOffset));
1284 } else { 1337 } else {
(...skipping 1056 matching lines...)
2341 push(new Operator(token.stringValue)..fileOffset = token.charOffset); 2394 push(new Operator(token.stringValue)..fileOffset = token.charOffset);
2342 } 2395 }
2343 2396
2344 @override 2397 @override
2345 void handleSymbolVoid(Token token) { 2398 void handleSymbolVoid(Token token) {
2346 logEvent("SymbolVoid"); 2399 logEvent("SymbolVoid");
2347 } 2400 }
2348 2401
2349 dynamic addCompileTimeError(int charOffset, String message, 2402 dynamic addCompileTimeError(int charOffset, String message,
2350 {bool silent: false}) { 2403 {bool silent: false}) {
2404 // TODO(ahe): If constantExpressionRequired is set, set it to false to
2405 // avoid a long list of errors.
2351 return library.addCompileTimeError(charOffset, message, fileUri: uri); 2406 return library.addCompileTimeError(charOffset, message, fileUri: uri);
2352 } 2407 }
2353 2408
2354 @override 2409 @override
2355 void handleInvalidFunctionBody(Token token) { 2410 void handleInvalidFunctionBody(Token token) {
2356 if (member.isNative) { 2411 if (member.isNative) {
2357 push(NullValue.FunctionBody); 2412 push(NullValue.FunctionBody);
2358 } else { 2413 } else {
2359 push(new Block(<Statement>[new InvalidStatement()])); 2414 push(new Block(<Statement>[new InvalidStatement()]));
2360 } 2415 }
2361 } 2416 }
2362 2417
2363 @override 2418 @override
2419 void warning(String message, [int charOffset = -1]) {
2420 if (constantExpressionRequired) {
2421 addCompileTimeError(charOffset, message);
2422 } else {
2423 super.warning(message, charOffset);
2424 }
2425 }
2426
2427 @override
2364 void debugEvent(String name) { 2428 void debugEvent(String name) {
2365 // printEvent(name); 2429 // printEvent(name);
2366 } 2430 }
2367 } 2431 }
2368 2432
2369 // TODO(ahe): Shouldn't need to be an expression. 2433 // TODO(ahe): Shouldn't need to be an expression.
2370 class UnresolvedIdentifier extends InvalidExpression { 2434 class UnresolvedIdentifier extends InvalidExpression {
2371 final Name name; 2435 final Name name;
2372 2436
2373 UnresolvedIdentifier(this.name); 2437 UnresolvedIdentifier(this.name);
(...skipping 438 matching lines...)
2812 } else if (node is PrefixBuilder) { 2876 } else if (node is PrefixBuilder) {
2813 return node.name; 2877 return node.name;
2814 } else if (node is ThisAccessor) { 2878 } else if (node is ThisAccessor) {
2815 return node.isSuper ? "super" : "this"; 2879 return node.isSuper ? "super" : "this";
2816 } else if (node is BuilderAccessor) { 2880 } else if (node is BuilderAccessor) {
2817 return node.plainNameForRead; 2881 return node.plainNameForRead;
2818 } else { 2882 } else {
2819 return internalError("Unhandled: ${node.runtimeType}"); 2883 return internalError("Unhandled: ${node.runtimeType}");
2820 } 2884 }
2821 } 2885 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/builder/type_declaration_builder.dart ('k') | tests/co19/co19-kernel.status » ('j') | no next file with comments »

Powered by Google App Engine