Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

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

Issue 2765283002: Various errors on constant expressions. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
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 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 node.name.name, new Arguments.empty(), node.fileOffset, 175 node.name.name, new Arguments.empty(), node.fileOffset,
176 isGetter: true); 176 isGetter: true);
177 } else if (node is BuilderAccessor) { 177 } else if (node is BuilderAccessor) {
178 return node.buildSimpleRead(); 178 return node.buildSimpleRead();
179 } else if (node is TypeVariableBuilder) { 179 } else if (node is TypeVariableBuilder) {
180 TypeParameterType type = node.buildTypesWithBuiltArguments(library, null); 180 TypeParameterType type = node.buildTypesWithBuiltArguments(library, null);
181 if (!isInstanceContext && type.parameter.parent is Class) { 181 if (!isInstanceContext && type.parameter.parent is Class) {
182 return buildCompileTimeError( 182 return buildCompileTimeError(
183 "Type variables can only be used in instance methods."); 183 "Type variables can only be used in instance methods.");
184 } else { 184 } else {
185 if (constantExpressionRequired) {
186 addCompileTimeError(-1,
187 "Type variable can't be used as a constant expression $type.");
Paul Berry 2017/03/22 16:18:04 I have two concerns about how this technique for d
ahe 2017/03/22 16:58:02 I'm aware of that, and I've started work on error
188 }
185 return new TypeLiteral(type); 189 return new TypeLiteral(type);
186 } 190 }
187 } else if (node is TypeDeclarationBuilder) { 191 } else if (node is TypeDeclarationBuilder) {
188 return new TypeLiteral(node.buildTypesWithBuiltArguments(library, null)); 192 return new TypeLiteral(node.buildTypesWithBuiltArguments(library, null));
189 } else if (node is KernelTypeBuilder) { 193 } else if (node is KernelTypeBuilder) {
190 return new TypeLiteral(node.build(library)); 194 return new TypeLiteral(node.build(library));
191 } else if (node is Expression) { 195 } else if (node is Expression) {
192 return node; 196 return node;
193 } else if (node is PrefixBuilder) { 197 } else if (node is PrefixBuilder) {
194 return buildCompileTimeError("A library can't be used as an expression."); 198 return buildCompileTimeError("A library can't be used as an expression.");
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 } else if (arguments == null) { 531 } else if (arguments == null) {
528 push(receiver); 532 push(receiver);
529 } else { 533 } else {
530 push(finishSend(receiver, arguments, beginToken.charOffset)); 534 push(finishSend(receiver, arguments, beginToken.charOffset));
531 } 535 }
532 } 536 }
533 537
534 @override 538 @override
535 finishSend(Object receiver, Arguments arguments, int charOffset) { 539 finishSend(Object receiver, Arguments arguments, int charOffset) {
536 if (receiver is BuilderAccessor) { 540 if (receiver is BuilderAccessor) {
541 if (constantExpressionRequired) {
542 addCompileTimeError(charOffset, "Not a constant expression.");
Paul Berry 2017/03/22 16:18:04 Idea: when we report a "Not a constant expression"
ahe 2017/03/22 16:58:02 That's probably a good idea.
ahe 2017/03/23 12:22:13 I'm going to follow up on this in separate CL.
543 }
537 return receiver.doInvocation(charOffset, arguments); 544 return receiver.doInvocation(charOffset, arguments);
538 } else if (receiver is UnresolvedIdentifier) { 545 } else if (receiver is UnresolvedIdentifier) {
539 return throwNoSuchMethodError( 546 return throwNoSuchMethodError(
540 receiver.name.name, arguments, receiver.fileOffset); 547 receiver.name.name, arguments, receiver.fileOffset);
541 } else { 548 } else {
542 return buildMethodInvocation( 549 return buildMethodInvocation(
543 toValue(receiver), callName, arguments, charOffset); 550 toValue(receiver), callName, arguments, charOffset);
544 } 551 }
545 } 552 }
546 553
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 String name = token.lexeme; 741 String name = token.lexeme;
735 if (context.isScopeReference) { 742 if (context.isScopeReference) {
736 assert(!inInitializer || 743 assert(!inInitializer ||
737 this.scope == enclosingScope || 744 this.scope == enclosingScope ||
738 this.scope.parent == enclosingScope); 745 this.scope.parent == enclosingScope);
739 // This deals with this kind of initializer: `C(a) : a = a;` 746 // This deals with this kind of initializer: `C(a) : a = a;`
740 Scope scope = inInitializer ? enclosingScope : this.scope; 747 Scope scope = inInitializer ? enclosingScope : this.scope;
741 Builder builder = scope.lookup(name, token.charOffset, uri); 748 Builder builder = scope.lookup(name, token.charOffset, uri);
742 push(builderToFirstExpression(builder, name, token.charOffset)); 749 push(builderToFirstExpression(builder, name, token.charOffset));
743 } else { 750 } else {
751 if (constantExpressionRequired) {
752 if (context != IdentifierContext.namedArgumentReference &&
Paul Berry 2017/03/22 16:18:05 Rather than a bunch of != checks, we should add a
ahe 2017/03/22 16:58:02 Good idea.
ahe 2017/03/23 12:22:13 I'll do this in a separate CL.
753 context != IdentifierContext.constructorReferenceContinuation &&
754 context != IdentifierContext.expressionContinuation &&
755 context != IdentifierContext.typeReferenceContinuation &&
756 context !=
757 IdentifierContext
758 .constructorReferenceContinuationAfterTypeArguments) {
759 addCompileTimeError(
760 token.charOffset, "Not a constant expression: $context");
761 }
762 }
744 push(new Identifier(name)..fileOffset = token.charOffset); 763 push(new Identifier(name)..fileOffset = token.charOffset);
745 } 764 }
746 } 765 }
747 766
748 @override 767 @override
749 builderToFirstExpression(Builder builder, String name, int charOffset, 768 builderToFirstExpression(Builder builder, String name, int charOffset,
750 {bool isPrefix: false}) { 769 {bool isPrefix: false}) {
751 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { 770 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) {
752 Name n = new Name(name, library.library); 771 Name n = new Name(name, library.library);
753 if (!isPrefix && isInstanceContext) { 772 if (!isPrefix && isInstanceContext) {
754 assert(builder == null); 773 assert(builder == null);
774 if (constantExpressionRequired) {
775 addCompileTimeError(charOffset, "Not a constant expression.");
776 }
755 return new ThisPropertyAccessor(this, charOffset, n, null, null); 777 return new ThisPropertyAccessor(this, charOffset, n, null, null);
756 } else { 778 } else {
779 if (constantExpressionRequired) {
780 addCompileTimeError(charOffset, "Not a constant expression.");
781 }
757 return new UnresolvedIdentifier(n)..fileOffset = charOffset; 782 return new UnresolvedIdentifier(n)..fileOffset = charOffset;
758 } 783 }
759 } else if (builder.isTypeDeclaration) { 784 } else if (builder.isTypeDeclaration) {
785 if (constantExpressionRequired && builder.isTypeVariable) {
786 addCompileTimeError(charOffset, "Not a constant expression.");
787 }
760 return builder; 788 return builder;
761 } else if (builder.isLocal) { 789 } else if (builder.isLocal) {
790 if (constantExpressionRequired && !builder.isConst) {
791 addCompileTimeError(charOffset, "Not a constant expression.");
792 }
762 return new VariableAccessor(this, charOffset, builder.target); 793 return new VariableAccessor(this, charOffset, builder.target);
763 } else if (builder.isInstanceMember) { 794 } else if (builder.isInstanceMember) {
795 if (constantExpressionRequired) {
796 addCompileTimeError(charOffset, "Not a constant expression.");
797 }
764 return new ThisPropertyAccessor( 798 return new ThisPropertyAccessor(
765 this, charOffset, new Name(name, library.library), null, null); 799 this, charOffset, new Name(name, library.library), null, null);
766 } else if (builder.isRegularMethod) { 800 } else if (builder.isRegularMethod) {
767 assert(builder.isStatic || builder.isTopLevel); 801 assert(builder.isStatic || builder.isTopLevel);
768 return new StaticAccessor(this, charOffset, builder.target, null); 802 return new StaticAccessor(this, charOffset, builder.target, null);
769 } else if (builder is PrefixBuilder) { 803 } else if (builder is PrefixBuilder) {
770 return builder; 804 return builder;
771 } else if (builder is MixedAccessor) { 805 } else if (builder is MixedAccessor) {
806 if (constantExpressionRequired && !builder.getter.target.isConst) {
807 addCompileTimeError(charOffset, "Not a constant expression.");
808 }
772 return new StaticAccessor( 809 return new StaticAccessor(
773 this, charOffset, builder.getter.target, builder.setter.target); 810 this, charOffset, builder.getter.target, builder.setter.target);
774 } else { 811 } else {
775 if (builder.hasProblem && builder is! AccessErrorBuilder) return builder; 812 if (builder.hasProblem && builder is! AccessErrorBuilder) return builder;
776 Builder setter; 813 Builder setter;
777 if (builder.isSetter) { 814 if (builder.isSetter) {
778 setter = builder; 815 setter = builder;
779 } else if (builder.isGetter) { 816 } else if (builder.isGetter) {
780 setter = scope.lookupSetter(name, charOffset, uri); 817 setter = scope.lookupSetter(name, charOffset, uri);
781 } else if (builder.isField && !builder.isFinal) { 818 } else if (builder.isField && !builder.isFinal) {
782 setter = builder; 819 setter = builder;
783 } 820 }
784 return new StaticAccessor.fromBuilder(this, builder, charOffset, setter); 821 StaticAccessor accessor =
822 new StaticAccessor.fromBuilder(this, builder, charOffset, setter);
823 if (constantExpressionRequired) {
824 Member readTarget = accessor.readTarget;
825 if (!(readTarget is Field && readTarget.isConst)) {
826 addCompileTimeError(charOffset, "Not a constant expression.");
827 }
828 }
829 return accessor;
785 } 830 }
786 } 831 }
787 832
788 @override 833 @override
789 void handleQualified(Token period) { 834 void handleQualified(Token period) {
790 debugEvent("Qualified"); 835 debugEvent("Qualified");
791 Identifier name = pop(); 836 Identifier name = pop();
792 var receiver = pop(); 837 var receiver = pop();
793 push([receiver, name]); 838 push([receiver, name]);
794 } 839 }
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 if (builder == null) { 1239 if (builder == null) {
1195 warning("Type not found: '$name'.", charOffset); 1240 warning("Type not found: '$name'.", charOffset);
1196 return const DynamicType(); 1241 return const DynamicType();
1197 } else { 1242 } else {
1198 return kernelTypeFromBuilder(builder, arguments, charOffset); 1243 return kernelTypeFromBuilder(builder, arguments, charOffset);
1199 } 1244 }
1200 } 1245 }
1201 1246
1202 DartType kernelTypeFromBuilder( 1247 DartType kernelTypeFromBuilder(
1203 Builder builder, List<DartType> arguments, int charOffset) { 1248 Builder builder, List<DartType> arguments, int charOffset) {
1249 if (constantExpressionRequired && builder is TypeVariableBuilder) {
1250 addCompileTimeError(charOffset, "Not a constant expression.");
1251 }
1204 if (builder is TypeDeclarationBuilder) { 1252 if (builder is TypeDeclarationBuilder) {
1205 return builder.buildTypesWithBuiltArguments(library, arguments); 1253 return builder.buildTypesWithBuiltArguments(library, arguments);
1206 } else if (builder.hasProblem) { 1254 } else if (builder.hasProblem) {
1207 ProblemBuilder problem = builder; 1255 ProblemBuilder problem = builder;
1208 addCompileTimeError(charOffset, problem.message); 1256 addCompileTimeError(charOffset, problem.message);
1209 } else { 1257 } else {
1210 warning("Not a type: '${builder.fullNameForErrors}'.", charOffset); 1258 warning("Not a type: '${builder.fullNameForErrors}'.", charOffset);
1211 } 1259 }
1212 // TODO(ahe): Create an error somehow. 1260 // TODO(ahe): Create an error somehow.
1213 return const DynamicType(); 1261 return const DynamicType();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1251 if (name is Identifier) { 1299 if (name is Identifier) {
1252 name = name.name; 1300 name = name.name;
1253 } 1301 }
1254 if (name is BuilderAccessor) { 1302 if (name is BuilderAccessor) {
1255 warning("'${beginToken.lexeme}' isn't a type.", beginToken.charOffset); 1303 warning("'${beginToken.lexeme}' isn't a type.", beginToken.charOffset);
1256 push(const DynamicType()); 1304 push(const DynamicType());
1257 } else if (name is UnresolvedIdentifier) { 1305 } else if (name is UnresolvedIdentifier) {
1258 warning("'${name.name}' isn't a type.", beginToken.charOffset); 1306 warning("'${name.name}' isn't a type.", beginToken.charOffset);
1259 push(const DynamicType()); 1307 push(const DynamicType());
1260 } else if (name is TypeVariableBuilder) { 1308 } else if (name is TypeVariableBuilder) {
1309 if (constantExpressionRequired) {
1310 addCompileTimeError(
1311 beginToken.charOffset, "Not a constant expression.");
1312 }
1261 push(name.buildTypesWithBuiltArguments(library, arguments)); 1313 push(name.buildTypesWithBuiltArguments(library, arguments));
1262 } else if (name is TypeDeclarationBuilder) { 1314 } else if (name is TypeDeclarationBuilder) {
1263 push(name.buildTypesWithBuiltArguments(library, arguments)); 1315 push(name.buildTypesWithBuiltArguments(library, arguments));
1264 } else if (name is TypeBuilder) { 1316 } else if (name is TypeBuilder) {
1265 push(name.build(library)); 1317 push(name.build(library));
1266 } else if (name is Builder) { 1318 } else if (name is Builder) {
1267 push(kernelTypeFromBuilder(name, arguments, beginToken.charOffset)); 1319 push(kernelTypeFromBuilder(name, arguments, beginToken.charOffset));
1268 } else if (name is String) { 1320 } else if (name is String) {
1269 push(kernelTypeFromString(name, arguments, beginToken.charOffset)); 1321 push(kernelTypeFromString(name, arguments, beginToken.charOffset));
1270 } else { 1322 } else {
(...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after
2340 @override 2392 @override
2341 void handleInvalidFunctionBody(Token token) { 2393 void handleInvalidFunctionBody(Token token) {
2342 if (member.isNative) { 2394 if (member.isNative) {
2343 push(NullValue.FunctionBody); 2395 push(NullValue.FunctionBody);
2344 } else { 2396 } else {
2345 push(new Block(<Statement>[new InvalidStatement()])); 2397 push(new Block(<Statement>[new InvalidStatement()]));
2346 } 2398 }
2347 } 2399 }
2348 2400
2349 @override 2401 @override
2402 void warning(String message, [int charOffset = -1]) {
2403 if (constantExpressionRequired) {
2404 addCompileTimeError(charOffset, message);
Paul Berry 2017/03/22 16:18:04 This seems really scary to me. Are we sure that a
ahe 2017/03/22 16:58:02 There are a few warnings that don't follow this ru
2405 } else {
2406 super.warning(message, charOffset);
2407 }
2408 }
2409
2410 @override
2350 void debugEvent(String name) { 2411 void debugEvent(String name) {
2351 // printEvent(name); 2412 // printEvent(name);
2352 } 2413 }
2353 } 2414 }
2354 2415
2355 // TODO(ahe): Shouldn't need to be an expression. 2416 // TODO(ahe): Shouldn't need to be an expression.
2356 class UnresolvedIdentifier extends InvalidExpression { 2417 class UnresolvedIdentifier extends InvalidExpression {
2357 final Name name; 2418 final Name name;
2358 2419
2359 UnresolvedIdentifier(this.name); 2420 UnresolvedIdentifier(this.name);
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
2798 } else if (node is PrefixBuilder) { 2859 } else if (node is PrefixBuilder) {
2799 return node.name; 2860 return node.name;
2800 } else if (node is ThisAccessor) { 2861 } else if (node is ThisAccessor) {
2801 return node.isSuper ? "super" : "this"; 2862 return node.isSuper ? "super" : "this";
2802 } else if (node is BuilderAccessor) { 2863 } else if (node is BuilderAccessor) {
2803 return node.plainNameForRead; 2864 return node.plainNameForRead;
2804 } else { 2865 } else {
2805 return internalError("Unhandled: ${node.runtimeType}"); 2866 return internalError("Unhandled: ${node.runtimeType}");
2806 } 2867 }
2807 } 2868 }
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
This is Rietveld 408576698