| 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 '../fasta_codes.dart' | 7 import '../fasta_codes.dart' |
| 8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; | 8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; |
| 9 | 9 |
| 10 import '../parser/parser.dart' show FormalParameterType, optional; | 10 import '../parser/parser.dart' show FormalParameterType, optional; |
| 11 | 11 |
| 12 import '../parser/identifier_context.dart' show IdentifierContext; | 12 import '../parser/identifier_context.dart' show IdentifierContext; |
| 13 | 13 |
| 14 import 'package:front_end/src/fasta/builder/ast_factory.dart' show AstFactory; |
| 15 |
| 14 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart' | 16 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart' |
| 15 show KernelVariableDeclaration; | 17 show KernelVariableDeclaration; |
| 16 | 18 |
| 17 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart' | 19 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart' |
| 18 show TypeInferrer; | 20 show TypeInferrer; |
| 19 | 21 |
| 20 import 'package:kernel/ast.dart'; | 22 import 'package:kernel/ast.dart'; |
| 21 | 23 |
| 22 import 'package:kernel/clone.dart' show CloneVisitor; | 24 import 'package:kernel/clone.dart' show CloneVisitor; |
| 23 | 25 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 final Scope enclosingScope; | 83 final Scope enclosingScope; |
| 82 | 84 |
| 83 final bool isDartLibrary; | 85 final bool isDartLibrary; |
| 84 | 86 |
| 85 @override | 87 @override |
| 86 final Uri uri; | 88 final Uri uri; |
| 87 | 89 |
| 88 final TypeInferrer<Statement, Expression, KernelVariableDeclaration, Field> | 90 final TypeInferrer<Statement, Expression, KernelVariableDeclaration, Field> |
| 89 _typeInferrer; | 91 _typeInferrer; |
| 90 | 92 |
| 93 final AstFactory astFactory; |
| 94 |
| 91 /// Only used when [member] is a constructor. It tracks if an implicit super | 95 /// Only used when [member] is a constructor. It tracks if an implicit super |
| 92 /// initializer is needed. | 96 /// initializer is needed. |
| 93 /// | 97 /// |
| 94 /// An implicit super initializer isn't needed | 98 /// An implicit super initializer isn't needed |
| 95 /// | 99 /// |
| 96 /// 1. if the current class is Object, | 100 /// 1. if the current class is Object, |
| 97 /// 2. if there is an explicit super initializer, | 101 /// 2. if there is an explicit super initializer, |
| 98 /// 3. if there is a redirecting (this) initializer, or | 102 /// 3. if there is a redirecting (this) initializer, or |
| 99 /// 4. if a compile-time error prevented us from generating code for an | 103 /// 4. if a compile-time error prevented us from generating code for an |
| 100 /// initializer. This avoids cascading errors. | 104 /// initializer. This avoids cascading errors. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 129 BodyBuilder( | 133 BodyBuilder( |
| 130 KernelLibraryBuilder library, | 134 KernelLibraryBuilder library, |
| 131 this.member, | 135 this.member, |
| 132 Scope scope, | 136 Scope scope, |
| 133 this.formalParameterScope, | 137 this.formalParameterScope, |
| 134 this.hierarchy, | 138 this.hierarchy, |
| 135 this.coreTypes, | 139 this.coreTypes, |
| 136 this.classBuilder, | 140 this.classBuilder, |
| 137 this.isInstanceMember, | 141 this.isInstanceMember, |
| 138 this.uri, | 142 this.uri, |
| 139 this._typeInferrer) | 143 this._typeInferrer, |
| 144 this.astFactory) |
| 140 : enclosingScope = scope, | 145 : enclosingScope = scope, |
| 141 library = library, | 146 library = library, |
| 142 isDartLibrary = library.uri.scheme == "dart", | 147 isDartLibrary = library.uri.scheme == "dart", |
| 143 needsImplicitSuperInitializer = | 148 needsImplicitSuperInitializer = |
| 144 coreTypes.objectClass != classBuilder?.cls, | 149 coreTypes.objectClass != classBuilder?.cls, |
| 145 super(scope); | 150 super(scope); |
| 146 | 151 |
| 147 bool get hasParserError => recoverableErrors.isNotEmpty; | 152 bool get hasParserError => recoverableErrors.isNotEmpty; |
| 148 | 153 |
| 149 bool get inConstructor { | 154 bool get inConstructor { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 var statement = statements[i]; | 235 var statement = statements[i]; |
| 231 if (statement is List) { | 236 if (statement is List) { |
| 232 copy ??= new List<Statement>.from(statements.getRange(0, i)); | 237 copy ??= new List<Statement>.from(statements.getRange(0, i)); |
| 233 // TODO(sigmund): remove this assignment (issue #28651) | 238 // TODO(sigmund): remove this assignment (issue #28651) |
| 234 Iterable subStatements = statement; | 239 Iterable subStatements = statement; |
| 235 copy.addAll(subStatements); | 240 copy.addAll(subStatements); |
| 236 } else if (copy != null) { | 241 } else if (copy != null) { |
| 237 copy.add(statement); | 242 copy.add(statement); |
| 238 } | 243 } |
| 239 } | 244 } |
| 240 return new Block(copy ?? statements)..fileOffset = charOffset; | 245 return astFactory.block(copy ?? statements, charOffset); |
| 241 } | 246 } |
| 242 | 247 |
| 243 Statement popStatementIfNotNull(Object value) { | 248 Statement popStatementIfNotNull(Object value) { |
| 244 return value == null ? null : popStatement(); | 249 return value == null ? null : popStatement(); |
| 245 } | 250 } |
| 246 | 251 |
| 247 Statement popStatement() { | 252 Statement popStatement() { |
| 248 var statement = pop(); | 253 var statement = pop(); |
| 249 if (statement is List) { | 254 if (statement is List) { |
| 250 return new Block(new List<Statement>.from(statement)); | 255 return new Block(new List<Statement>.from(statement)); |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 | 439 |
| 435 @override | 440 @override |
| 436 void endInitializers(int count, Token beginToken, Token endToken) { | 441 void endInitializers(int count, Token beginToken, Token endToken) { |
| 437 debugEvent("Initializers"); | 442 debugEvent("Initializers"); |
| 438 } | 443 } |
| 439 | 444 |
| 440 @override | 445 @override |
| 441 void finishFunction( | 446 void finishFunction( |
| 442 FormalParameters formals, AsyncMarker asyncModifier, Statement body) { | 447 FormalParameters formals, AsyncMarker asyncModifier, Statement body) { |
| 443 debugEvent("finishFunction"); | 448 debugEvent("finishFunction"); |
| 444 _typeInferrer.inferBody(body, uri); | 449 _typeInferrer?.inferBody(body, uri); |
| 445 KernelFunctionBuilder builder = member; | 450 KernelFunctionBuilder builder = member; |
| 446 builder.body = body; | 451 builder.body = body; |
| 447 if (formals?.optional != null) { | 452 if (formals?.optional != null) { |
| 448 Iterator<FormalParameterBuilder> formalBuilders = | 453 Iterator<FormalParameterBuilder> formalBuilders = |
| 449 builder.formals.skip(formals.required.length).iterator; | 454 builder.formals.skip(formals.required.length).iterator; |
| 450 for (VariableDeclaration parameter in formals.optional.formals) { | 455 for (VariableDeclaration parameter in formals.optional.formals) { |
| 451 bool hasMore = formalBuilders.moveNext(); | 456 bool hasMore = formalBuilders.moveNext(); |
| 452 assert(hasMore); | 457 assert(hasMore); |
| 453 VariableDeclaration realParameter = formalBuilders.current.target; | 458 VariableDeclaration realParameter = formalBuilders.current.target; |
| 454 Expression initializer = parameter.initializer ?? new NullLiteral(); | 459 Expression initializer = parameter.initializer ?? new NullLiteral(); |
| (...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 expressions.add(part); | 980 expressions.add(part); |
| 976 } | 981 } |
| 977 } | 982 } |
| 978 } | 983 } |
| 979 push(new StringConcatenation(expressions ?? parts)); | 984 push(new StringConcatenation(expressions ?? parts)); |
| 980 } | 985 } |
| 981 | 986 |
| 982 @override | 987 @override |
| 983 void handleLiteralInt(Token token) { | 988 void handleLiteralInt(Token token) { |
| 984 debugEvent("LiteralInt"); | 989 debugEvent("LiteralInt"); |
| 985 push( | 990 push(astFactory.intLiteral(int.parse(token.lexeme), token.charOffset)); |
| 986 new IntLiteral(int.parse(token.lexeme))..fileOffset = token.charOffset); | |
| 987 } | 991 } |
| 988 | 992 |
| 989 @override | 993 @override |
| 990 void handleEmptyFunctionBody(Token semicolon) { | 994 void handleEmptyFunctionBody(Token semicolon) { |
| 991 debugEvent("ExpressionFunctionBody"); | 995 debugEvent("ExpressionFunctionBody"); |
| 992 endBlockFunctionBody(0, null, semicolon); | 996 endBlockFunctionBody(0, null, semicolon); |
| 993 } | 997 } |
| 994 | 998 |
| 995 @override | 999 @override |
| 996 void handleExpressionFunctionBody(Token arrowToken, Token endToken) { | 1000 void handleExpressionFunctionBody(Token arrowToken, Token endToken) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1033 pushNewLocalVariable(null); | 1037 pushNewLocalVariable(null); |
| 1034 } | 1038 } |
| 1035 | 1039 |
| 1036 void pushNewLocalVariable(Expression initializer, | 1040 void pushNewLocalVariable(Expression initializer, |
| 1037 {int equalsCharOffset: TreeNode.noOffset}) { | 1041 {int equalsCharOffset: TreeNode.noOffset}) { |
| 1038 Identifier identifier = pop(); | 1042 Identifier identifier = pop(); |
| 1039 assert(currentLocalVariableModifiers != -1); | 1043 assert(currentLocalVariableModifiers != -1); |
| 1040 bool isConst = (currentLocalVariableModifiers & constMask) != 0; | 1044 bool isConst = (currentLocalVariableModifiers & constMask) != 0; |
| 1041 bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; | 1045 bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; |
| 1042 assert(isConst == constantExpressionRequired); | 1046 assert(isConst == constantExpressionRequired); |
| 1043 push(new VariableDeclaration(identifier.name, | 1047 push(astFactory.variableDeclaration(identifier.name, |
| 1044 initializer: initializer, | 1048 initializer: initializer, |
| 1045 type: currentLocalVariableType ?? const DynamicType(), | 1049 type: currentLocalVariableType, |
| 1046 isFinal: isFinal, | 1050 isFinal: isFinal, |
| 1047 isConst: isConst) | 1051 isConst: isConst, |
| 1048 ..fileEqualsOffset = equalsCharOffset); | 1052 equalsCharOffset: equalsCharOffset)); |
| 1049 } | 1053 } |
| 1050 | 1054 |
| 1051 @override | 1055 @override |
| 1052 void endFieldInitializer(Token assignmentOperator) { | 1056 void endFieldInitializer(Token assignmentOperator) { |
| 1053 debugEvent("FieldInitializer"); | 1057 debugEvent("FieldInitializer"); |
| 1054 assert(assignmentOperator.stringValue == "="); | 1058 assert(assignmentOperator.stringValue == "="); |
| 1055 push(popForValue()); | 1059 push(popForValue()); |
| 1056 } | 1060 } |
| 1057 | 1061 |
| 1058 @override | 1062 @override |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1497 } else if (thisKeyword == null) { | 1501 } else if (thisKeyword == null) { |
| 1498 variable = builder.build(library); | 1502 variable = builder.build(library); |
| 1499 variable.initializer = name.initializer; | 1503 variable.initializer = name.initializer; |
| 1500 } else if (builder.isField && builder.parent == classBuilder) { | 1504 } else if (builder.isField && builder.parent == classBuilder) { |
| 1501 FieldBuilder field = builder; | 1505 FieldBuilder field = builder; |
| 1502 if (type != null) { | 1506 if (type != null) { |
| 1503 nit("Ignoring type on 'this' parameter '${name.name}'.", | 1507 nit("Ignoring type on 'this' parameter '${name.name}'.", |
| 1504 thisKeyword.charOffset); | 1508 thisKeyword.charOffset); |
| 1505 } | 1509 } |
| 1506 type = field.target.type ?? const DynamicType(); | 1510 type = field.target.type ?? const DynamicType(); |
| 1507 variable = new VariableDeclaration(name.name, | 1511 variable = astFactory.variableDeclaration(name.name, |
| 1508 type: type, | 1512 type: type, |
| 1509 initializer: name.initializer, | 1513 initializer: name.initializer, |
| 1510 isFinal: isFinal, | 1514 isFinal: isFinal, |
| 1511 isConst: isConst) | 1515 isConst: isConst, |
| 1512 ..fileOffset = name.fileOffset; | 1516 charOffset: name.fileOffset); |
| 1513 } else { | 1517 } else { |
| 1514 addCompileTimeError( | 1518 addCompileTimeError( |
| 1515 name.fileOffset, "'${name.name}' isn't a field in this class."); | 1519 name.fileOffset, "'${name.name}' isn't a field in this class."); |
| 1516 } | 1520 } |
| 1517 } | 1521 } |
| 1518 variable ??= new VariableDeclaration(name.name, | 1522 variable ??= astFactory.variableDeclaration(name.name, |
| 1519 type: type ?? const DynamicType(), | 1523 type: type ?? const DynamicType(), |
| 1520 initializer: name.initializer, | 1524 initializer: name.initializer, |
| 1521 isFinal: isFinal, | 1525 isFinal: isFinal, |
| 1522 isConst: isConst) | 1526 isConst: isConst, |
| 1523 ..fileOffset = name.fileOffset; | 1527 charOffset: name.fileOffset); |
| 1524 push(variable); | 1528 push(variable); |
| 1525 } | 1529 } |
| 1526 | 1530 |
| 1527 @override | 1531 @override |
| 1528 void endOptionalFormalParameters( | 1532 void endOptionalFormalParameters( |
| 1529 int count, Token beginToken, Token endToken) { | 1533 int count, Token beginToken, Token endToken) { |
| 1530 debugEvent("OptionalFormalParameters"); | 1534 debugEvent("OptionalFormalParameters"); |
| 1531 FormalParameterType kind = optional("{", beginToken) | 1535 FormalParameterType kind = optional("{", beginToken) |
| 1532 ? FormalParameterType.NAMED | 1536 ? FormalParameterType.NAMED |
| 1533 : FormalParameterType.POSITIONAL; | 1537 : FormalParameterType.POSITIONAL; |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1973 Expression value = popForValue(); | 1977 Expression value = popForValue(); |
| 1974 Identifier identifier = pop(); | 1978 Identifier identifier = pop(); |
| 1975 push(new NamedExpression(identifier.name, value)); | 1979 push(new NamedExpression(identifier.name, value)); |
| 1976 } | 1980 } |
| 1977 | 1981 |
| 1978 @override | 1982 @override |
| 1979 void endFunctionName(Token beginToken, Token token) { | 1983 void endFunctionName(Token beginToken, Token token) { |
| 1980 debugEvent("FunctionName"); | 1984 debugEvent("FunctionName"); |
| 1981 Identifier name = pop(); | 1985 Identifier name = pop(); |
| 1982 VariableDeclaration variable = | 1986 VariableDeclaration variable = |
| 1983 new VariableDeclaration(name.name, isFinal: true); | 1987 astFactory.variableDeclaration(name.name, isFinal: true); |
| 1984 push(new FunctionDeclaration( | 1988 push(new FunctionDeclaration( |
| 1985 variable, new FunctionNode(new InvalidStatement())) | 1989 variable, new FunctionNode(new InvalidStatement())) |
| 1986 ..fileOffset = beginToken.charOffset); | 1990 ..fileOffset = beginToken.charOffset); |
| 1987 scope[variable.name] = new KernelVariableBuilder( | 1991 scope[variable.name] = new KernelVariableBuilder( |
| 1988 variable, member ?? classBuilder ?? library, uri); | 1992 variable, member ?? classBuilder ?? library, uri); |
| 1989 enterLocalScope(); | 1993 enterLocalScope(); |
| 1990 } | 1994 } |
| 1991 | 1995 |
| 1992 void enterFunction() { | 1996 void enterFunction() { |
| 1993 debugEvent("enterFunction"); | 1997 debugEvent("enterFunction"); |
| (...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3053 } else if (node is PrefixBuilder) { | 3057 } else if (node is PrefixBuilder) { |
| 3054 return node.name; | 3058 return node.name; |
| 3055 } else if (node is ThisAccessor) { | 3059 } else if (node is ThisAccessor) { |
| 3056 return node.isSuper ? "super" : "this"; | 3060 return node.isSuper ? "super" : "this"; |
| 3057 } else if (node is FastaAccessor) { | 3061 } else if (node is FastaAccessor) { |
| 3058 return node.plainNameForRead; | 3062 return node.plainNameForRead; |
| 3059 } else { | 3063 } else { |
| 3060 return internalError("Unhandled: ${node.runtimeType}"); | 3064 return internalError("Unhandled: ${node.runtimeType}"); |
| 3061 } | 3065 } |
| 3062 } | 3066 } |
| OLD | NEW |