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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: pkg/front_end/lib/src/fasta/kernel/body_builder.dart
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 53720473f23579c02ad899ad9998fa3645077bdf..37e98e1a4ff1349b82c78d55af668c02e7217bfb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -10,6 +10,10 @@ import '../parser/error_kind.dart' show ErrorKind;
import '../parser/identifier_context.dart' show IdentifierContext;
+import 'package:front_end/src/fasta/builder/ast_factory.dart';
+import 'package:front_end/src/fasta/kernel/ast_factory.dart' as kernel;
+import 'package:front_end/src/fasta/type_inference/local_type_inferrer.dart';
+import 'shadow_ast.dart' as shadow;
import 'package:kernel/ast.dart';
import 'package:kernel/clone.dart' show CloneVisitor;
@@ -128,19 +132,28 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
// from VM engineers. TODO(ahe): Does this still apply?
int currentLocalVariableModifiers = -1;
+ final AstFactory _ast = new kernel.AstFactory();
+
+ final LocalTypeInferrer _typeInferrer;
+
+ OldFunctionContext _functionContext;
+
BodyBuilder(
KernelLibraryBuilder library,
this.member,
Scope scope,
this.formalParameterScope,
this.hierarchy,
- this.coreTypes,
+ CoreTypes coreTypes,
this.classBuilder,
this.isInstanceMember,
this.uri)
- : enclosingScope = scope,
+ : coreTypes = coreTypes,
+ enclosingScope = scope,
library = library,
isDartLibrary = library.uri.scheme == "dart",
+ // TODO(paulberry): put this behind a flag.
+ _typeInferrer = new LocalTypeInferrer(coreTypes),
super(scope);
bool get hasParserError => recoverableErrors.isNotEmpty;
@@ -214,9 +227,9 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
return toValue(node);
}
- List<Expression> popListForValue(int n) {
- List<Expression> list =
- new List<Expression>.filled(n, null, growable: true);
+ List<shadow.Expression> popListForValue(int n) {
+ List<shadow.Expression> list =
+ new List<shadow.Expression>.filled(n, null, growable: true);
for (int i = n - 1; i >= 0; i--) {
list[i] = popForValue();
}
@@ -232,7 +245,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
return list;
}
- Block popBlock(int count, int charOffset) {
+ shadow.Block popBlock(int count, int charOffset) {
List<dynamic /*Statement | List<Statement>*/ > statements =
popList(count) ?? <Statement>[];
List<Statement> copy;
@@ -247,7 +260,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
copy.add(statement);
}
}
- return new Block(copy ?? statements)..fileOffset = charOffset;
+ return _ast.block(copy ?? statements, charOffset);
}
Statement popStatementIfNotNull(Object value) {
@@ -444,8 +457,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
}
@override
- void finishFunction(
- FormalParameters formals, AsyncMarker asyncModifier, Statement body) {
+ void finishFunction(FormalParameters formals, AsyncMarker asyncModifier,
+ shadow.Statement body) {
debugEvent("finishFunction");
KernelFunctionBuilder builder = member;
if (builder is KernelConstructorBuilder) {
@@ -459,6 +472,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
} else {
internalError("Unhandled: ${builder.runtimeType}");
}
+ _typeInferrer.inferBody(body);
builder.body = body;
if (formals?.optional != null) {
Iterator<FormalParameterBuilder> formalBuilders =
@@ -921,8 +935,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
@override
void handleLiteralInt(Token token) {
debugEvent("LiteralInt");
- push(
- new IntLiteral(int.parse(token.lexeme))..fileOffset = token.charOffset);
+ push(_ast.intLiteral(int.parse(token.lexeme), token.charOffset));
}
@override
@@ -941,12 +954,13 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
void endReturnStatement(
bool hasExpression, Token beginToken, Token endToken) {
debugEvent("ReturnStatement");
- Expression expression = hasExpression ? popForValue() : null;
+ shadow.Expression expression = hasExpression ? popForValue() : null;
if (expression != null && inConstructor) {
push(buildCompileTimeErrorStatement(
"Can't return from a constructor.", beginToken.charOffset));
} else {
- push(new ReturnStatement(expression)..fileOffset = beginToken.charOffset);
+ push(_ast.returnStatement(expression, beginToken.charOffset));
+ _typeInferrer.recordReturnStatement(_functionContext, expression);
}
}
@@ -972,18 +986,22 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
pushNewLocalVariable(null);
}
- void pushNewLocalVariable(Expression initializer,
+ void pushNewLocalVariable(shadow.Expression initializer,
{int equalsCharOffset: TreeNode.noOffset}) {
Identifier identifier = pop();
assert(currentLocalVariableModifiers != -1);
bool isConst = (currentLocalVariableModifiers & constMask) != 0;
bool isFinal = (currentLocalVariableModifiers & finalMask) != 0;
assert(isConst == constantExpressionRequired);
- push(new VariableDeclaration(identifier.name,
+ var variable = _ast.variableDeclaration(identifier.name,
initializer: initializer,
- type: currentLocalVariableType ?? const DynamicType(),
+ type: currentLocalVariableType,
isFinal: isFinal,
- isConst: isConst)..fileEqualsOffset = equalsCharOffset);
+ isConst: isConst,
+ charOffset: equalsCharOffset);
+ _typeInferrer.finishVariableDeclaration(
+ currentLocalVariableType, initializer, variable);
+ push(variable);
}
@override
@@ -1143,26 +1161,26 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
void handleAsyncModifier(Token asyncToken, Token starToken) {
debugEvent("AsyncModifier");
push(asyncMarkerFromTokens(asyncToken, starToken));
+ _functionContext?.recordAsyncModifier(asyncToken != null);
}
@override
void handleLiteralList(
int count, Token beginToken, Token constKeyword, Token endToken) {
debugEvent("LiteralList");
- List<Expression> expressions = popListForValue(count);
+ List<shadow.Expression> expressions = popListForValue(count);
List<DartType> typeArguments = pop();
- DartType typeArgument = const DynamicType();
+ DartType typeArgument;
if (typeArguments != null) {
typeArgument = typeArguments.first;
if (typeArguments.length > 1) {
- typeArgument = const DynamicType();
+ typeArgument = null;
warning(
"Too many type arguments on List literal.", beginToken.charOffset);
}
}
- push(new ListLiteral(expressions,
- typeArgument: typeArgument, isConst: constKeyword != null)
- ..fileOffset = constKeyword?.charOffset ?? beginToken.charOffset);
+ push(_ast.listLiteral(expressions, typeArgument, constKeyword != null,
+ constKeyword?.charOffset ?? beginToken.charOffset));
}
@override
@@ -1183,7 +1201,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
@override
void handleLiteralNull(Token token) {
debugEvent("LiteralNull");
- push(new NullLiteral()..fileOffset = token.charOffset);
+ push(_ast.nullLiteral(token.charOffset));
}
@override
@@ -1405,7 +1423,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
DartType type = pop();
pop(); // Modifiers.
ignore(Unhandled.Metadata);
- VariableDeclaration variable;
+ shadow.VariableDeclaration variable;
if (!inCatchClause && functionNestingLevel == 0) {
dynamic builder = formalParameterScope.lookup(name.name, charOffset, uri);
if (builder == null) {
@@ -1426,16 +1444,19 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
thisKeyword.charOffset);
}
type = field.target.type ?? const DynamicType();
- variable = new VariableDeclaration(name.name,
- type: type, initializer: name.initializer);
+ variable = _ast.variableDeclaration(name.name,
+ type: type,
+ initializer: name.initializer as shadow.Expression,
+ charOffset: name.fileOffset);
} else {
addCompileTimeError(
name.fileOffset, "'${name.name}' isn't a field in this class.");
}
}
- variable ??= new VariableDeclaration(name.name,
- type: type ?? const DynamicType(),
- initializer: name.initializer)..fileOffset = name.fileOffset;
+ variable ??= _ast.variableDeclaration(name.name,
+ type: type,
+ initializer: name.initializer as shadow.Expression,
+ charOffset: name.fileOffset);
push(variable);
}
@@ -1501,6 +1522,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
enterLocalScope(formals.computeFormalParameterScope(
scope, member ?? classBuilder ?? library));
}
+ formals.recordTypeInferenceTo(_functionContext);
}
@override
@@ -1878,11 +1900,12 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
enterLocalScope();
}
- void enterFunction() {
+ void enterFunction(bool isNamed) {
debugEvent("enterFunction");
functionNestingLevel++;
push(switchScope ?? NullValue.SwitchScope);
switchScope = null;
+ _functionContext = _typeInferrer.nestFunctionContext(_functionContext);
}
void exitFunction() {
@@ -1894,13 +1917,13 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
@override
void beginFunction(Token token) {
debugEvent("beginFunction");
- enterFunction();
+ enterFunction(true);
}
@override
void beginUnnamedFunction(Token token) {
debugEvent("beginUnnamedFunction");
- enterFunction();
+ enterFunction(false);
}
@override
@@ -1946,7 +1969,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
typeParameters: typeParameters, asyncMarker: asyncModifier)
..fileOffset = beginToken.charOffset
..fileEndOffset = token.charOffset);
- push(new FunctionExpression(function)..fileOffset = beginToken.charOffset);
+ push(new shadow.FunctionExpression(function)
+ ..fileOffset = beginToken.charOffset);
}
@override
@@ -2837,6 +2861,21 @@ class FormalParameters {
}
return new Scope(local, parent, isModifiable: false);
}
+
+ void recordTypeInferenceTo(OldFunctionContext functionContext) {
+ if (functionContext == null) return;
+ int requiredParameterCount = required.length;
+ var positionalFormals = <shadow.VariableDeclaration>[];
+ var namedFormals = const <shadow.VariableDeclaration>[];
+ for (VariableDeclaration parameter in required) {
+ positionalFormals.add(parameter);
+ }
+ if (optional != null) {
+ throw new UnimplementedError();
+ }
+ functionContext.recordFormals(
+ requiredParameterCount, positionalFormals, namedFormals);
+ }
}
/// Returns a block like this:

Powered by Google App Engine
This is Rietveld 408576698