| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |