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

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: Address comments. 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] = new KernelVariableBuilder(variable,
914 // TODO(ahe): This should be `member ?? classBuilder ?? part`, but we
915 // don't have an object representing the current part.
916 member ?? classBuilder);
911 } 917 }
912 918
913 @override 919 @override
914 void endVariablesDeclaration(int count, Token endToken) { 920 void endVariablesDeclaration(int count, Token endToken) {
915 debugEvent("VariablesDeclaration"); 921 debugEvent("VariablesDeclaration");
916 List<VariableDeclaration> variables = popList(count); 922 List<VariableDeclaration> variables = popList(count);
917 DartType type = pop(); 923 DartType type = pop();
918 int modifiers = Modifier.validate(pop()); 924 int modifiers = Modifier.validate(pop());
919 bool isConst = (modifiers & constMask) != 0; 925 bool isConst = (modifiers & constMask) != 0;
920 bool isFinal = (modifiers & finalMask) != 0; 926 bool isFinal = (modifiers & finalMask) != 0;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 new TypeLiteral(accessor.buildTypesWithBuiltArguments(null)))); 958 new TypeLiteral(accessor.buildTypesWithBuiltArguments(null))));
953 } else if (accessor is! BuilderAccessor) { 959 } else if (accessor is! BuilderAccessor) {
954 push(buildCompileTimeError("Can't assign to this.", token.charOffset)); 960 push(buildCompileTimeError("Can't assign to this.", token.charOffset));
955 } else { 961 } else {
956 push(new DelayedAssignment(this, token.charOffset, accessor, value, 962 push(new DelayedAssignment(this, token.charOffset, accessor, value,
957 token.stringValue)); 963 token.stringValue));
958 } 964 }
959 } 965 }
960 966
961 @override 967 @override
962 void enterLoop() { 968 void enterLoop(int charOffset) {
963 if (peek() is LabelTarget) { 969 if (peek() is LabelTarget) {
964 LabelTarget target = peek(); 970 LabelTarget target = peek();
965 enterBreakTarget(target.breakTarget); 971 enterBreakTarget(charOffset, target.breakTarget);
966 enterContinueTarget(target.continueTarget); 972 enterContinueTarget(charOffset, target.continueTarget);
967 } else{ 973 } else{
968 enterBreakTarget(); 974 enterBreakTarget(charOffset);
969 enterContinueTarget(); 975 enterContinueTarget(charOffset);
970 } 976 }
971 } 977 }
972 978
973 void exitLoopOrSwitch(Statement statement) { 979 void exitLoopOrSwitch(Statement statement) {
974 if (compileTimeErrorInLoopOrSwitch != null) { 980 if (compileTimeErrorInLoopOrSwitch != null) {
975 push(compileTimeErrorInLoopOrSwitch); 981 push(compileTimeErrorInLoopOrSwitch);
976 compileTimeErrorInLoopOrSwitch = null; 982 compileTimeErrorInLoopOrSwitch = null;
977 } else { 983 } else {
978 push(statement); 984 push(statement);
979 } 985 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 } else { 1139 } else {
1134 List parts = popList(identifierCount); 1140 List parts = popList(identifierCount);
1135 value = symbolPartToString(parts.first); 1141 value = symbolPartToString(parts.first);
1136 for (int i = 1; i < parts.length; i++) { 1142 for (int i = 1; i < parts.length; i++) {
1137 value += ".${symbolPartToString(parts[i])}"; 1143 value += ".${symbolPartToString(parts[i])}";
1138 } 1144 }
1139 } 1145 }
1140 push(new SymbolLiteral(value)); 1146 push(new SymbolLiteral(value));
1141 } 1147 }
1142 1148
1143 DartType toKernelType(String name, List<DartType> arguments) { 1149 DartType toKernelType(String name, List<DartType> arguments, int charOffset) {
1144 if (identical(name, "void")) return const VoidType(); 1150 if (identical(name, "void")) return const VoidType();
1145 if (identical(name, "dynamic")) return const DynamicType(); 1151 if (identical(name, "dynamic")) return const DynamicType();
1146 Builder builder = scope.lookup(name); 1152 Builder builder = scope.lookup(name, charOffset, uri);
1147 if (builder is TypeDeclarationBuilder) { 1153 if (builder is TypeDeclarationBuilder) {
1148 return builder.buildTypesWithBuiltArguments(arguments); 1154 return builder.buildTypesWithBuiltArguments(arguments);
1149 } 1155 }
1150 if (builder == null) { 1156 if (builder == null) {
1151 print("$uri: Type not found: $name"); 1157 print("$uri: Type not found: $name");
1152 } else { 1158 } else {
1153 print("$uri: Not a type: $name"); 1159 print("$uri: Not a type: $name");
1154 } 1160 }
1155 // TODO(ahe): Create an error somehow. 1161 // TODO(ahe): Create an error somehow.
1156 return const DynamicType(); 1162 return const DynamicType();
(...skipping 14 matching lines...) Expand all
1171 prefix = prefix.name; 1177 prefix = prefix.name;
1172 } 1178 }
1173 var suffix = name[1]; 1179 var suffix = name[1];
1174 if (suffix is Identifier) { 1180 if (suffix is Identifier) {
1175 suffix = suffix.name; 1181 suffix = suffix.name;
1176 } 1182 }
1177 Builder builder; 1183 Builder builder;
1178 if (prefix is Builder) { 1184 if (prefix is Builder) {
1179 builder = prefix; 1185 builder = prefix;
1180 } else { 1186 } else {
1181 builder = scope.lookup(prefix); 1187 builder = scope.lookup(prefix, beginToken.charOffset, uri);
1182 } 1188 }
1183 if (builder is PrefixBuilder) { 1189 if (builder is PrefixBuilder) {
1184 name = builder.exports[suffix]; 1190 name = builder.exports[suffix];
1185 } else { 1191 } else {
1186 return inputError( 1192 return inputError(
1187 "Can't be used as a type: '${debugName(prefix, suffix)}'.", 1193 "Can't be used as a type: '${debugName(prefix, suffix)}'.",
1188 beginToken.charOffset); 1194 beginToken.charOffset);
1189 } 1195 }
1190 } 1196 }
1191 if (name is Identifier) { 1197 if (name is Identifier) {
1192 name = name.name; 1198 name = name.name;
1193 } 1199 }
1194 if (name is BuilderAccessor) { 1200 if (name is BuilderAccessor) {
1195 warning("'${beginToken.value}' isn't a type.", beginToken.charOffset); 1201 warning("'${beginToken.value}' isn't a type.", beginToken.charOffset);
1196 push(const DynamicType()); 1202 push(const DynamicType());
1197 } else if (name is UnresolvedIdentifier) { 1203 } else if (name is UnresolvedIdentifier) {
1198 warning("'${name.name}' isn't a type.", beginToken.charOffset); 1204 warning("'${name.name}' isn't a type.", beginToken.charOffset);
1199 push(const DynamicType()); 1205 push(const DynamicType());
1200 } else if (name is TypeVariableBuilder) { 1206 } else if (name is TypeVariableBuilder) {
1201 push(name.buildTypesWithBuiltArguments(arguments)); 1207 push(name.buildTypesWithBuiltArguments(arguments));
1202 } else if (name is TypeDeclarationBuilder) { 1208 } else if (name is TypeDeclarationBuilder) {
1203 push(name.buildTypesWithBuiltArguments(arguments)); 1209 push(name.buildTypesWithBuiltArguments(arguments));
1204 } else if (name is TypeBuilder) { 1210 } else if (name is TypeBuilder) {
1205 push(name.build()); 1211 push(name.build());
1206 } else { 1212 } else {
1207 push(toKernelType(name, arguments)); 1213 push(toKernelType(name, arguments, beginToken.charOffset));
1208 } 1214 }
1209 if (peek() is TypeParameterType) { 1215 if (peek() is TypeParameterType) {
1210 TypeParameterType type = peek(); 1216 TypeParameterType type = peek();
1211 if (!isInstanceContext && type.parameter.parent is Class) { 1217 if (!isInstanceContext && type.parameter.parent is Class) {
1212 pop(); 1218 pop();
1213 warning("Type variables can only be used in instance methods.", 1219 warning("Type variables can only be used in instance methods.",
1214 beginToken.charOffset); 1220 beginToken.charOffset);
1215 push(const DynamicType()); 1221 push(const DynamicType());
1216 } 1222 }
1217 } 1223 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1256 @override 1262 @override
1257 void endThrowExpression(Token throwToken, Token endToken) { 1263 void endThrowExpression(Token throwToken, Token endToken) {
1258 debugEvent("ThrowExpression"); 1264 debugEvent("ThrowExpression");
1259 Expression expression = popForValue(); 1265 Expression expression = popForValue();
1260 push(new Throw(expression)); 1266 push(new Throw(expression));
1261 } 1267 }
1262 1268
1263 @override 1269 @override
1264 void endFormalParameter(Token thisKeyword) { 1270 void endFormalParameter(Token thisKeyword) {
1265 debugEvent("FormalParameter"); 1271 debugEvent("FormalParameter");
1272 // TODO(ahe): Need beginToken here.
1273 int charOffset = thisKeyword?.charOffset;
1266 if (thisKeyword != null) { 1274 if (thisKeyword != null) {
1267 if (!inConstructor) { 1275 if (!inConstructor) {
1268 return inputError("'this' parameters can only be used on constructors.", 1276 return inputError("'this' parameters can only be used on constructors.",
1269 thisKeyword.charOffset); 1277 thisKeyword.charOffset);
1270 } 1278 }
1271 } 1279 }
1272 Identifier name = pop(); 1280 Identifier name = pop();
1273 DartType type = pop(); 1281 DartType type = pop();
1274 pop(); // Modifiers. 1282 pop(); // Modifiers.
1275 ignore(Unhandled.Metadata); 1283 ignore(Unhandled.Metadata);
1276 VariableDeclaration variable; 1284 VariableDeclaration variable;
1277 if (!inCatchClause && functionNestingLevel == 0) { 1285 if (!inCatchClause && functionNestingLevel == 0) {
1278 var builder = formalParameterScope.lookup(name.name); 1286 var builder = formalParameterScope.lookup(name.name, charOffset, uri);
1279 if (builder == null) { 1287 if (builder == null) {
1280 return inputError("'${name.name}' isn't a field in this class.", 1288 return inputError("'${name.name}' isn't a field in this class.",
1281 name.fileOffset); 1289 name.fileOffset);
1282 } 1290 }
1283 if (thisKeyword == null) { 1291 if (thisKeyword == null) {
1284 variable = builder.build(); 1292 variable = builder.build();
1285 variable.initializer = name.initializer; 1293 variable.initializer = name.initializer;
1286 } else if (builder.isField && builder.parent == classBuilder) { 1294 } else if (builder.isField && builder.parent == classBuilder) {
1287 FieldBuilder field = builder; 1295 FieldBuilder field = builder;
1288 if (type != null) { 1296 if (type != null) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 debugEvent("FormalParameters"); 1354 debugEvent("FormalParameters");
1347 OptionalFormals optional; 1355 OptionalFormals optional;
1348 if (count > 0 && peek() is OptionalFormals) { 1356 if (count > 0 && peek() is OptionalFormals) {
1349 optional = pop(); 1357 optional = pop();
1350 count--; 1358 count--;
1351 } 1359 }
1352 FormalParameters formals = new FormalParameters( 1360 FormalParameters formals = new FormalParameters(
1353 popList(count) ?? <VariableDeclaration>[], optional); 1361 popList(count) ?? <VariableDeclaration>[], optional);
1354 push(formals); 1362 push(formals);
1355 if (inCatchClause || functionNestingLevel != 0) { 1363 if (inCatchClause || functionNestingLevel != 0) {
1356 enterLocalScope(formals.computeFormalParameterScope(scope)); 1364 enterLocalScope(formals.computeFormalParameterScope(
1365 scope, member ?? classBuilder ?? library));
1357 } 1366 }
1358 } 1367 }
1359 1368
1360 @override 1369 @override
1361 void beginCatchClause(Token token) { 1370 void beginCatchClause(Token token) {
1362 debugEvent("beginCatchClause"); 1371 debugEvent("beginCatchClause");
1363 inCatchClause = true; 1372 inCatchClause = true;
1364 } 1373 }
1365 1374
1366 @override 1375 @override
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1711 } 1720 }
1712 1721
1713 @override 1722 @override
1714 void endFunctionName(Token token) { 1723 void endFunctionName(Token token) {
1715 debugEvent("FunctionName"); 1724 debugEvent("FunctionName");
1716 Identifier name = pop(); 1725 Identifier name = pop();
1717 VariableDeclaration variable = new VariableDeclaration( 1726 VariableDeclaration variable = new VariableDeclaration(
1718 name.name, isFinal: true); 1727 name.name, isFinal: true);
1719 push(new FunctionDeclaration(variable, 1728 push(new FunctionDeclaration(variable,
1720 new FunctionNode(new InvalidStatement()))); 1729 new FunctionNode(new InvalidStatement())));
1721 scope[variable.name] = new KernelVariableBuilder(variable); 1730 scope[variable.name] = new KernelVariableBuilder(variable,
1731 // TODO(ahe): This should be `member ?? classBuilder ?? part`, but we
1732 // don't have an object representing the current part.
1733 member ?? classBuilder);
1722 enterLocalScope(); 1734 enterLocalScope();
1723 } 1735 }
1724 1736
1725 @override 1737 @override
1726 void beginFunction(Token token) { 1738 void beginFunction(Token token) {
1727 debugEvent("beginFunction"); 1739 debugEvent("beginFunction");
1728 functionNestingLevel++; 1740 functionNestingLevel++;
1729 } 1741 }
1730 1742
1731 @override 1743 @override
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1861 debugEvent("Label"); 1873 debugEvent("Label");
1862 Identifier identifier = pop(); 1874 Identifier identifier = pop();
1863 push(new Label(identifier.name)); 1875 push(new Label(identifier.name));
1864 } 1876 }
1865 1877
1866 @override 1878 @override
1867 void beginLabeledStatement(Token token, int labelCount) { 1879 void beginLabeledStatement(Token token, int labelCount) {
1868 debugEvent("beginLabeledStatement"); 1880 debugEvent("beginLabeledStatement");
1869 List<Label> labels = popList(labelCount); 1881 List<Label> labels = popList(labelCount);
1870 enterLocalScope(); 1882 enterLocalScope();
1871 LabelTarget target = new LabelTarget(); 1883 LabelTarget target = new LabelTarget(member, token.charOffset);
1872 for (Label label in labels) { 1884 for (Label label in labels) {
1873 scope[label.name] = target; 1885 scope[label.name] = target;
1874 } 1886 }
1875 push(target); 1887 push(target);
1876 } 1888 }
1877 1889
1878 @override 1890 @override
1879 void endLabeledStatement(int labelCount) { 1891 void endLabeledStatement(int labelCount) {
1880 debugEvent("LabeledStatement"); 1892 debugEvent("LabeledStatement");
1881 Statement statement = popStatement(); 1893 Statement statement = popStatement();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1946 void endYieldStatement(Token yieldToken, Token starToken, Token endToken) { 1958 void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
1947 debugEvent("YieldStatement"); 1959 debugEvent("YieldStatement");
1948 push(new YieldStatement(popForValue(), isYieldStar: starToken != null)); 1960 push(new YieldStatement(popForValue(), isYieldStar: starToken != null));
1949 } 1961 }
1950 1962
1951 @override 1963 @override
1952 void beginSwitchBlock(Token token) { 1964 void beginSwitchBlock(Token token) {
1953 debugEvent("beginSwitchBlock"); 1965 debugEvent("beginSwitchBlock");
1954 enterLocalScope(); 1966 enterLocalScope();
1955 enterSwitchScope(); 1967 enterSwitchScope();
1956 enterBreakTarget(); 1968 enterBreakTarget(token.charOffset);
1957 } 1969 }
1958 1970
1959 @override 1971 @override
1960 void beginSwitchCase(int labelCount, int expressionCount, Token firstToken) { 1972 void beginSwitchCase(int labelCount, int expressionCount, Token firstToken) {
1961 debugEvent("beginSwitchCase"); 1973 debugEvent("beginSwitchCase");
1962 List labelsAndExpressions = popList(labelCount + expressionCount); 1974 List labelsAndExpressions = popList(labelCount + expressionCount);
1963 List<Label> labels = <Label>[]; 1975 List<Label> labels = <Label>[];
1964 List<Expression> expressions = <Expression>[]; 1976 List<Expression> expressions = <Expression>[];
1965 if (labelsAndExpressions != null) { 1977 if (labelsAndExpressions != null) {
1966 for (var labelOrExpression in labelsAndExpressions) { 1978 for (var labelOrExpression in labelsAndExpressions) {
1967 if (labelOrExpression is Label) { 1979 if (labelOrExpression is Label) {
1968 labels.add(labelOrExpression); 1980 labels.add(labelOrExpression);
1969 } else { 1981 } else {
1970 expressions.add(toValue(labelOrExpression)); 1982 expressions.add(toValue(labelOrExpression));
1971 } 1983 }
1972 } 1984 }
1973 } 1985 }
1974 assert(scope == switchScope); 1986 assert(scope == switchScope);
1975 for (Label label in labels) { 1987 for (Label label in labels) {
1976 Builder existing = scope.local[label.name]; 1988 Builder existing = scope.local[label.name];
1977 if (existing == null) { 1989 if (existing == null) {
1978 scope[label.name] = createGotoTarget(); 1990 scope[label.name] = createGotoTarget(firstToken.charOffset);
1979 } else { 1991 } else {
1980 // TODO(ahe): Should validate this is a goto target and not duplicated. 1992 // TODO(ahe): Should validate this is a goto target and not duplicated.
1981 } 1993 }
1982 } 1994 }
1983 push(expressions); 1995 push(expressions);
1984 push(labels); 1996 push(labels);
1985 enterLocalScope(); 1997 enterLocalScope();
1986 } 1998 }
1987 1999
1988 @override 2000 @override
(...skipping 21 matching lines...) Expand all
2010 2022
2011 @override 2023 @override
2012 void endSwitchBlock(int caseCount, Token beginToken, Token endToken) { 2024 void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
2013 debugEvent("SwitchBlock"); 2025 debugEvent("SwitchBlock");
2014 List<SwitchCase> cases = 2026 List<SwitchCase> cases =
2015 new List<SwitchCase>.filled(caseCount, null, growable: true); 2027 new List<SwitchCase>.filled(caseCount, null, growable: true);
2016 for (int i = caseCount - 1; i >= 0; i--) { 2028 for (int i = caseCount - 1; i >= 0; i--) {
2017 List<Label> labels = pop(); 2029 List<Label> labels = pop();
2018 SwitchCase current = cases[i] = pop(); 2030 SwitchCase current = cases[i] = pop();
2019 for (Label label in labels) { 2031 for (Label label in labels) {
2020 JumpTarget target = switchScope.lookup(label.name); 2032 JumpTarget target =
2033 switchScope.lookup(label.name, label.fileOffset, uri);
2021 if (target != null) { 2034 if (target != null) {
2022 target.resolveGotos(current); 2035 target.resolveGotos(current);
2023 } 2036 }
2024 } 2037 }
2025 // TODO(ahe): Validate that there's only one default and it's last. 2038 // TODO(ahe): Validate that there's only one default and it's last.
2026 } 2039 }
2027 JumpTarget target = exitBreakTarget(); 2040 JumpTarget target = exitBreakTarget();
2028 exitSwitchScope(); 2041 exitSwitchScope();
2029 exitLocalScope(); 2042 exitLocalScope();
2030 Expression expression = popForValue(); 2043 Expression expression = popForValue();
(...skipping 13 matching lines...) Expand all
2044 2057
2045 @override 2058 @override
2046 void handleBreakStatement( 2059 void handleBreakStatement(
2047 bool hasTarget, Token breakKeyword, Token endToken) { 2060 bool hasTarget, Token breakKeyword, Token endToken) {
2048 debugEvent("BreakStatement"); 2061 debugEvent("BreakStatement");
2049 var target = breakTarget; 2062 var target = breakTarget;
2050 String name; 2063 String name;
2051 if (hasTarget) { 2064 if (hasTarget) {
2052 Identifier identifier = pop(); 2065 Identifier identifier = pop();
2053 name = identifier.name; 2066 name = identifier.name;
2054 target = scope.lookup(identifier.name); 2067 target = scope.lookup(
2068 identifier.name, breakKeyword.next.charOffset, uri);
2055 } 2069 }
2056 if (target == null && name == null) { 2070 if (target == null && name == null) {
2057 push(compileTimeErrorInLoopOrSwitch = 2071 push(compileTimeErrorInLoopOrSwitch =
2058 buildCompileTimeErrorStatement( 2072 buildCompileTimeErrorStatement(
2059 "No target of break.", breakKeyword.charOffset)); 2073 "No target of break.", breakKeyword.charOffset));
2060 } else if (target == null || target is! JumpTarget 2074 } else if (target == null || target is! JumpTarget
2061 || !target.isBreakTarget) { 2075 || !target.isBreakTarget) {
2062 push(compileTimeErrorInLoopOrSwitch = 2076 push(compileTimeErrorInLoopOrSwitch =
2063 buildCompileTimeErrorStatement("Can't break to '$name'.", 2077 buildCompileTimeErrorStatement("Can't break to '$name'.",
2064 breakKeyword.next.charOffset)); 2078 breakKeyword.next.charOffset));
2065 } else { 2079 } else {
2066 BreakStatement statement = new BreakStatement(null); 2080 BreakStatement statement = new BreakStatement(null);
2067 target.addBreak(statement); 2081 target.addBreak(statement);
2068 push(statement); 2082 push(statement);
2069 } 2083 }
2070 } 2084 }
2071 2085
2072 @override 2086 @override
2073 void handleContinueStatement( 2087 void handleContinueStatement(
2074 bool hasTarget, Token continueKeyword, Token endToken) { 2088 bool hasTarget, Token continueKeyword, Token endToken) {
2075 debugEvent("ContinueStatement"); 2089 debugEvent("ContinueStatement");
2076 var target = continueTarget; 2090 var target = continueTarget;
2077 String name; 2091 String name;
2078 if (hasTarget) { 2092 if (hasTarget) {
2079 Identifier identifier = pop(); 2093 Identifier identifier = pop();
2080 name = identifier.name; 2094 name = identifier.name;
2081 target = scope.lookup(identifier.name); 2095 target = scope.lookup(
2096 identifier.name, continueKeyword.next.charOffset, uri);
2082 if (target != null && target is! JumpTarget) { 2097 if (target != null && target is! JumpTarget) {
2083 push(compileTimeErrorInLoopOrSwitch = 2098 push(compileTimeErrorInLoopOrSwitch =
2084 buildCompileTimeErrorStatement( 2099 buildCompileTimeErrorStatement(
2085 "Target of continue must be a label.", 2100 "Target of continue must be a label.",
2086 continueKeyword.charOffset)); 2101 continueKeyword.charOffset));
2087 return; 2102 return;
2088 } 2103 }
2089 if (target == null) { 2104 if (target == null) {
2090 if (switchScope == null) { 2105 if (switchScope == null) {
2091 push(buildCompileTimeErrorStatement("Can't find label '$name'.", 2106 push(buildCompileTimeErrorStatement("Can't find label '$name'.",
2092 continueKeyword.next.charOffset)); 2107 continueKeyword.next.charOffset));
2093 return; 2108 return;
2094 } 2109 }
2095 switchScope[identifier.name] = target = createGotoTarget(); 2110 switchScope[identifier.name] = target =
2111 createGotoTarget(identifier.fileOffset);
2096 } 2112 }
2097 if (target.isGotoTarget) { 2113 if (target.isGotoTarget) {
2098 ContinueSwitchStatement statement = new ContinueSwitchStatement(null); 2114 ContinueSwitchStatement statement = new ContinueSwitchStatement(null);
2099 target.addGoto(statement); 2115 target.addGoto(statement);
2100 push(statement); 2116 push(statement);
2101 return; 2117 return;
2102 } 2118 }
2103 } 2119 }
2104 if (target == null) { 2120 if (target == null) {
2105 push(compileTimeErrorInLoopOrSwitch = 2121 push(compileTimeErrorInLoopOrSwitch =
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
2478 return accessor.buildPostfixIncrement(binaryOperator, voidContext: true, 2494 return accessor.buildPostfixIncrement(binaryOperator, voidContext: true,
2479 interfaceTarget: interfaceTarget); 2495 interfaceTarget: interfaceTarget);
2480 } 2496 }
2481 } 2497 }
2482 2498
2483 class JumpTarget extends Builder { 2499 class JumpTarget extends Builder {
2484 final List<Statement> users = <Statement>[]; 2500 final List<Statement> users = <Statement>[];
2485 2501
2486 final JumpTargetKind kind; 2502 final JumpTargetKind kind;
2487 2503
2488 JumpTarget(this.kind); 2504 JumpTarget(this.kind, MemberBuilder member, int charOffset)
2505 : super(member, charOffset, member.fileUri);
2489 2506
2490 bool get isBreakTarget => kind == JumpTargetKind.Break; 2507 bool get isBreakTarget => kind == JumpTargetKind.Break;
2491 2508
2492 bool get isContinueTarget => kind == JumpTargetKind.Continue; 2509 bool get isContinueTarget => kind == JumpTargetKind.Continue;
2493 2510
2494 bool get isGotoTarget => kind == JumpTargetKind.Goto; 2511 bool get isGotoTarget => kind == JumpTargetKind.Goto;
2495 2512
2496 bool get hasUsers => users.isNotEmpty; 2513 bool get hasUsers => users.isNotEmpty;
2497 2514
2498 void addBreak(BreakStatement statement) { 2515 void addBreak(BreakStatement statement) {
(...skipping 30 matching lines...) Expand all
2529 void resolveGotos(SwitchCase target) { 2546 void resolveGotos(SwitchCase target) {
2530 assert(isGotoTarget); 2547 assert(isGotoTarget);
2531 for (ContinueSwitchStatement user in users) { 2548 for (ContinueSwitchStatement user in users) {
2532 user.target = target; 2549 user.target = target;
2533 } 2550 }
2534 users.clear(); 2551 users.clear();
2535 } 2552 }
2536 } 2553 }
2537 2554
2538 class LabelTarget extends Builder implements JumpTarget { 2555 class LabelTarget extends Builder implements JumpTarget {
2539 final JumpTarget breakTarget = new JumpTarget(JumpTargetKind.Break); 2556 final JumpTarget breakTarget;
2540 2557
2541 final JumpTarget continueTarget = new JumpTarget(JumpTargetKind.Continue); 2558 final JumpTarget continueTarget;
2542 2559
2543 LabelTarget(); 2560 LabelTarget(MemberBuilder member, int charOffset)
2561 : breakTarget = new JumpTarget(JumpTargetKind.Break, member, charOffset),
2562 continueTarget =
2563 new JumpTarget(JumpTargetKind.Continue, member, charOffset),
2564 super(member, charOffset, member.fileUri);
2544 2565
2545 bool get hasUsers => breakTarget.hasUsers || continueTarget.hasUsers; 2566 bool get hasUsers => breakTarget.hasUsers || continueTarget.hasUsers;
2546 2567
2547 List<Statement> get users => internalError("Unsupported operation."); 2568 List<Statement> get users => internalError("Unsupported operation.");
2548 2569
2549 JumpTargetKind get kind => internalError("Unsupported operation."); 2570 JumpTargetKind get kind => internalError("Unsupported operation.");
2550 2571
2551 bool get isBreakTarget => true; 2572 bool get isBreakTarget => true;
2552 2573
2553 bool get isContinueTarget => true; 2574 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)); 2648 namedParameters.add(new NamedType(parameter.name, parameter.type));
2628 } 2649 }
2629 namedParameters.sort(); 2650 namedParameters.sort();
2630 } 2651 }
2631 } 2652 }
2632 return new FunctionType(positionalParameters, returnType, 2653 return new FunctionType(positionalParameters, returnType,
2633 namedParameters: namedParameters, 2654 namedParameters: namedParameters,
2634 requiredParameterCount: requiredParameterCount); 2655 requiredParameterCount: requiredParameterCount);
2635 } 2656 }
2636 2657
2637 Scope computeFormalParameterScope(Scope parent) { 2658 Scope computeFormalParameterScope(Scope parent, Builder builder) {
2638 if (required.length == 0 && optional == null) return parent; 2659 if (required.length == 0 && optional == null) return parent;
2639 Map<String, Builder> local = <String, Builder>{}; 2660 Map<String, Builder> local = <String, Builder>{};
2640 for (VariableDeclaration parameter in required) { 2661 for (VariableDeclaration parameter in required) {
2641 local[parameter.name] = new KernelVariableBuilder(parameter); 2662 local[parameter.name] = new KernelVariableBuilder(parameter, builder);
2642 } 2663 }
2643 if (optional != null) { 2664 if (optional != null) {
2644 for (VariableDeclaration parameter in optional.formals) { 2665 for (VariableDeclaration parameter in optional.formals) {
2645 local[parameter.name] = new KernelVariableBuilder(parameter); 2666 local[parameter.name] = new KernelVariableBuilder(parameter, builder);
2646 } 2667 }
2647 } 2668 }
2648 return new Scope(local, parent, isModifiable: false); 2669 return new Scope(local, parent, isModifiable: false);
2649 } 2670 }
2650 } 2671 }
2651 2672
2652 /// Returns a block like this: 2673 /// Returns a block like this:
2653 /// 2674 ///
2654 /// { 2675 /// {
2655 /// statement; 2676 /// statement;
(...skipping 24 matching lines...) Expand all
2680 } else if (node is TypeDeclarationBuilder) { 2701 } else if (node is TypeDeclarationBuilder) {
2681 return node.name; 2702 return node.name;
2682 } else if (node is PrefixBuilder) { 2703 } else if (node is PrefixBuilder) {
2683 return node.name; 2704 return node.name;
2684 } else if (node is ThisPropertyAccessor) { 2705 } else if (node is ThisPropertyAccessor) {
2685 return node.name.name; 2706 return node.name.name;
2686 } else { 2707 } else {
2687 return internalError("Unhandled: ${node.runtimeType}"); 2708 return internalError("Unhandled: ${node.runtimeType}");
2688 } 2709 }
2689 } 2710 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/import.dart ('k') | pkg/front_end/lib/src/fasta/kernel/builder_accessors.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698