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

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

Issue 2906253004: Avoid using Invalid{Statement,Expression,Initializer}. (Closed)
Patch Set: Created 3 years, 6 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 '../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, MemberKind, optional; 10 import '../parser/parser.dart' show FormalParameterType, MemberKind, optional;
11 11
12 import '../parser/identifier_context.dart' show IdentifierContext; 12 import '../parser/identifier_context.dart' show IdentifierContext;
13 13
14 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; 14 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart';
15 15
16 import 'package:front_end/src/fasta/kernel/utils.dart' show offsetForToken; 16 import 'package:front_end/src/fasta/kernel/utils.dart' show offsetForToken;
17 17
18 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart' 18 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart'
19 show FieldNode; 19 show FieldNode;
20 20
21 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart' 21 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart'
22 show TypeInferrer; 22 show TypeInferrer;
23 23
24 import 'package:front_end/src/fasta/type_inference/type_promotion.dart' 24 import 'package:front_end/src/fasta/type_inference/type_promotion.dart'
25 show TypePromoter; 25 show TypePromoter;
26 26
27 import 'package:kernel/ast.dart'; 27 import 'package:kernel/ast.dart'
28 hide InvalidExpression, InvalidInitializer, InvalidStatement;
28 29
29 import 'package:kernel/clone.dart' show CloneVisitor; 30 import 'package:kernel/clone.dart' show CloneVisitor;
30 31
31 import 'package:kernel/transformations/flags.dart' show TransformerFlag; 32 import 'package:kernel/transformations/flags.dart' show TransformerFlag;
32 33
33 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; 34 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
34 35
35 import 'package:kernel/core_types.dart' show CoreTypes; 36 import 'package:kernel/core_types.dart' show CoreTypes;
36 37
37 import 'frontend_accessors.dart' show buildIsNull, makeBinary, makeLet; 38 import 'frontend_accessors.dart' show buildIsNull, makeBinary, makeLet;
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 var node = pop(); 457 var node = pop();
457 Initializer initializer; 458 Initializer initializer;
458 if (node is Initializer) { 459 if (node is Initializer) {
459 initializer = node; 460 initializer = node;
460 } else if (node is FastaAccessor) { 461 } else if (node is FastaAccessor) {
461 initializer = node.buildFieldInitializer(fieldInitializers); 462 initializer = node.buildFieldInitializer(fieldInitializers);
462 } else if (node is ConstructorInvocation) { 463 } else if (node is ConstructorInvocation) {
463 initializer = 464 initializer =
464 buildSuperInitializer(node.target, node.arguments, token.charOffset); 465 buildSuperInitializer(node.target, node.arguments, token.charOffset);
465 } else { 466 } else {
467 Expression value = toValue(node);
466 if (node is! Throw) { 468 if (node is! Throw) {
467 // TODO(ahe): This is probably an internal error. 469 value = wrapInCompileTimeError(value, "Expected an initializer.");
468 needsImplicitSuperInitializer = false;
469 node = wrapInvalid(node);
470 } 470 }
471 initializer = buildInvalidIntializer(node, token.charOffset); 471 initializer = buildInvalidIntializer(node, token.charOffset);
472 } 472 }
473 _typeInferrer.inferInitializer(initializer); 473 _typeInferrer.inferInitializer(initializer);
474 if (member is KernelConstructorBuilder) { 474 if (member is KernelConstructorBuilder) {
475 member.addInitializer(initializer); 475 member.addInitializer(initializer);
476 } else { 476 } else {
477 addCompileTimeError( 477 addCompileTimeError(
478 token.charOffset, "Can't have initializers: ${member.name}"); 478 token.charOffset, "Can't have initializers: ${member.name}");
479 } 479 }
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 Block block = popBlock(count, beginToken); 1226 Block block = popBlock(count, beginToken);
1227 exitLocalScope(); 1227 exitLocalScope();
1228 push(block); 1228 push(block);
1229 } 1229 }
1230 1230
1231 @override 1231 @override
1232 void handleAssignmentExpression(Token token) { 1232 void handleAssignmentExpression(Token token) {
1233 debugEvent("AssignmentExpression"); 1233 debugEvent("AssignmentExpression");
1234 Expression value = popForValue(); 1234 Expression value = popForValue();
1235 var accessor = pop(); 1235 var accessor = pop();
1236 if (accessor is TypeDeclarationBuilder) { 1236 if (accessor is TypeDeclarationBuilder || accessor is! FastaAccessor) {
ahe 2017/05/29 13:14:47 This change is what's causing the new compile-time
1237 push(wrapInvalid(new KernelTypeLiteral(
1238 accessor.buildTypesWithBuiltArguments(library, null))));
1239 } else if (accessor is! FastaAccessor) {
1240 push(buildCompileTimeError("Can't assign to this.", token.charOffset)); 1237 push(buildCompileTimeError("Can't assign to this.", token.charOffset));
1241 } else { 1238 } else {
1242 push(new DelayedAssignment( 1239 push(new DelayedAssignment(
1243 this, token, accessor, value, token.stringValue)); 1240 this, token, accessor, value, token.stringValue));
1244 } 1241 }
1245 } 1242 }
1246 1243
1247 @override 1244 @override
1248 void enterLoop(int charOffset) { 1245 void enterLoop(int charOffset) {
1249 if (peek() is LabelTarget) { 1246 if (peek() is LabelTarget) {
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 VariableDeclaration stackTrace; 1757 VariableDeclaration stackTrace;
1761 if (catchParameters != null) { 1758 if (catchParameters != null) {
1762 if (catchParameters.required.length > 0) { 1759 if (catchParameters.required.length > 0) {
1763 exception = catchParameters.required[0]; 1760 exception = catchParameters.required[0];
1764 } 1761 }
1765 if (catchParameters.required.length > 1) { 1762 if (catchParameters.required.length > 1) {
1766 stackTrace = catchParameters.required[1]; 1763 stackTrace = catchParameters.required[1];
1767 } 1764 }
1768 if (catchParameters.required.length > 2 || 1765 if (catchParameters.required.length > 2 ||
1769 catchParameters.optional != null) { 1766 catchParameters.optional != null) {
1770 body = new Block(<Statement>[new InvalidStatement()]); 1767 body = new Block(<Statement>[
1771 compileTimeErrorInTry ??= buildCompileTimeErrorStatement( 1768 compileTimeErrorInTry ??= buildCompileTimeErrorStatement(
1772 "Invalid catch arguments.", catchKeyword.next.charOffset); 1769 "Invalid catch arguments.", catchKeyword.next.charOffset)
1770 ]);
1773 } 1771 }
1774 } 1772 }
1775 push(new Catch(exception, body, guard: type, stackTrace: stackTrace)); 1773 push(new Catch(exception, body, guard: type, stackTrace: stackTrace));
1776 } 1774 }
1777 1775
1778 @override 1776 @override
1779 void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) { 1777 void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
1780 Statement finallyBlock = popStatementIfNotNull(finallyKeyword); 1778 Statement finallyBlock = popStatementIfNotNull(finallyKeyword);
1781 List<Catch> catches = popList(catchCount); 1779 List<Catch> catches = popList(catchCount);
1782 Statement tryBlock = popStatement(); 1780 Statement tryBlock = popStatement();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1848 } 1846 }
1849 1847
1850 @override 1848 @override
1851 void handleUnaryPrefixAssignmentExpression(Token token) { 1849 void handleUnaryPrefixAssignmentExpression(Token token) {
1852 debugEvent("UnaryPrefixAssignmentExpression"); 1850 debugEvent("UnaryPrefixAssignmentExpression");
1853 var accessor = pop(); 1851 var accessor = pop();
1854 if (accessor is FastaAccessor) { 1852 if (accessor is FastaAccessor) {
1855 push(accessor.buildPrefixIncrement(incrementOperator(token), 1853 push(accessor.buildPrefixIncrement(incrementOperator(token),
1856 offset: token.charOffset)); 1854 offset: token.charOffset));
1857 } else { 1855 } else {
1858 push(wrapInvalid(toValue(accessor))); 1856 push(wrapInCompileTimeError(toValue(accessor), "Can't assign to this."));
1859 } 1857 }
1860 } 1858 }
1861 1859
1862 @override 1860 @override
1863 void handleUnaryPostfixAssignmentExpression(Token token) { 1861 void handleUnaryPostfixAssignmentExpression(Token token) {
1864 debugEvent("UnaryPostfixAssignmentExpression"); 1862 debugEvent("UnaryPostfixAssignmentExpression");
1865 var accessor = pop(); 1863 var accessor = pop();
1866 if (accessor is FastaAccessor) { 1864 if (accessor is FastaAccessor) {
1867 push(new DelayedPostfixIncrement( 1865 push(new DelayedPostfixIncrement(
1868 this, token, accessor, incrementOperator(token), null)); 1866 this, token, accessor, incrementOperator(token), null));
1869 } else { 1867 } else {
1870 push(wrapInvalid(toValue(accessor))); 1868 push(wrapInCompileTimeError(toValue(accessor), "Can't assign to this."));
1871 } 1869 }
1872 } 1870 }
1873 1871
1874 @override 1872 @override
1875 void endConstructorReference( 1873 void endConstructorReference(
1876 Token start, Token periodBeforeName, Token endToken) { 1874 Token start, Token periodBeforeName, Token endToken) {
1877 debugEvent("ConstructorReference"); 1875 debugEvent("ConstructorReference");
1878 // A constructor reference can contain up to three identifiers: 1876 // A constructor reference can contain up to three identifiers:
1879 // 1877 //
1880 // a) type <type-arguments>? 1878 // a) type <type-arguments>?
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
2130 2128
2131 @override 2129 @override
2132 void endFunctionName(Token beginToken, Token token) { 2130 void endFunctionName(Token beginToken, Token token) {
2133 debugEvent("FunctionName"); 2131 debugEvent("FunctionName");
2134 Identifier name = pop(); 2132 Identifier name = pop();
2135 VariableDeclaration variable = new KernelVariableDeclaration( 2133 VariableDeclaration variable = new KernelVariableDeclaration(
2136 name.name, functionNestingLevel, 2134 name.name, functionNestingLevel,
2137 isFinal: true, isLocalFunction: true) 2135 isFinal: true, isLocalFunction: true)
2138 ..fileOffset = offsetForToken(name.token); 2136 ..fileOffset = offsetForToken(name.token);
2139 push(new KernelFunctionDeclaration( 2137 push(new KernelFunctionDeclaration(
2140 variable, new FunctionNode(new InvalidStatement())) 2138 variable,
2139 // The function node is created later.
2140 null)
2141 ..fileOffset = beginToken.charOffset); 2141 ..fileOffset = beginToken.charOffset);
2142 declareVariable(variable); 2142 declareVariable(variable);
2143 enterLocalScope(); 2143 enterLocalScope();
2144 } 2144 }
2145 2145
2146 void enterFunction() { 2146 void enterFunction() {
2147 debugEvent("enterFunction"); 2147 debugEvent("enterFunction");
2148 functionNestingLevel++; 2148 functionNestingLevel++;
2149 push(switchScope ?? NullValue.SwitchScope); 2149 push(switchScope ?? NullValue.SwitchScope);
2150 switchScope = null; 2150 switchScope = null;
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
2651 @override 2651 @override
2652 Expression buildCompileTimeError(error, [int charOffset = -1]) { 2652 Expression buildCompileTimeError(error, [int charOffset = -1]) {
2653 // TODO(ahe): This method should be passed the erroneous expression, wrap 2653 // TODO(ahe): This method should be passed the erroneous expression, wrap
2654 // it in a class (TBD) from which the erroneous expression can be easily 2654 // it in a class (TBD) from which the erroneous expression can be easily
2655 // extracted. Similar for statements and initializers. See also [issue 2655 // extracted. Similar for statements and initializers. See also [issue
2656 // 29717](https://github.com/dart-lang/sdk/issues/29717) 2656 // 29717](https://github.com/dart-lang/sdk/issues/29717)
2657 addCompileTimeError(charOffset, error); 2657 addCompileTimeError(charOffset, error);
2658 String message = formatUnexpected(uri, charOffset, error); 2658 String message = formatUnexpected(uri, charOffset, error);
2659 Builder constructor = library.loader.getCompileTimeError(); 2659 Builder constructor = library.loader.getCompileTimeError();
2660 return new Throw(buildStaticInvocation(constructor.target, 2660 return new Throw(buildStaticInvocation(constructor.target,
2661 new KernelArguments(<Expression>[new StringLiteral(message)]))); 2661 new KernelArguments(<Expression>[new StringLiteral(message)]),
2662 charOffset: charOffset));
2663 }
2664
2665 Expression wrapInCompileTimeError(Expression expression, String message) {
2666 return new Let(
2667 new VariableDeclaration.forValue(expression)
2668 ..fileOffset = expression.fileOffset,
2669 buildCompileTimeError(message, expression.fileOffset))
2670 ..fileOffset = expression.fileOffset;
2662 } 2671 }
2663 2672
2664 Expression buildAbstractClassInstantiationError(String className, 2673 Expression buildAbstractClassInstantiationError(String className,
2665 [int charOffset = -1]) { 2674 [int charOffset = -1]) {
2666 warning("The class '$className' is abstract and can't be instantiated.", 2675 warning("The class '$className' is abstract and can't be instantiated.",
2667 charOffset); 2676 charOffset);
2668 Builder constructor = library.loader.getAbstractClassInstantiationError(); 2677 Builder constructor = library.loader.getAbstractClassInstantiationError();
2669 return new Throw(buildStaticInvocation(constructor.target, 2678 return new Throw(buildStaticInvocation(constructor.target,
2670 new KernelArguments(<Expression>[new StringLiteral(className)]))); 2679 new KernelArguments(<Expression>[new StringLiteral(className)])));
2671 } 2680 }
(...skipping 30 matching lines...) Expand all
2702 } 2711 }
2703 2712
2704 @override 2713 @override
2705 Expression buildProblemExpression(ProblemBuilder builder, int charOffset) { 2714 Expression buildProblemExpression(ProblemBuilder builder, int charOffset) {
2706 return buildCompileTimeError(builder.message, charOffset); 2715 return buildCompileTimeError(builder.message, charOffset);
2707 } 2716 }
2708 2717
2709 @override 2718 @override
2710 void handleOperator(Token token) { 2719 void handleOperator(Token token) {
2711 debugEvent("Operator"); 2720 debugEvent("Operator");
2712 push(new Operator(token.stringValue)..fileOffset = token.charOffset); 2721 push(new Operator(token.stringValue, token.charOffset));
2713 } 2722 }
2714 2723
2715 @override 2724 @override
2716 void handleSymbolVoid(Token token) { 2725 void handleSymbolVoid(Token token) {
2717 debugEvent("SymbolVoid"); 2726 debugEvent("SymbolVoid");
2718 push(new Identifier(token)); 2727 push(new Identifier(token));
2719 } 2728 }
2720 2729
2721 @override 2730 @override
2722 dynamic addCompileTimeError(int charOffset, String message, 2731 dynamic addCompileTimeError(int charOffset, String message,
2723 {bool silent: false}) { 2732 {bool silent: false}) {
2724 // TODO(ahe): If constantExpressionRequired is set, set it to false to 2733 // TODO(ahe): If constantExpressionRequired is set, set it to false to
2725 // avoid a long list of errors. 2734 // avoid a long list of errors.
2726 return library.addCompileTimeError(charOffset, message, fileUri: uri); 2735 return library.addCompileTimeError(charOffset, message, fileUri: uri);
2727 } 2736 }
2728 2737
2729 @override 2738 @override
2730 void handleInvalidFunctionBody(Token token) { 2739 void handleInvalidFunctionBody(Token token) {
2731 if (member.isNative) { 2740 if (member.isNative) {
2732 push(NullValue.FunctionBody); 2741 push(NullValue.FunctionBody);
2733 } else { 2742 } else {
2734 push(new Block(<Statement>[new InvalidStatement()])); 2743 push(new Block(<Statement>[
2744 buildCompileTimeErrorStatement("Expected '{'.", token.charOffset)
2745 ]));
2735 } 2746 }
2736 } 2747 }
2737 2748
2738 @override 2749 @override
2739 void warning(String message, [int charOffset = -1]) { 2750 void warning(String message, [int charOffset = -1]) {
2740 if (constantExpressionRequired) { 2751 if (constantExpressionRequired) {
2741 addCompileTimeError(charOffset, message); 2752 addCompileTimeError(charOffset, message);
2742 } else { 2753 } else {
2743 super.warning(message, charOffset); 2754 super.warning(message, charOffset);
2744 } 2755 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2793 final Token token; 2804 final Token token;
2794 String get name => token.lexeme; 2805 String get name => token.lexeme;
2795 2806
2796 Identifier(this.token); 2807 Identifier(this.token);
2797 2808
2798 Expression get initializer => null; 2809 Expression get initializer => null;
2799 2810
2800 String toString() => "identifier($name)"; 2811 String toString() => "identifier($name)";
2801 } 2812 }
2802 2813
2803 // TODO(ahe): Shouldn't need to be an expression. 2814 class Operator {
2804 class Operator extends InvalidExpression {
2805 final String name; 2815 final String name;
2806 2816
2807 Operator(this.name); 2817 final int charOffset;
2818
2819 Operator(this.name, this.charOffset);
2808 2820
2809 String toString() => "operator($name)"; 2821 String toString() => "operator($name)";
2810 } 2822 }
2811 2823
2812 class InitializedIdentifier extends Identifier { 2824 class InitializedIdentifier extends Identifier {
2813 final Expression initializer; 2825 final Expression initializer;
2814 2826
2815 InitializedIdentifier(Token token, this.initializer) : super(token); 2827 InitializedIdentifier(Token token, this.initializer) : super(token);
2816 2828
2817 String toString() => "initialized-identifier($name, $initializer)"; 2829 String toString() => "initialized-identifier($name, $initializer)";
2818 } 2830 }
2819 2831
2820 // TODO(ahe): Shouldn't need to be an expression. 2832 class Label {
2821 class Label extends InvalidExpression {
2822 String name; 2833 String name;
2823 2834
2824 Label(this.name); 2835 Label(this.name);
2825 2836
2826 String toString() => "label($name)"; 2837 String toString() => "label($name)";
2827 } 2838 }
2828 2839
2829 abstract class ContextAccessor extends FastaAccessor { 2840 abstract class ContextAccessor extends FastaAccessor {
2830 final BuilderHelper helper; 2841 final BuilderHelper helper;
2831 2842
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
3238 if (starToken == null) { 3249 if (starToken == null) {
3239 return AsyncMarker.Async; 3250 return AsyncMarker.Async;
3240 } else { 3251 } else {
3241 assert(identical(starToken.stringValue, "*")); 3252 assert(identical(starToken.stringValue, "*"));
3242 return AsyncMarker.AsyncStar; 3253 return AsyncMarker.AsyncStar;
3243 } 3254 }
3244 } else { 3255 } else {
3245 return internalError("Unknown async modifier: $asyncToken"); 3256 return internalError("Unknown async modifier: $asyncToken");
3246 } 3257 }
3247 } 3258 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/kernel/fasta_support.dart ('k') | pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698