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

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

Issue 2691523002: Ensure locations are always provided, but don't store them yet. (Closed)
Patch Set: Missing file. Created 3 years, 10 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 'package:front_end/src/fasta/parser/parser.dart' show 7 import 'package:front_end/src/fasta/parser/parser.dart' show
8 FormalParameterType, 8 FormalParameterType,
9 optional; 9 optional;
10 10
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 } 273 }
274 274
275 void exitSwitchScope() { 275 void exitSwitchScope() {
276 switchScope = pop(); 276 switchScope = pop();
277 } 277 }
278 278
279 @override 279 @override
280 Uri get uri => library.fileUri ?? library.uri; 280 Uri get uri => library.fileUri ?? library.uri;
281 281
282 @override 282 @override
283 JumpTarget createJumpTarget(JumpTargetKind kind) => new JumpTarget(kind); 283 JumpTarget createJumpTarget(JumpTargetKind kind, int charOffset) {
284 return new JumpTarget(kind, member, charOffset);
285 }
284 286
285 @override 287 @override
286 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { 288 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
287 debugEvent("Metadata"); 289 debugEvent("Metadata");
288 pop(); // Arguments. 290 pop(); // Arguments.
289 popIfNotNull(periodBeforeName); // Postfix. 291 popIfNotNull(periodBeforeName); // Postfix.
290 pop(); // Type arguments. 292 pop(); // Type arguments.
291 pop(); // Expression or type name (depends on arguments). 293 pop(); // Expression or type name (depends on arguments).
292 // TODO(ahe): Implement metadata on local declarations. 294 // TODO(ahe): Implement metadata on local declarations.
293 } 295 }
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 } 701 }
700 return null; 702 return null;
701 } 703 }
702 704
703 @override 705 @override
704 void beginExpression(Token token) { 706 void beginExpression(Token token) {
705 debugEvent("beginExpression"); 707 debugEvent("beginExpression");
706 isFirstIdentifier = true; 708 isFirstIdentifier = true;
707 } 709 }
708 710
709 Builder computeSetter(Builder builder, Scope scope, String name) { 711 Builder computeSetter(
712 Builder builder, Scope scope, String name, int charOffset) {
710 if (builder.isSetter) return builder; 713 if (builder.isSetter) return builder;
711 if (builder.isGetter) return scope.lookupSetter(name); 714 if (builder.isGetter) return scope.lookupSetter(name, charOffset, uri);
712 return builder.isField ? (builder.isFinal ? null : builder) : null; 715 return builder.isField ? (builder.isFinal ? null : builder) : null;
713 } 716 }
714 717
715 @override 718 @override
716 void handleIdentifier(Token token) { 719 void handleIdentifier(Token token) {
717 debugEvent("handleIdentifier"); 720 debugEvent("handleIdentifier");
718 String name = token.value; 721 String name = token.value;
719 if (isFirstIdentifier) { 722 if (isFirstIdentifier) {
720 assert(!inInitializer || this.scope == enclosingScope || 723 assert(!inInitializer || this.scope == enclosingScope ||
721 this.scope.parent == enclosingScope); 724 this.scope.parent == enclosingScope);
722 // This deals with this kind of initializer: `C(a) : a = a;` 725 // This deals with this kind of initializer: `C(a) : a = a;`
723 Scope scope = inInitializer ? enclosingScope : this.scope; 726 Scope scope = inInitializer ? enclosingScope : this.scope;
724 Builder builder = scope.lookup(name); 727 Builder builder = scope.lookup(name, token.charOffset, uri);
725 push(builderToFirstExpression(builder, name, token.charOffset)); 728 push(builderToFirstExpression(builder, name, token.charOffset));
726 } else { 729 } else {
727 push(new Identifier(name)..fileOffset = token.charOffset); 730 push(new Identifier(name)..fileOffset = token.charOffset);
728 } 731 }
729 } 732 }
730 733
731 @override 734 @override
732 builderToFirstExpression(Builder builder, String name, int charOffset, 735 builderToFirstExpression(Builder builder, String name, int charOffset,
733 {bool isPrefix: false}) { 736 {bool isPrefix: false}) {
734 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { 737 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) {
735 if (!isPrefix && identical(name, "dynamic") && builder == null) { 738 if (!isPrefix && identical(name, "dynamic") && builder == null) {
736 return new KernelNamedTypeBuilder(name, null); 739 return new KernelNamedTypeBuilder(name, null, charOffset, uri);
737 } 740 }
738 Name n = new Name(name, library.library); 741 Name n = new Name(name, library.library);
739 if (!isPrefix && isInstanceContext) { 742 if (!isPrefix && isInstanceContext) {
740 assert(builder == null); 743 assert(builder == null);
741 return new ThisPropertyAccessor(this, charOffset, n, null, null); 744 return new ThisPropertyAccessor(this, charOffset, n, null, null);
742 } else { 745 } else {
743 return new UnresolvedIdentifier(n) 746 return new UnresolvedIdentifier(n)
744 ..fileOffset = charOffset; 747 ..fileOffset = charOffset;
745 } 748 }
746 } else if (builder.isTypeDeclaration) { 749 } else if (builder.isTypeDeclaration) {
(...skipping 14 matching lines...) Expand all
761 } else { 764 } else {
762 if (builder is AccessErrorBuilder) { 765 if (builder is AccessErrorBuilder) {
763 AccessErrorBuilder error = builder; 766 AccessErrorBuilder error = builder;
764 builder = error.builder; 767 builder = error.builder;
765 } 768 }
766 if (builder.target == null) { 769 if (builder.target == null) {
767 return internalError("Unhandled: ${builder}"); 770 return internalError("Unhandled: ${builder}");
768 } 771 }
769 Member getter = builder.target.hasGetter ? builder.target : null; 772 Member getter = builder.target.hasGetter ? builder.target : null;
770 Member setter = builder.target.hasSetter ? builder.target : null; 773 Member setter = builder.target.hasSetter ? builder.target : null;
771 setter ??= computeSetter(builder, scope, name)?.target; 774 setter ??= computeSetter(builder, scope, name, charOffset)?.target;
772 return 775 return
773 new StaticAccessor(this, charOffset, getter, setter); 776 new StaticAccessor(this, charOffset, getter, setter);
774 } 777 }
775 } 778 }
776 779
777 @override 780 @override
778 void handleQualified(Token period) { 781 void handleQualified(Token period) {
779 debugEvent("Qualified"); 782 debugEvent("Qualified");
780 Identifier name = pop(); 783 Identifier name = pop();
781 var receiver = pop(); 784 var receiver = pop();
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 TreeNode node = pop(); 903 TreeNode node = pop();
901 VariableDeclaration variable; 904 VariableDeclaration variable;
902 if (node is VariableDeclaration) { 905 if (node is VariableDeclaration) {
903 variable = node; 906 variable = node;
904 } else if (node is Identifier) { 907 } else if (node is Identifier) {
905 variable = new VariableDeclaration(node.name); 908 variable = new VariableDeclaration(node.name);
906 } else { 909 } else {
907 internalError("unhandled identifier: ${node.runtimeType}"); 910 internalError("unhandled identifier: ${node.runtimeType}");
908 } 911 }
909 push(variable); 912 push(variable);
910 scope[variable.name] = new KernelVariableBuilder(variable); 913 scope[variable.name] =
914 new KernelVariableBuilder(variable, member ?? classBuilder);
Johnni Winther 2017/02/13 08:42:03 Should it be `member ?? classBuilder ?? library` ?
ahe 2017/02/13 10:44:23 I've added a TODO. It should be the current part,
911 } 915 }
912 916
913 @override 917 @override
914 void endVariablesDeclaration(int count, Token endToken) { 918 void endVariablesDeclaration(int count, Token endToken) {
915 debugEvent("VariablesDeclaration"); 919 debugEvent("VariablesDeclaration");
916 List<VariableDeclaration> variables = popList(count); 920 List<VariableDeclaration> variables = popList(count);
917 DartType type = pop(); 921 DartType type = pop();
918 int modifiers = Modifier.validate(pop()); 922 int modifiers = Modifier.validate(pop());
919 bool isConst = (modifiers & constMask) != 0; 923 bool isConst = (modifiers & constMask) != 0;
920 bool isFinal = (modifiers & finalMask) != 0; 924 bool isFinal = (modifiers & finalMask) != 0;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 new TypeLiteral(accessor.buildTypesWithBuiltArguments(null)))); 956 new TypeLiteral(accessor.buildTypesWithBuiltArguments(null))));
953 } else if (accessor is! BuilderAccessor) { 957 } else if (accessor is! BuilderAccessor) {
954 push(buildCompileTimeError("Can't assign to this.", token.charOffset)); 958 push(buildCompileTimeError("Can't assign to this.", token.charOffset));
955 } else { 959 } else {
956 push(new DelayedAssignment(this, token.charOffset, accessor, value, 960 push(new DelayedAssignment(this, token.charOffset, accessor, value,
957 token.stringValue)); 961 token.stringValue));
958 } 962 }
959 } 963 }
960 964
961 @override 965 @override
962 void enterLoop() { 966 void enterLoop(int charOffset) {
963 if (peek() is LabelTarget) { 967 if (peek() is LabelTarget) {
964 LabelTarget target = peek(); 968 LabelTarget target = peek();
965 enterBreakTarget(target.breakTarget); 969 enterBreakTarget(charOffset, target.breakTarget);
966 enterContinueTarget(target.continueTarget); 970 enterContinueTarget(charOffset, target.continueTarget);
967 } else{ 971 } else{
968 enterBreakTarget(); 972 enterBreakTarget(charOffset);
969 enterContinueTarget(); 973 enterContinueTarget(charOffset);
970 } 974 }
971 } 975 }
972 976
973 void exitLoopOrSwitch(Statement statement) { 977 void exitLoopOrSwitch(Statement statement) {
974 if (compileTimeErrorInLoopOrSwitch != null) { 978 if (compileTimeErrorInLoopOrSwitch != null) {
975 push(compileTimeErrorInLoopOrSwitch); 979 push(compileTimeErrorInLoopOrSwitch);
976 compileTimeErrorInLoopOrSwitch = null; 980 compileTimeErrorInLoopOrSwitch = null;
977 } else { 981 } else {
978 push(statement); 982 push(statement);
979 } 983 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 } else { 1137 } else {
1134 List parts = popList(identifierCount); 1138 List parts = popList(identifierCount);
1135 value = symbolPartToString(parts.first); 1139 value = symbolPartToString(parts.first);
1136 for (int i = 1; i < parts.length; i++) { 1140 for (int i = 1; i < parts.length; i++) {
1137 value += ".${symbolPartToString(parts[i])}"; 1141 value += ".${symbolPartToString(parts[i])}";
1138 } 1142 }
1139 } 1143 }
1140 push(new SymbolLiteral(value)); 1144 push(new SymbolLiteral(value));
1141 } 1145 }
1142 1146
1143 DartType toKernelType(String name, List<DartType> arguments) { 1147 DartType toKernelType(String name, List<DartType> arguments, int charOffset) {
1144 if (identical(name, "void")) return const VoidType(); 1148 if (identical(name, "void")) return const VoidType();
1145 if (identical(name, "dynamic")) return const DynamicType(); 1149 if (identical(name, "dynamic")) return const DynamicType();
1146 Builder builder = scope.lookup(name); 1150 Builder builder = scope.lookup(name, charOffset, uri);
1147 if (builder is TypeDeclarationBuilder) { 1151 if (builder is TypeDeclarationBuilder) {
1148 return builder.buildTypesWithBuiltArguments(arguments); 1152 return builder.buildTypesWithBuiltArguments(arguments);
1149 } 1153 }
1150 if (builder == null) { 1154 if (builder == null) {
1151 print("$uri: Type not found: $name"); 1155 print("$uri: Type not found: $name");
1152 } else { 1156 } else {
1153 print("$uri: Not a type: $name"); 1157 print("$uri: Not a type: $name");
1154 } 1158 }
1155 // TODO(ahe): Create an error somehow. 1159 // TODO(ahe): Create an error somehow.
1156 return const DynamicType(); 1160 return const DynamicType();
(...skipping 14 matching lines...) Expand all
1171 prefix = prefix.name; 1175 prefix = prefix.name;
1172 } 1176 }
1173 var suffix = name[1]; 1177 var suffix = name[1];
1174 if (suffix is Identifier) { 1178 if (suffix is Identifier) {
1175 suffix = suffix.name; 1179 suffix = suffix.name;
1176 } 1180 }
1177 Builder builder; 1181 Builder builder;
1178 if (prefix is Builder) { 1182 if (prefix is Builder) {
1179 builder = prefix; 1183 builder = prefix;
1180 } else { 1184 } else {
1181 builder = scope.lookup(prefix); 1185 builder = scope.lookup(prefix, beginToken.charOffset, uri);
1182 } 1186 }
1183 if (builder is PrefixBuilder) { 1187 if (builder is PrefixBuilder) {
1184 name = builder.exports[suffix]; 1188 name = builder.exports[suffix];
1185 } else { 1189 } else {
1186 return inputError( 1190 return inputError(
1187 "Can't be used as a type: '${debugName(prefix, suffix)}'.", 1191 "Can't be used as a type: '${debugName(prefix, suffix)}'.",
1188 beginToken.charOffset); 1192 beginToken.charOffset);
1189 } 1193 }
1190 } 1194 }
1191 if (name is Identifier) { 1195 if (name is Identifier) {
1192 name = name.name; 1196 name = name.name;
1193 } 1197 }
1194 if (name is BuilderAccessor) { 1198 if (name is BuilderAccessor) {
1195 warning("'${beginToken.value}' isn't a type.", beginToken.charOffset); 1199 warning("'${beginToken.value}' isn't a type.", beginToken.charOffset);
1196 push(const DynamicType()); 1200 push(const DynamicType());
1197 } else if (name is UnresolvedIdentifier) { 1201 } else if (name is UnresolvedIdentifier) {
1198 warning("'${name.name}' isn't a type.", beginToken.charOffset); 1202 warning("'${name.name}' isn't a type.", beginToken.charOffset);
1199 push(const DynamicType()); 1203 push(const DynamicType());
1200 } else if (name is TypeVariableBuilder) { 1204 } else if (name is TypeVariableBuilder) {
1201 push(name.buildTypesWithBuiltArguments(arguments)); 1205 push(name.buildTypesWithBuiltArguments(arguments));
1202 } else if (name is TypeDeclarationBuilder) { 1206 } else if (name is TypeDeclarationBuilder) {
1203 push(name.buildTypesWithBuiltArguments(arguments)); 1207 push(name.buildTypesWithBuiltArguments(arguments));
1204 } else if (name is TypeBuilder) { 1208 } else if (name is TypeBuilder) {
1205 push(name.build()); 1209 push(name.build());
1206 } else { 1210 } else {
1207 push(toKernelType(name, arguments)); 1211 push(toKernelType(name, arguments, beginToken.charOffset));
1208 } 1212 }
1209 if (peek() is TypeParameterType) { 1213 if (peek() is TypeParameterType) {
1210 TypeParameterType type = peek(); 1214 TypeParameterType type = peek();
1211 if (!isInstanceContext && type.parameter.parent is Class) { 1215 if (!isInstanceContext && type.parameter.parent is Class) {
1212 pop(); 1216 pop();
1213 warning("Type variables can only be used in instance methods.", 1217 warning("Type variables can only be used in instance methods.",
1214 beginToken.charOffset); 1218 beginToken.charOffset);
1215 push(const DynamicType()); 1219 push(const DynamicType());
1216 } 1220 }
1217 } 1221 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1256 @override 1260 @override
1257 void endThrowExpression(Token throwToken, Token endToken) { 1261 void endThrowExpression(Token throwToken, Token endToken) {
1258 debugEvent("ThrowExpression"); 1262 debugEvent("ThrowExpression");
1259 Expression expression = popForValue(); 1263 Expression expression = popForValue();
1260 push(new Throw(expression)); 1264 push(new Throw(expression));
1261 } 1265 }
1262 1266
1263 @override 1267 @override
1264 void endFormalParameter(Token thisKeyword) { 1268 void endFormalParameter(Token thisKeyword) {
1265 debugEvent("FormalParameter"); 1269 debugEvent("FormalParameter");
1270 // TODO(ahe): Need beginToken here.
1271 int charOffset = thisKeyword?.charOffset;
1266 if (thisKeyword != null) { 1272 if (thisKeyword != null) {
1267 if (!inConstructor) { 1273 if (!inConstructor) {
1268 return inputError("'this' parameters can only be used on constructors.", 1274 return inputError("'this' parameters can only be used on constructors.",
1269 thisKeyword.charOffset); 1275 thisKeyword.charOffset);
1270 } 1276 }
1271 } 1277 }
1272 Identifier name = pop(); 1278 Identifier name = pop();
1273 DartType type = pop(); 1279 DartType type = pop();
1274 pop(); // Modifiers. 1280 pop(); // Modifiers.
1275 ignore(Unhandled.Metadata); 1281 ignore(Unhandled.Metadata);
1276 VariableDeclaration variable; 1282 VariableDeclaration variable;
1277 if (!inCatchClause && functionNestingLevel == 0) { 1283 if (!inCatchClause && functionNestingLevel == 0) {
1278 var builder = formalParameterScope.lookup(name.name); 1284 var builder = formalParameterScope.lookup(name.name, charOffset, uri);
1279 if (builder == null) { 1285 if (builder == null) {
1280 return inputError("'${name.name}' isn't a field in this class.", 1286 return inputError("'${name.name}' isn't a field in this class.",
1281 name.fileOffset); 1287 name.fileOffset);
1282 } 1288 }
1283 if (thisKeyword == null) { 1289 if (thisKeyword == null) {
1284 variable = builder.build(); 1290 variable = builder.build();
1285 variable.initializer = name.initializer; 1291 variable.initializer = name.initializer;
1286 } else if (builder.isField && builder.parent == classBuilder) { 1292 } else if (builder.isField && builder.parent == classBuilder) {
1287 FieldBuilder field = builder; 1293 FieldBuilder field = builder;
1288 if (type != null) { 1294 if (type != null) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 debugEvent("FormalParameters"); 1352 debugEvent("FormalParameters");
1347 OptionalFormals optional; 1353 OptionalFormals optional;
1348 if (count > 0 && peek() is OptionalFormals) { 1354 if (count > 0 && peek() is OptionalFormals) {
1349 optional = pop(); 1355 optional = pop();
1350 count--; 1356 count--;
1351 } 1357 }
1352 FormalParameters formals = new FormalParameters( 1358 FormalParameters formals = new FormalParameters(
1353 popList(count) ?? <VariableDeclaration>[], optional); 1359 popList(count) ?? <VariableDeclaration>[], optional);
1354 push(formals); 1360 push(formals);
1355 if (inCatchClause || functionNestingLevel != 0) { 1361 if (inCatchClause || functionNestingLevel != 0) {
1356 enterLocalScope(formals.computeFormalParameterScope(scope)); 1362 enterLocalScope(formals.computeFormalParameterScope(
1363 scope, member ?? classBuilder ?? library));
1357 } 1364 }
1358 } 1365 }
1359 1366
1360 @override 1367 @override
1361 void beginCatchClause(Token token) { 1368 void beginCatchClause(Token token) {
1362 debugEvent("beginCatchClause"); 1369 debugEvent("beginCatchClause");
1363 inCatchClause = true; 1370 inCatchClause = true;
1364 } 1371 }
1365 1372
1366 @override 1373 @override
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1711 } 1718 }
1712 1719
1713 @override 1720 @override
1714 void endFunctionName(Token token) { 1721 void endFunctionName(Token token) {
1715 debugEvent("FunctionName"); 1722 debugEvent("FunctionName");
1716 Identifier name = pop(); 1723 Identifier name = pop();
1717 VariableDeclaration variable = new VariableDeclaration( 1724 VariableDeclaration variable = new VariableDeclaration(
1718 name.name, isFinal: true); 1725 name.name, isFinal: true);
1719 push(new FunctionDeclaration(variable, 1726 push(new FunctionDeclaration(variable,
1720 new FunctionNode(new InvalidStatement()))); 1727 new FunctionNode(new InvalidStatement())));
1721 scope[variable.name] = new KernelVariableBuilder(variable); 1728 scope[variable.name] =
1729 new KernelVariableBuilder(variable, member ?? classBuilder);
Johnni Winther 2017/02/13 08:42:03 Ditto.
ahe 2017/02/13 10:44:23 Done.
1722 enterLocalScope(); 1730 enterLocalScope();
1723 } 1731 }
1724 1732
1725 @override 1733 @override
1726 void beginFunction(Token token) { 1734 void beginFunction(Token token) {
1727 debugEvent("beginFunction"); 1735 debugEvent("beginFunction");
1728 functionNestingLevel++; 1736 functionNestingLevel++;
1729 } 1737 }
1730 1738
1731 @override 1739 @override
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1861 debugEvent("Label"); 1869 debugEvent("Label");
1862 Identifier identifier = pop(); 1870 Identifier identifier = pop();
1863 push(new Label(identifier.name)); 1871 push(new Label(identifier.name));
1864 } 1872 }
1865 1873
1866 @override 1874 @override
1867 void beginLabeledStatement(Token token, int labelCount) { 1875 void beginLabeledStatement(Token token, int labelCount) {
1868 debugEvent("beginLabeledStatement"); 1876 debugEvent("beginLabeledStatement");
1869 List<Label> labels = popList(labelCount); 1877 List<Label> labels = popList(labelCount);
1870 enterLocalScope(); 1878 enterLocalScope();
1871 LabelTarget target = new LabelTarget(); 1879 LabelTarget target = new LabelTarget(member, token.charOffset);
1872 for (Label label in labels) { 1880 for (Label label in labels) {
1873 scope[label.name] = target; 1881 scope[label.name] = target;
1874 } 1882 }
1875 push(target); 1883 push(target);
1876 } 1884 }
1877 1885
1878 @override 1886 @override
1879 void endLabeledStatement(int labelCount) { 1887 void endLabeledStatement(int labelCount) {
1880 debugEvent("LabeledStatement"); 1888 debugEvent("LabeledStatement");
1881 Statement statement = popStatement(); 1889 Statement statement = popStatement();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1946 void endYieldStatement(Token yieldToken, Token starToken, Token endToken) { 1954 void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
1947 debugEvent("YieldStatement"); 1955 debugEvent("YieldStatement");
1948 push(new YieldStatement(popForValue(), isYieldStar: starToken != null)); 1956 push(new YieldStatement(popForValue(), isYieldStar: starToken != null));
1949 } 1957 }
1950 1958
1951 @override 1959 @override
1952 void beginSwitchBlock(Token token) { 1960 void beginSwitchBlock(Token token) {
1953 debugEvent("beginSwitchBlock"); 1961 debugEvent("beginSwitchBlock");
1954 enterLocalScope(); 1962 enterLocalScope();
1955 enterSwitchScope(); 1963 enterSwitchScope();
1956 enterBreakTarget(); 1964 enterBreakTarget(token.charOffset);
1957 } 1965 }
1958 1966
1959 @override 1967 @override
1960 void beginSwitchCase(int labelCount, int expressionCount, Token firstToken) { 1968 void beginSwitchCase(int labelCount, int expressionCount, Token firstToken) {
1961 debugEvent("beginSwitchCase"); 1969 debugEvent("beginSwitchCase");
1962 List labelsAndExpressions = popList(labelCount + expressionCount); 1970 List labelsAndExpressions = popList(labelCount + expressionCount);
1963 List<Label> labels = <Label>[]; 1971 List<Label> labels = <Label>[];
1964 List<Expression> expressions = <Expression>[]; 1972 List<Expression> expressions = <Expression>[];
1965 if (labelsAndExpressions != null) { 1973 if (labelsAndExpressions != null) {
1966 for (var labelOrExpression in labelsAndExpressions) { 1974 for (var labelOrExpression in labelsAndExpressions) {
1967 if (labelOrExpression is Label) { 1975 if (labelOrExpression is Label) {
1968 labels.add(labelOrExpression); 1976 labels.add(labelOrExpression);
1969 } else { 1977 } else {
1970 expressions.add(toValue(labelOrExpression)); 1978 expressions.add(toValue(labelOrExpression));
1971 } 1979 }
1972 } 1980 }
1973 } 1981 }
1974 assert(scope == switchScope); 1982 assert(scope == switchScope);
1975 for (Label label in labels) { 1983 for (Label label in labels) {
1976 Builder existing = scope.local[label.name]; 1984 Builder existing = scope.local[label.name];
1977 if (existing == null) { 1985 if (existing == null) {
1978 scope[label.name] = createGotoTarget(); 1986 scope[label.name] = createGotoTarget(firstToken.charOffset);
1979 } else { 1987 } else {
1980 // TODO(ahe): Should validate this is a goto target and not duplicated. 1988 // TODO(ahe): Should validate this is a goto target and not duplicated.
1981 } 1989 }
1982 } 1990 }
1983 push(expressions); 1991 push(expressions);
1984 push(labels); 1992 push(labels);
1985 enterLocalScope(); 1993 enterLocalScope();
1986 } 1994 }
1987 1995
1988 @override 1996 @override
(...skipping 21 matching lines...) Expand all
2010 2018
2011 @override 2019 @override
2012 void endSwitchBlock(int caseCount, Token beginToken, Token endToken) { 2020 void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
2013 debugEvent("SwitchBlock"); 2021 debugEvent("SwitchBlock");
2014 List<SwitchCase> cases = 2022 List<SwitchCase> cases =
2015 new List<SwitchCase>.filled(caseCount, null, growable: true); 2023 new List<SwitchCase>.filled(caseCount, null, growable: true);
2016 for (int i = caseCount - 1; i >= 0; i--) { 2024 for (int i = caseCount - 1; i >= 0; i--) {
2017 List<Label> labels = pop(); 2025 List<Label> labels = pop();
2018 SwitchCase current = cases[i] = pop(); 2026 SwitchCase current = cases[i] = pop();
2019 for (Label label in labels) { 2027 for (Label label in labels) {
2020 JumpTarget target = switchScope.lookup(label.name); 2028 JumpTarget target =
2029 switchScope.lookup(label.name, label.fileOffset, uri);
2021 if (target != null) { 2030 if (target != null) {
2022 target.resolveGotos(current); 2031 target.resolveGotos(current);
2023 } 2032 }
2024 } 2033 }
2025 // TODO(ahe): Validate that there's only one default and it's last. 2034 // TODO(ahe): Validate that there's only one default and it's last.
2026 } 2035 }
2027 JumpTarget target = exitBreakTarget(); 2036 JumpTarget target = exitBreakTarget();
2028 exitSwitchScope(); 2037 exitSwitchScope();
2029 exitLocalScope(); 2038 exitLocalScope();
2030 Expression expression = popForValue(); 2039 Expression expression = popForValue();
(...skipping 13 matching lines...) Expand all
2044 2053
2045 @override 2054 @override
2046 void handleBreakStatement( 2055 void handleBreakStatement(
2047 bool hasTarget, Token breakKeyword, Token endToken) { 2056 bool hasTarget, Token breakKeyword, Token endToken) {
2048 debugEvent("BreakStatement"); 2057 debugEvent("BreakStatement");
2049 var target = breakTarget; 2058 var target = breakTarget;
2050 String name; 2059 String name;
2051 if (hasTarget) { 2060 if (hasTarget) {
2052 Identifier identifier = pop(); 2061 Identifier identifier = pop();
2053 name = identifier.name; 2062 name = identifier.name;
2054 target = scope.lookup(identifier.name); 2063 target = scope.lookup(
2064 identifier.name, breakKeyword.next.charOffset, uri);
2055 } 2065 }
2056 if (target == null && name == null) { 2066 if (target == null && name == null) {
2057 push(compileTimeErrorInLoopOrSwitch = 2067 push(compileTimeErrorInLoopOrSwitch =
2058 buildCompileTimeErrorStatement( 2068 buildCompileTimeErrorStatement(
2059 "No target of break.", breakKeyword.charOffset)); 2069 "No target of break.", breakKeyword.charOffset));
2060 } else if (target == null || target is! JumpTarget 2070 } else if (target == null || target is! JumpTarget
2061 || !target.isBreakTarget) { 2071 || !target.isBreakTarget) {
2062 push(compileTimeErrorInLoopOrSwitch = 2072 push(compileTimeErrorInLoopOrSwitch =
2063 buildCompileTimeErrorStatement("Can't break to '$name'.", 2073 buildCompileTimeErrorStatement("Can't break to '$name'.",
2064 breakKeyword.next.charOffset)); 2074 breakKeyword.next.charOffset));
2065 } else { 2075 } else {
2066 BreakStatement statement = new BreakStatement(null); 2076 BreakStatement statement = new BreakStatement(null);
2067 target.addBreak(statement); 2077 target.addBreak(statement);
2068 push(statement); 2078 push(statement);
2069 } 2079 }
2070 } 2080 }
2071 2081
2072 @override 2082 @override
2073 void handleContinueStatement( 2083 void handleContinueStatement(
2074 bool hasTarget, Token continueKeyword, Token endToken) { 2084 bool hasTarget, Token continueKeyword, Token endToken) {
2075 debugEvent("ContinueStatement"); 2085 debugEvent("ContinueStatement");
2076 var target = continueTarget; 2086 var target = continueTarget;
2077 String name; 2087 String name;
2078 if (hasTarget) { 2088 if (hasTarget) {
2079 Identifier identifier = pop(); 2089 Identifier identifier = pop();
2080 name = identifier.name; 2090 name = identifier.name;
2081 target = scope.lookup(identifier.name); 2091 target = scope.lookup(
2092 identifier.name, continueKeyword.next.charOffset, uri);
2082 if (target != null && target is! JumpTarget) { 2093 if (target != null && target is! JumpTarget) {
2083 push(compileTimeErrorInLoopOrSwitch = 2094 push(compileTimeErrorInLoopOrSwitch =
2084 buildCompileTimeErrorStatement( 2095 buildCompileTimeErrorStatement(
2085 "Target of continue must be a label.", 2096 "Target of continue must be a label.",
2086 continueKeyword.charOffset)); 2097 continueKeyword.charOffset));
2087 return; 2098 return;
2088 } 2099 }
2089 if (target == null) { 2100 if (target == null) {
2090 if (switchScope == null) { 2101 if (switchScope == null) {
2091 push(buildCompileTimeErrorStatement("Can't find label '$name'.", 2102 push(buildCompileTimeErrorStatement("Can't find label '$name'.",
2092 continueKeyword.next.charOffset)); 2103 continueKeyword.next.charOffset));
2093 return; 2104 return;
2094 } 2105 }
2095 switchScope[identifier.name] = target = createGotoTarget(); 2106 switchScope[identifier.name] = target =
2107 createGotoTarget(identifier.fileOffset);
2096 } 2108 }
2097 if (target.isGotoTarget) { 2109 if (target.isGotoTarget) {
2098 ContinueSwitchStatement statement = new ContinueSwitchStatement(null); 2110 ContinueSwitchStatement statement = new ContinueSwitchStatement(null);
2099 target.addGoto(statement); 2111 target.addGoto(statement);
2100 push(statement); 2112 push(statement);
2101 return; 2113 return;
2102 } 2114 }
2103 } 2115 }
2104 if (target == null) { 2116 if (target == null) {
2105 push(compileTimeErrorInLoopOrSwitch = 2117 push(compileTimeErrorInLoopOrSwitch =
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
2478 return accessor.buildPostfixIncrement(binaryOperator, voidContext: true, 2490 return accessor.buildPostfixIncrement(binaryOperator, voidContext: true,
2479 interfaceTarget: interfaceTarget); 2491 interfaceTarget: interfaceTarget);
2480 } 2492 }
2481 } 2493 }
2482 2494
2483 class JumpTarget extends Builder { 2495 class JumpTarget extends Builder {
2484 final List<Statement> users = <Statement>[]; 2496 final List<Statement> users = <Statement>[];
2485 2497
2486 final JumpTargetKind kind; 2498 final JumpTargetKind kind;
2487 2499
2488 JumpTarget(this.kind); 2500 JumpTarget(this.kind, MemberBuilder member, int charOffset)
2501 : super(member, charOffset, member.fileUri);
2489 2502
2490 bool get isBreakTarget => kind == JumpTargetKind.Break; 2503 bool get isBreakTarget => kind == JumpTargetKind.Break;
2491 2504
2492 bool get isContinueTarget => kind == JumpTargetKind.Continue; 2505 bool get isContinueTarget => kind == JumpTargetKind.Continue;
2493 2506
2494 bool get isGotoTarget => kind == JumpTargetKind.Goto; 2507 bool get isGotoTarget => kind == JumpTargetKind.Goto;
2495 2508
2496 bool get hasUsers => users.isNotEmpty; 2509 bool get hasUsers => users.isNotEmpty;
2497 2510
2498 void addBreak(BreakStatement statement) { 2511 void addBreak(BreakStatement statement) {
(...skipping 30 matching lines...) Expand all
2529 void resolveGotos(SwitchCase target) { 2542 void resolveGotos(SwitchCase target) {
2530 assert(isGotoTarget); 2543 assert(isGotoTarget);
2531 for (ContinueSwitchStatement user in users) { 2544 for (ContinueSwitchStatement user in users) {
2532 user.target = target; 2545 user.target = target;
2533 } 2546 }
2534 users.clear(); 2547 users.clear();
2535 } 2548 }
2536 } 2549 }
2537 2550
2538 class LabelTarget extends Builder implements JumpTarget { 2551 class LabelTarget extends Builder implements JumpTarget {
2539 final JumpTarget breakTarget = new JumpTarget(JumpTargetKind.Break); 2552 final JumpTarget breakTarget;
2540 2553
2541 final JumpTarget continueTarget = new JumpTarget(JumpTargetKind.Continue); 2554 final JumpTarget continueTarget;
2542 2555
2543 LabelTarget(); 2556 LabelTarget(MemberBuilder member, int charOffset)
2557 : breakTarget = new JumpTarget(JumpTargetKind.Break, member, charOffset),
2558 continueTarget =
2559 new JumpTarget(JumpTargetKind.Continue, member, charOffset),
2560 super(member, charOffset, member.fileUri);
2544 2561
2545 bool get hasUsers => breakTarget.hasUsers || continueTarget.hasUsers; 2562 bool get hasUsers => breakTarget.hasUsers || continueTarget.hasUsers;
2546 2563
2547 List<Statement> get users => internalError("Unsupported operation."); 2564 List<Statement> get users => internalError("Unsupported operation.");
2548 2565
2549 JumpTargetKind get kind => internalError("Unsupported operation."); 2566 JumpTargetKind get kind => internalError("Unsupported operation.");
2550 2567
2551 bool get isBreakTarget => true; 2568 bool get isBreakTarget => true;
2552 2569
2553 bool get isContinueTarget => true; 2570 bool get isContinueTarget => true;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2627 namedParameters.add(new NamedType(parameter.name, parameter.type)); 2644 namedParameters.add(new NamedType(parameter.name, parameter.type));
2628 } 2645 }
2629 namedParameters.sort(); 2646 namedParameters.sort();
2630 } 2647 }
2631 } 2648 }
2632 return new FunctionType(positionalParameters, returnType, 2649 return new FunctionType(positionalParameters, returnType,
2633 namedParameters: namedParameters, 2650 namedParameters: namedParameters,
2634 requiredParameterCount: requiredParameterCount); 2651 requiredParameterCount: requiredParameterCount);
2635 } 2652 }
2636 2653
2637 Scope computeFormalParameterScope(Scope parent) { 2654 Scope computeFormalParameterScope(Scope parent, Builder builder) {
2638 if (required.length == 0 && optional == null) return parent; 2655 if (required.length == 0 && optional == null) return parent;
2639 Map<String, Builder> local = <String, Builder>{}; 2656 Map<String, Builder> local = <String, Builder>{};
2640 for (VariableDeclaration parameter in required) { 2657 for (VariableDeclaration parameter in required) {
2641 local[parameter.name] = new KernelVariableBuilder(parameter); 2658 local[parameter.name] = new KernelVariableBuilder(parameter, builder);
2642 } 2659 }
2643 if (optional != null) { 2660 if (optional != null) {
2644 for (VariableDeclaration parameter in optional.formals) { 2661 for (VariableDeclaration parameter in optional.formals) {
2645 local[parameter.name] = new KernelVariableBuilder(parameter); 2662 local[parameter.name] = new KernelVariableBuilder(parameter, builder);
2646 } 2663 }
2647 } 2664 }
2648 return new Scope(local, parent, isModifiable: false); 2665 return new Scope(local, parent, isModifiable: false);
2649 } 2666 }
2650 } 2667 }
2651 2668
2652 /// Returns a block like this: 2669 /// Returns a block like this:
2653 /// 2670 ///
2654 /// { 2671 /// {
2655 /// statement; 2672 /// statement;
(...skipping 24 matching lines...) Expand all
2680 } else if (node is TypeDeclarationBuilder) { 2697 } else if (node is TypeDeclarationBuilder) {
2681 return node.name; 2698 return node.name;
2682 } else if (node is PrefixBuilder) { 2699 } else if (node is PrefixBuilder) {
2683 return node.name; 2700 return node.name;
2684 } else if (node is ThisPropertyAccessor) { 2701 } else if (node is ThisPropertyAccessor) {
2685 return node.name.name; 2702 return node.name.name;
2686 } else { 2703 } else {
2687 return internalError("Unhandled: ${node.runtimeType}"); 2704 return internalError("Unhandled: ${node.runtimeType}");
2688 } 2705 }
2689 } 2706 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698