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

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

Issue 2768533002: Fasta type inference prototype #2
Patch Set: Merge origin/master Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library fasta.body_builder; 5 library fasta.body_builder;
6 6
7 import '../parser/parser.dart' show FormalParameterType, optional; 7 import '../parser/parser.dart' show FormalParameterType, optional;
8 8
9 import '../parser/error_kind.dart' show ErrorKind; 9 import '../parser/error_kind.dart' show ErrorKind;
10 10
11 import '../parser/identifier_context.dart' show IdentifierContext; 11 import '../parser/identifier_context.dart' show IdentifierContext;
12 12
13 import 'package:front_end/src/fasta/builder/ast_factory.dart';
14 import 'package:front_end/src/fasta/kernel/ast_factory.dart' as kernel;
15 import 'package:front_end/src/fasta/type_inference/local_type_inferrer.dart';
16 import 'shadow_ast.dart' as shadow;
13 import 'package:kernel/ast.dart'; 17 import 'package:kernel/ast.dart';
14 18
15 import 'package:kernel/clone.dart' show CloneVisitor; 19 import 'package:kernel/clone.dart' show CloneVisitor;
16 20
17 import 'package:kernel/transformations/flags.dart' show TransformerFlag; 21 import 'package:kernel/transformations/flags.dart' show TransformerFlag;
18 22
19 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; 23 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
20 24
21 import 'package:kernel/core_types.dart' show CoreTypes; 25 import 'package:kernel/core_types.dart' show CoreTypes;
22 26
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 CloneVisitor cloner; 125 CloneVisitor cloner;
122 126
123 bool constantExpressionRequired = false; 127 bool constantExpressionRequired = false;
124 128
125 DartType currentLocalVariableType; 129 DartType currentLocalVariableType;
126 130
127 // Using non-null value to initialize this field based on performance advice 131 // Using non-null value to initialize this field based on performance advice
128 // from VM engineers. TODO(ahe): Does this still apply? 132 // from VM engineers. TODO(ahe): Does this still apply?
129 int currentLocalVariableModifiers = -1; 133 int currentLocalVariableModifiers = -1;
130 134
135 final AstFactory _ast = new kernel.AstFactory();
136
137 final LocalTypeInferrer _typeInferrer;
138
139 OldFunctionContext _functionContext;
140
131 BodyBuilder( 141 BodyBuilder(
132 KernelLibraryBuilder library, 142 KernelLibraryBuilder library,
133 this.member, 143 this.member,
134 Scope scope, 144 Scope scope,
135 this.formalParameterScope, 145 this.formalParameterScope,
136 this.hierarchy, 146 this.hierarchy,
137 this.coreTypes, 147 CoreTypes coreTypes,
138 this.classBuilder, 148 this.classBuilder,
139 this.isInstanceMember, 149 this.isInstanceMember,
140 this.uri) 150 this.uri)
141 : enclosingScope = scope, 151 : coreTypes = coreTypes,
152 enclosingScope = scope,
142 library = library, 153 library = library,
143 isDartLibrary = library.uri.scheme == "dart", 154 isDartLibrary = library.uri.scheme == "dart",
155 // TODO(paulberry): put this behind a flag.
156 _typeInferrer = new LocalTypeInferrer(coreTypes),
144 super(scope); 157 super(scope);
145 158
146 bool get hasParserError => recoverableErrors.isNotEmpty; 159 bool get hasParserError => recoverableErrors.isNotEmpty;
147 160
148 bool get inConstructor { 161 bool get inConstructor {
149 return functionNestingLevel == 0 && member is KernelConstructorBuilder; 162 return functionNestingLevel == 0 && member is KernelConstructorBuilder;
150 } 163 }
151 164
152 bool get isInstanceContext { 165 bool get isInstanceContext {
153 return isInstanceMember || member is KernelConstructorBuilder; 166 return isInstanceMember || member is KernelConstructorBuilder;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 } else { 220 } else {
208 return internalError("Unhandled: ${node.runtimeType}"); 221 return internalError("Unhandled: ${node.runtimeType}");
209 } 222 }
210 } 223 }
211 224
212 Expression toEffect(Object node) { 225 Expression toEffect(Object node) {
213 if (node is BuilderAccessor) return node.buildForEffect(); 226 if (node is BuilderAccessor) return node.buildForEffect();
214 return toValue(node); 227 return toValue(node);
215 } 228 }
216 229
217 List<Expression> popListForValue(int n) { 230 List<shadow.Expression> popListForValue(int n) {
218 List<Expression> list = 231 List<shadow.Expression> list =
219 new List<Expression>.filled(n, null, growable: true); 232 new List<shadow.Expression>.filled(n, null, growable: true);
220 for (int i = n - 1; i >= 0; i--) { 233 for (int i = n - 1; i >= 0; i--) {
221 list[i] = popForValue(); 234 list[i] = popForValue();
222 } 235 }
223 return list; 236 return list;
224 } 237 }
225 238
226 List<Expression> popListForEffect(int n) { 239 List<Expression> popListForEffect(int n) {
227 List<Expression> list = 240 List<Expression> list =
228 new List<Expression>.filled(n, null, growable: true); 241 new List<Expression>.filled(n, null, growable: true);
229 for (int i = n - 1; i >= 0; i--) { 242 for (int i = n - 1; i >= 0; i--) {
230 list[i] = popForEffect(); 243 list[i] = popForEffect();
231 } 244 }
232 return list; 245 return list;
233 } 246 }
234 247
235 Block popBlock(int count, int charOffset) { 248 shadow.Block popBlock(int count, int charOffset) {
236 List<dynamic /*Statement | List<Statement>*/ > statements = 249 List<dynamic /*Statement | List<Statement>*/ > statements =
237 popList(count) ?? <Statement>[]; 250 popList(count) ?? <Statement>[];
238 List<Statement> copy; 251 List<Statement> copy;
239 for (int i = 0; i < statements.length; i++) { 252 for (int i = 0; i < statements.length; i++) {
240 var statement = statements[i]; 253 var statement = statements[i];
241 if (statement is List) { 254 if (statement is List) {
242 copy ??= new List<Statement>.from(statements.getRange(0, i)); 255 copy ??= new List<Statement>.from(statements.getRange(0, i));
243 // TODO(sigmund): remove this assignment (issue #28651) 256 // TODO(sigmund): remove this assignment (issue #28651)
244 Iterable subStatements = statement; 257 Iterable subStatements = statement;
245 copy.addAll(subStatements); 258 copy.addAll(subStatements);
246 } else if (copy != null) { 259 } else if (copy != null) {
247 copy.add(statement); 260 copy.add(statement);
248 } 261 }
249 } 262 }
250 return new Block(copy ?? statements)..fileOffset = charOffset; 263 return _ast.block(copy ?? statements, charOffset);
251 } 264 }
252 265
253 Statement popStatementIfNotNull(Object value) { 266 Statement popStatementIfNotNull(Object value) {
254 return value == null ? null : popStatement(); 267 return value == null ? null : popStatement();
255 } 268 }
256 269
257 Statement popStatement() { 270 Statement popStatement() {
258 var statement = pop(); 271 var statement = pop();
259 if (statement is List) { 272 if (statement is List) {
260 return new Block(new List<Statement>.from(statement)); 273 return new Block(new List<Statement>.from(statement));
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 void handleNoInitializers() { 450 void handleNoInitializers() {
438 debugEvent("NoInitializers"); 451 debugEvent("NoInitializers");
439 } 452 }
440 453
441 @override 454 @override
442 void endInitializers(int count, Token beginToken, Token endToken) { 455 void endInitializers(int count, Token beginToken, Token endToken) {
443 debugEvent("Initializers"); 456 debugEvent("Initializers");
444 } 457 }
445 458
446 @override 459 @override
447 void finishFunction( 460 void finishFunction(FormalParameters formals, AsyncMarker asyncModifier,
448 FormalParameters formals, AsyncMarker asyncModifier, Statement body) { 461 shadow.Statement body) {
449 debugEvent("finishFunction"); 462 debugEvent("finishFunction");
450 KernelFunctionBuilder builder = member; 463 KernelFunctionBuilder builder = member;
451 if (builder is KernelConstructorBuilder) { 464 if (builder is KernelConstructorBuilder) {
452 if (asyncModifier != AsyncMarker.Sync) { 465 if (asyncModifier != AsyncMarker.Sync) {
453 // TODO(ahe): Change this to a null check. 466 // TODO(ahe): Change this to a null check.
454 addCompileTimeError(body?.fileOffset, 467 addCompileTimeError(body?.fileOffset,
455 "Can't be marked as ${asyncModifier}: ${builder.name}"); 468 "Can't be marked as ${asyncModifier}: ${builder.name}");
456 } 469 }
457 } else if (builder is KernelProcedureBuilder) { 470 } else if (builder is KernelProcedureBuilder) {
458 builder.asyncModifier = asyncModifier; 471 builder.asyncModifier = asyncModifier;
459 } else { 472 } else {
460 internalError("Unhandled: ${builder.runtimeType}"); 473 internalError("Unhandled: ${builder.runtimeType}");
461 } 474 }
475 _typeInferrer.inferBody(body);
462 builder.body = body; 476 builder.body = body;
463 if (formals?.optional != null) { 477 if (formals?.optional != null) {
464 Iterator<FormalParameterBuilder> formalBuilders = 478 Iterator<FormalParameterBuilder> formalBuilders =
465 builder.formals.skip(formals.required.length).iterator; 479 builder.formals.skip(formals.required.length).iterator;
466 for (VariableDeclaration parameter in formals.optional.formals) { 480 for (VariableDeclaration parameter in formals.optional.formals) {
467 bool hasMore = formalBuilders.moveNext(); 481 bool hasMore = formalBuilders.moveNext();
468 assert(hasMore); 482 assert(hasMore);
469 VariableDeclaration realParameter = formalBuilders.current.target; 483 VariableDeclaration realParameter = formalBuilders.current.target;
470 Expression initializer = parameter.initializer ?? new NullLiteral(); 484 Expression initializer = parameter.initializer ?? new NullLiteral();
471 realParameter.initializer = initializer..parent = realParameter; 485 realParameter.initializer = initializer..parent = realParameter;
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 expressions.add(part); 928 expressions.add(part);
915 } 929 }
916 } 930 }
917 } 931 }
918 push(new StringConcatenation(expressions ?? parts)); 932 push(new StringConcatenation(expressions ?? parts));
919 } 933 }
920 934
921 @override 935 @override
922 void handleLiteralInt(Token token) { 936 void handleLiteralInt(Token token) {
923 debugEvent("LiteralInt"); 937 debugEvent("LiteralInt");
924 push( 938 push(_ast.intLiteral(int.parse(token.lexeme), token.charOffset));
925 new IntLiteral(int.parse(token.lexeme))..fileOffset = token.charOffset);
926 } 939 }
927 940
928 @override 941 @override
929 void handleEmptyFunctionBody(Token semicolon) { 942 void handleEmptyFunctionBody(Token semicolon) {
930 debugEvent("ExpressionFunctionBody"); 943 debugEvent("ExpressionFunctionBody");
931 endBlockFunctionBody(0, null, semicolon); 944 endBlockFunctionBody(0, null, semicolon);
932 } 945 }
933 946
934 @override 947 @override
935 void handleExpressionFunctionBody(Token arrowToken, Token endToken) { 948 void handleExpressionFunctionBody(Token arrowToken, Token endToken) {
936 debugEvent("ExpressionFunctionBody"); 949 debugEvent("ExpressionFunctionBody");
937 endReturnStatement(true, arrowToken.next, endToken); 950 endReturnStatement(true, arrowToken.next, endToken);
938 } 951 }
939 952
940 @override 953 @override
941 void endReturnStatement( 954 void endReturnStatement(
942 bool hasExpression, Token beginToken, Token endToken) { 955 bool hasExpression, Token beginToken, Token endToken) {
943 debugEvent("ReturnStatement"); 956 debugEvent("ReturnStatement");
944 Expression expression = hasExpression ? popForValue() : null; 957 shadow.Expression expression = hasExpression ? popForValue() : null;
945 if (expression != null && inConstructor) { 958 if (expression != null && inConstructor) {
946 push(buildCompileTimeErrorStatement( 959 push(buildCompileTimeErrorStatement(
947 "Can't return from a constructor.", beginToken.charOffset)); 960 "Can't return from a constructor.", beginToken.charOffset));
948 } else { 961 } else {
949 push(new ReturnStatement(expression)..fileOffset = beginToken.charOffset); 962 push(_ast.returnStatement(expression, beginToken.charOffset));
963 _typeInferrer.recordReturnStatement(_functionContext, expression);
950 } 964 }
951 } 965 }
952 966
953 @override 967 @override
954 void endIfStatement(Token ifToken, Token elseToken) { 968 void endIfStatement(Token ifToken, Token elseToken) {
955 Statement elsePart = popStatementIfNotNull(elseToken); 969 Statement elsePart = popStatementIfNotNull(elseToken);
956 Statement thenPart = popStatement(); 970 Statement thenPart = popStatement();
957 Expression condition = popForValue(); 971 Expression condition = popForValue();
958 push(new IfStatement(condition, thenPart, elsePart)); 972 push(new IfStatement(condition, thenPart, elsePart));
959 } 973 }
960 974
961 @override 975 @override
962 void endVariableInitializer(Token assignmentOperator) { 976 void endVariableInitializer(Token assignmentOperator) {
963 debugEvent("VariableInitializer"); 977 debugEvent("VariableInitializer");
964 assert(assignmentOperator.stringValue == "="); 978 assert(assignmentOperator.stringValue == "=");
965 pushNewLocalVariable(popForValue(), 979 pushNewLocalVariable(popForValue(),
966 equalsCharOffset: assignmentOperator.charOffset); 980 equalsCharOffset: assignmentOperator.charOffset);
967 } 981 }
968 982
969 @override 983 @override
970 void handleNoVariableInitializer(Token token) { 984 void handleNoVariableInitializer(Token token) {
971 debugEvent("NoVariableInitializer"); 985 debugEvent("NoVariableInitializer");
972 pushNewLocalVariable(null); 986 pushNewLocalVariable(null);
973 } 987 }
974 988
975 void pushNewLocalVariable(Expression initializer, 989 void pushNewLocalVariable(shadow.Expression initializer,
976 {int equalsCharOffset: TreeNode.noOffset}) { 990 {int equalsCharOffset: TreeNode.noOffset}) {
977 Identifier identifier = pop(); 991 Identifier identifier = pop();
978 assert(currentLocalVariableModifiers != -1); 992 assert(currentLocalVariableModifiers != -1);
979 bool isConst = (currentLocalVariableModifiers & constMask) != 0; 993 bool isConst = (currentLocalVariableModifiers & constMask) != 0;
980 bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; 994 bool isFinal = (currentLocalVariableModifiers & finalMask) != 0;
981 assert(isConst == constantExpressionRequired); 995 assert(isConst == constantExpressionRequired);
982 push(new VariableDeclaration(identifier.name, 996 var variable = _ast.variableDeclaration(identifier.name,
983 initializer: initializer, 997 initializer: initializer,
984 type: currentLocalVariableType ?? const DynamicType(), 998 type: currentLocalVariableType,
985 isFinal: isFinal, 999 isFinal: isFinal,
986 isConst: isConst)..fileEqualsOffset = equalsCharOffset); 1000 isConst: isConst,
1001 charOffset: equalsCharOffset);
1002 _typeInferrer.finishVariableDeclaration(
1003 currentLocalVariableType, initializer, variable);
1004 push(variable);
987 } 1005 }
988 1006
989 @override 1007 @override
990 void endFieldInitializer(Token assignmentOperator) { 1008 void endFieldInitializer(Token assignmentOperator) {
991 debugEvent("FieldInitializer"); 1009 debugEvent("FieldInitializer");
992 assert(assignmentOperator.stringValue == "="); 1010 assert(assignmentOperator.stringValue == "=");
993 push(popForValue()); 1011 push(popForValue());
994 } 1012 }
995 1013
996 @override 1014 @override
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 void endAwaitExpression(Token beginToken, Token endToken) { 1154 void endAwaitExpression(Token beginToken, Token endToken) {
1137 debugEvent("AwaitExpression"); 1155 debugEvent("AwaitExpression");
1138 push( 1156 push(
1139 new AwaitExpression(popForValue())..fileOffset = beginToken.charOffset); 1157 new AwaitExpression(popForValue())..fileOffset = beginToken.charOffset);
1140 } 1158 }
1141 1159
1142 @override 1160 @override
1143 void handleAsyncModifier(Token asyncToken, Token starToken) { 1161 void handleAsyncModifier(Token asyncToken, Token starToken) {
1144 debugEvent("AsyncModifier"); 1162 debugEvent("AsyncModifier");
1145 push(asyncMarkerFromTokens(asyncToken, starToken)); 1163 push(asyncMarkerFromTokens(asyncToken, starToken));
1164 _functionContext?.recordAsyncModifier(asyncToken != null);
1146 } 1165 }
1147 1166
1148 @override 1167 @override
1149 void handleLiteralList( 1168 void handleLiteralList(
1150 int count, Token beginToken, Token constKeyword, Token endToken) { 1169 int count, Token beginToken, Token constKeyword, Token endToken) {
1151 debugEvent("LiteralList"); 1170 debugEvent("LiteralList");
1152 List<Expression> expressions = popListForValue(count); 1171 List<shadow.Expression> expressions = popListForValue(count);
1153 List<DartType> typeArguments = pop(); 1172 List<DartType> typeArguments = pop();
1154 DartType typeArgument = const DynamicType(); 1173 DartType typeArgument;
1155 if (typeArguments != null) { 1174 if (typeArguments != null) {
1156 typeArgument = typeArguments.first; 1175 typeArgument = typeArguments.first;
1157 if (typeArguments.length > 1) { 1176 if (typeArguments.length > 1) {
1158 typeArgument = const DynamicType(); 1177 typeArgument = null;
1159 warning( 1178 warning(
1160 "Too many type arguments on List literal.", beginToken.charOffset); 1179 "Too many type arguments on List literal.", beginToken.charOffset);
1161 } 1180 }
1162 } 1181 }
1163 push(new ListLiteral(expressions, 1182 push(_ast.listLiteral(expressions, typeArgument, constKeyword != null,
1164 typeArgument: typeArgument, isConst: constKeyword != null) 1183 constKeyword?.charOffset ?? beginToken.charOffset));
1165 ..fileOffset = constKeyword?.charOffset ?? beginToken.charOffset);
1166 } 1184 }
1167 1185
1168 @override 1186 @override
1169 void handleLiteralBool(Token token) { 1187 void handleLiteralBool(Token token) {
1170 debugEvent("LiteralBool"); 1188 debugEvent("LiteralBool");
1171 bool value = optional("true", token); 1189 bool value = optional("true", token);
1172 assert(value || optional("false", token)); 1190 assert(value || optional("false", token));
1173 push(new BoolLiteral(value)..fileOffset = token.charOffset); 1191 push(new BoolLiteral(value)..fileOffset = token.charOffset);
1174 } 1192 }
1175 1193
1176 @override 1194 @override
1177 void handleLiteralDouble(Token token) { 1195 void handleLiteralDouble(Token token) {
1178 debugEvent("LiteralDouble"); 1196 debugEvent("LiteralDouble");
1179 push(new DoubleLiteral(double.parse(token.lexeme)) 1197 push(new DoubleLiteral(double.parse(token.lexeme))
1180 ..fileOffset = token.charOffset); 1198 ..fileOffset = token.charOffset);
1181 } 1199 }
1182 1200
1183 @override 1201 @override
1184 void handleLiteralNull(Token token) { 1202 void handleLiteralNull(Token token) {
1185 debugEvent("LiteralNull"); 1203 debugEvent("LiteralNull");
1186 push(new NullLiteral()..fileOffset = token.charOffset); 1204 push(_ast.nullLiteral(token.charOffset));
1187 } 1205 }
1188 1206
1189 @override 1207 @override
1190 void handleLiteralMap( 1208 void handleLiteralMap(
1191 int count, Token beginToken, Token constKeyword, Token endToken) { 1209 int count, Token beginToken, Token constKeyword, Token endToken) {
1192 debugEvent("LiteralMap"); 1210 debugEvent("LiteralMap");
1193 List<MapEntry> entries = popList(count) ?? <MapEntry>[]; 1211 List<MapEntry> entries = popList(count) ?? <MapEntry>[];
1194 List<DartType> typeArguments = pop(); 1212 List<DartType> typeArguments = pop();
1195 DartType keyType = const DynamicType(); 1213 DartType keyType = const DynamicType();
1196 DartType valueType = const DynamicType(); 1214 DartType valueType = const DynamicType();
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1398 if (!inConstructor) { 1416 if (!inConstructor) {
1399 addCompileTimeError(thisKeyword.charOffset, 1417 addCompileTimeError(thisKeyword.charOffset,
1400 "'this' parameters can only be used on constructors."); 1418 "'this' parameters can only be used on constructors.");
1401 thisKeyword = null; 1419 thisKeyword = null;
1402 } 1420 }
1403 } 1421 }
1404 Identifier name = pop(); 1422 Identifier name = pop();
1405 DartType type = pop(); 1423 DartType type = pop();
1406 pop(); // Modifiers. 1424 pop(); // Modifiers.
1407 ignore(Unhandled.Metadata); 1425 ignore(Unhandled.Metadata);
1408 VariableDeclaration variable; 1426 shadow.VariableDeclaration variable;
1409 if (!inCatchClause && functionNestingLevel == 0) { 1427 if (!inCatchClause && functionNestingLevel == 0) {
1410 dynamic builder = formalParameterScope.lookup(name.name, charOffset, uri); 1428 dynamic builder = formalParameterScope.lookup(name.name, charOffset, uri);
1411 if (builder == null) { 1429 if (builder == null) {
1412 if (thisKeyword == null) { 1430 if (thisKeyword == null) {
1413 internalError("Internal error: formal missing for '${name.name}'"); 1431 internalError("Internal error: formal missing for '${name.name}'");
1414 } else { 1432 } else {
1415 addCompileTimeError(thisKeyword.charOffset, 1433 addCompileTimeError(thisKeyword.charOffset,
1416 "'${name.name}' isn't a field in this class."); 1434 "'${name.name}' isn't a field in this class.");
1417 thisKeyword = null; 1435 thisKeyword = null;
1418 } 1436 }
1419 } else if (thisKeyword == null) { 1437 } else if (thisKeyword == null) {
1420 variable = builder.build(library); 1438 variable = builder.build(library);
1421 variable.initializer = name.initializer; 1439 variable.initializer = name.initializer;
1422 } else if (builder.isField && builder.parent == classBuilder) { 1440 } else if (builder.isField && builder.parent == classBuilder) {
1423 FieldBuilder field = builder; 1441 FieldBuilder field = builder;
1424 if (type != null) { 1442 if (type != null) {
1425 nit("Ignoring type on 'this' parameter '${name.name}'.", 1443 nit("Ignoring type on 'this' parameter '${name.name}'.",
1426 thisKeyword.charOffset); 1444 thisKeyword.charOffset);
1427 } 1445 }
1428 type = field.target.type ?? const DynamicType(); 1446 type = field.target.type ?? const DynamicType();
1429 variable = new VariableDeclaration(name.name, 1447 variable = _ast.variableDeclaration(name.name,
1430 type: type, initializer: name.initializer); 1448 type: type,
1449 initializer: name.initializer as shadow.Expression,
1450 charOffset: name.fileOffset);
1431 } else { 1451 } else {
1432 addCompileTimeError( 1452 addCompileTimeError(
1433 name.fileOffset, "'${name.name}' isn't a field in this class."); 1453 name.fileOffset, "'${name.name}' isn't a field in this class.");
1434 } 1454 }
1435 } 1455 }
1436 variable ??= new VariableDeclaration(name.name, 1456 variable ??= _ast.variableDeclaration(name.name,
1437 type: type ?? const DynamicType(), 1457 type: type,
1438 initializer: name.initializer)..fileOffset = name.fileOffset; 1458 initializer: name.initializer as shadow.Expression,
1459 charOffset: name.fileOffset);
1439 push(variable); 1460 push(variable);
1440 } 1461 }
1441 1462
1442 @override 1463 @override
1443 void endOptionalFormalParameters( 1464 void endOptionalFormalParameters(
1444 int count, Token beginToken, Token endToken) { 1465 int count, Token beginToken, Token endToken) {
1445 debugEvent("OptionalFormalParameters"); 1466 debugEvent("OptionalFormalParameters");
1446 FormalParameterType kind = optional("{", beginToken) 1467 FormalParameterType kind = optional("{", beginToken)
1447 ? FormalParameterType.NAMED 1468 ? FormalParameterType.NAMED
1448 : FormalParameterType.POSITIONAL; 1469 : FormalParameterType.POSITIONAL;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 } 1515 }
1495 FormalParameters formals = new FormalParameters( 1516 FormalParameters formals = new FormalParameters(
1496 popList(count) ?? <VariableDeclaration>[], 1517 popList(count) ?? <VariableDeclaration>[],
1497 optional, 1518 optional,
1498 beginToken.charOffset); 1519 beginToken.charOffset);
1499 push(formals); 1520 push(formals);
1500 if (inCatchClause || functionNestingLevel != 0) { 1521 if (inCatchClause || functionNestingLevel != 0) {
1501 enterLocalScope(formals.computeFormalParameterScope( 1522 enterLocalScope(formals.computeFormalParameterScope(
1502 scope, member ?? classBuilder ?? library)); 1523 scope, member ?? classBuilder ?? library));
1503 } 1524 }
1525 formals.recordTypeInferenceTo(_functionContext);
1504 } 1526 }
1505 1527
1506 @override 1528 @override
1507 void beginCatchClause(Token token) { 1529 void beginCatchClause(Token token) {
1508 debugEvent("beginCatchClause"); 1530 debugEvent("beginCatchClause");
1509 inCatchClause = true; 1531 inCatchClause = true;
1510 } 1532 }
1511 1533
1512 @override 1534 @override
1513 void endCatchClause(Token token) { 1535 void endCatchClause(Token token) {
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
1871 VariableDeclaration variable = 1893 VariableDeclaration variable =
1872 new VariableDeclaration(name.name, isFinal: true); 1894 new VariableDeclaration(name.name, isFinal: true);
1873 push(new FunctionDeclaration( 1895 push(new FunctionDeclaration(
1874 variable, new FunctionNode(new InvalidStatement())) 1896 variable, new FunctionNode(new InvalidStatement()))
1875 ..fileOffset = beginToken.charOffset); 1897 ..fileOffset = beginToken.charOffset);
1876 scope[variable.name] = new KernelVariableBuilder( 1898 scope[variable.name] = new KernelVariableBuilder(
1877 variable, member ?? classBuilder ?? library, uri); 1899 variable, member ?? classBuilder ?? library, uri);
1878 enterLocalScope(); 1900 enterLocalScope();
1879 } 1901 }
1880 1902
1881 void enterFunction() { 1903 void enterFunction(bool isNamed) {
1882 debugEvent("enterFunction"); 1904 debugEvent("enterFunction");
1883 functionNestingLevel++; 1905 functionNestingLevel++;
1884 push(switchScope ?? NullValue.SwitchScope); 1906 push(switchScope ?? NullValue.SwitchScope);
1885 switchScope = null; 1907 switchScope = null;
1908 _functionContext = _typeInferrer.nestFunctionContext(_functionContext);
1886 } 1909 }
1887 1910
1888 void exitFunction() { 1911 void exitFunction() {
1889 debugEvent("exitFunction"); 1912 debugEvent("exitFunction");
1890 functionNestingLevel--; 1913 functionNestingLevel--;
1891 switchScope = pop(); 1914 switchScope = pop();
1892 } 1915 }
1893 1916
1894 @override 1917 @override
1895 void beginFunction(Token token) { 1918 void beginFunction(Token token) {
1896 debugEvent("beginFunction"); 1919 debugEvent("beginFunction");
1897 enterFunction(); 1920 enterFunction(true);
1898 } 1921 }
1899 1922
1900 @override 1923 @override
1901 void beginUnnamedFunction(Token token) { 1924 void beginUnnamedFunction(Token token) {
1902 debugEvent("beginUnnamedFunction"); 1925 debugEvent("beginUnnamedFunction");
1903 enterFunction(); 1926 enterFunction(false);
1904 } 1927 }
1905 1928
1906 @override 1929 @override
1907 void endFunction(Token getOrSet, Token endToken) { 1930 void endFunction(Token getOrSet, Token endToken) {
1908 debugEvent("Function"); 1931 debugEvent("Function");
1909 Statement body = popStatement(); 1932 Statement body = popStatement();
1910 AsyncMarker asyncModifier = pop(); 1933 AsyncMarker asyncModifier = pop();
1911 if (functionNestingLevel != 0) { 1934 if (functionNestingLevel != 0) {
1912 exitLocalScope(); 1935 exitLocalScope();
1913 } 1936 }
(...skipping 25 matching lines...) Expand all
1939 Statement body = popStatement(); 1962 Statement body = popStatement();
1940 AsyncMarker asyncModifier = pop(); 1963 AsyncMarker asyncModifier = pop();
1941 exitLocalScope(); 1964 exitLocalScope();
1942 FormalParameters formals = pop(); 1965 FormalParameters formals = pop();
1943 exitFunction(); 1966 exitFunction();
1944 List<TypeParameter> typeParameters = pop(); 1967 List<TypeParameter> typeParameters = pop();
1945 FunctionNode function = formals.addToFunction(new FunctionNode(body, 1968 FunctionNode function = formals.addToFunction(new FunctionNode(body,
1946 typeParameters: typeParameters, asyncMarker: asyncModifier) 1969 typeParameters: typeParameters, asyncMarker: asyncModifier)
1947 ..fileOffset = beginToken.charOffset 1970 ..fileOffset = beginToken.charOffset
1948 ..fileEndOffset = token.charOffset); 1971 ..fileEndOffset = token.charOffset);
1949 push(new FunctionExpression(function)..fileOffset = beginToken.charOffset); 1972 push(new shadow.FunctionExpression(function)
1973 ..fileOffset = beginToken.charOffset);
1950 } 1974 }
1951 1975
1952 @override 1976 @override
1953 void endDoWhileStatement( 1977 void endDoWhileStatement(
1954 Token doKeyword, Token whileKeyword, Token endToken) { 1978 Token doKeyword, Token whileKeyword, Token endToken) {
1955 debugEvent("DoWhileStatement"); 1979 debugEvent("DoWhileStatement");
1956 Expression condition = popForValue(); 1980 Expression condition = popForValue();
1957 Statement body = popStatement(); 1981 Statement body = popStatement();
1958 JumpTarget continueTarget = exitContinueTarget(); 1982 JumpTarget continueTarget = exitContinueTarget();
1959 JumpTarget breakTarget = exitBreakTarget(); 1983 JumpTarget breakTarget = exitBreakTarget();
(...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after
2830 new KernelVariableBuilder(parameter, builder, builder.fileUri); 2854 new KernelVariableBuilder(parameter, builder, builder.fileUri);
2831 } 2855 }
2832 if (optional != null) { 2856 if (optional != null) {
2833 for (VariableDeclaration parameter in optional.formals) { 2857 for (VariableDeclaration parameter in optional.formals) {
2834 local[parameter.name] = 2858 local[parameter.name] =
2835 new KernelVariableBuilder(parameter, builder, builder.fileUri); 2859 new KernelVariableBuilder(parameter, builder, builder.fileUri);
2836 } 2860 }
2837 } 2861 }
2838 return new Scope(local, parent, isModifiable: false); 2862 return new Scope(local, parent, isModifiable: false);
2839 } 2863 }
2864
2865 void recordTypeInferenceTo(OldFunctionContext functionContext) {
2866 if (functionContext == null) return;
2867 int requiredParameterCount = required.length;
2868 var positionalFormals = <shadow.VariableDeclaration>[];
2869 var namedFormals = const <shadow.VariableDeclaration>[];
2870 for (VariableDeclaration parameter in required) {
2871 positionalFormals.add(parameter);
2872 }
2873 if (optional != null) {
2874 throw new UnimplementedError();
2875 }
2876 functionContext.recordFormals(
2877 requiredParameterCount, positionalFormals, namedFormals);
2878 }
2840 } 2879 }
2841 2880
2842 /// Returns a block like this: 2881 /// Returns a block like this:
2843 /// 2882 ///
2844 /// { 2883 /// {
2845 /// statement; 2884 /// statement;
2846 /// body; 2885 /// body;
2847 /// } 2886 /// }
2848 /// 2887 ///
2849 /// If [body] is a [Block], it's returned with [statement] prepended to it. 2888 /// If [body] is a [Block], it's returned with [statement] prepended to it.
(...skipping 22 matching lines...) Expand all
2872 } else if (node is PrefixBuilder) { 2911 } else if (node is PrefixBuilder) {
2873 return node.name; 2912 return node.name;
2874 } else if (node is ThisAccessor) { 2913 } else if (node is ThisAccessor) {
2875 return node.isSuper ? "super" : "this"; 2914 return node.isSuper ? "super" : "this";
2876 } else if (node is BuilderAccessor) { 2915 } else if (node is BuilderAccessor) {
2877 return node.plainNameForRead; 2916 return node.plainNameForRead;
2878 } else { 2917 } else {
2879 return internalError("Unhandled: ${node.runtimeType}"); 2918 return internalError("Unhandled: ${node.runtimeType}");
2880 } 2919 }
2881 } 2920 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698