Add statement hooks to TypeInferenceListener.

R=scheglov@google.com

Review-Url: https://codereview.chromium.org/2894343002 .
This commit is contained in:
Paul Berry 2017-05-20 18:56:56 -07:00
parent d7be9e36e8
commit d68f6ad603
2 changed files with 73 additions and 15 deletions

View file

@ -90,9 +90,11 @@ class KernelBlock extends Block implements KernelStatement {
@override
void _inferStatement(KernelTypeInferrer inferrer) {
inferrer.listener.blockEnter(this);
for (var statement in statements) {
inferrer.inferStatement(statement);
}
inferrer.listener.blockExit(this);
}
}
@ -259,7 +261,9 @@ class KernelExpressionStatement extends ExpressionStatement
@override
void _inferStatement(KernelTypeInferrer inferrer) {
inferrer.listener.expressionStatementEnter(this);
inferrer.inferExpression(expression, null, false);
inferrer.listener.expressionStatementExit(this);
}
}
@ -304,10 +308,12 @@ class KernelFunctionDeclaration extends FunctionDeclaration
@override
void _inferStatement(KernelTypeInferrer inferrer) {
inferrer.listener.functionDeclarationEnter(this);
var oldClosureContext = inferrer.closureContext;
inferrer.closureContext = null;
inferrer.inferStatement(function.body);
inferrer.closureContext = oldClosureContext;
inferrer.listener.functionDeclarationExit(this);
}
}
@ -489,10 +495,12 @@ class KernelIfStatement extends IfStatement implements KernelStatement {
@override
void _inferStatement(KernelTypeInferrer inferrer) {
inferrer.listener.ifStatementEnter(this);
inferrer.inferExpression(
condition, inferrer.coreTypes.boolClass.rawType, false);
inferrer.inferStatement(then);
if (otherwise != null) inferrer.inferStatement(otherwise);
inferrer.listener.ifStatementExit(this);
}
}
@ -762,6 +770,7 @@ class KernelReturnStatement extends ReturnStatement implements KernelStatement {
@override
void _inferStatement(KernelTypeInferrer inferrer) {
inferrer.listener.returnStatementEnter(this);
var closureContext = inferrer.closureContext;
var typeContext = closureContext != null && !closureContext.isGenerator
? closureContext.returnContext
@ -770,13 +779,13 @@ class KernelReturnStatement extends ReturnStatement implements KernelStatement {
? inferrer.inferExpression(
expression, typeContext, closureContext != null)
: const VoidType();
if (expression == null) {
// Analyzer treats bare `return` statements as having no effect on the
// inferred type of the closure. TODO(paulberry): is this what we want
// for Fasta?
return;
// Analyzer treats bare `return` statements as having no effect on the
// inferred type of the closure. TODO(paulberry): is this what we want
// for Fasta?
if (expression != null) {
closureContext?.updateInferredReturnType(inferrer, inferredType);
}
closureContext?.updateInferredReturnType(inferrer, inferredType);
inferrer.listener.returnStatementExit(this);
}
}
@ -1229,15 +1238,18 @@ class KernelVariableDeclaration extends VariableDeclaration
@override
void _inferStatement(KernelTypeInferrer inferrer) {
inferrer.listener.variableDeclarationEnter(this);
var declaredType = _implicitlyTyped ? null : type;
if (initializer == null) return;
var inferredType = inferrer.inferDeclarationType(
inferrer.inferExpression(initializer, declaredType, _implicitlyTyped));
if (inferrer.strongMode && _implicitlyTyped) {
inferrer.instrumentation?.record(Uri.parse(inferrer.uri), fileOffset,
'type', new InstrumentationValueForType(inferredType));
type = inferredType;
if (initializer != null) {
var inferredType = inferrer.inferDeclarationType(inferrer.inferExpression(
initializer, declaredType, _implicitlyTyped));
if (inferrer.strongMode && _implicitlyTyped) {
inferrer.instrumentation?.record(Uri.parse(inferrer.uri), fileOffset,
'type', new InstrumentationValueForType(inferredType));
type = inferredType;
}
}
inferrer.listener.variableDeclarationExit(this);
}
/// Determine whether the given [KernelVariableDeclaration] had an implicit

View file

@ -14,8 +14,12 @@ class TypeInferenceBase {
return false;
}
debugExpressionExit(
void debugExpressionExit(
String expressionType, Expression expression, DartType inferredType) {}
void debugStatementEnter(String statementType, Statement statement) {}
void debugStatementExit(String statementType, Statement statement) {}
}
/// Mixin which can be applied to [TypeInferenceListener] to cause debug info to
@ -27,10 +31,18 @@ class TypeInferenceDebugging implements TypeInferenceBase {
return true;
}
debugExpressionExit(
void debugExpressionExit(
String expressionType, Expression expression, DartType inferredType) {
print('Exit $expressionType($expression) (type=$inferredType)');
}
void debugStatementEnter(String statementType, Statement statement) {
print('Enter $statementType($statement)');
}
void debugStatementExit(String statementType, Statement statement) {
print('Exit $statementType($statement)');
}
}
/// Callback interface used by [TypeInferrer] to report the results of type
@ -56,6 +68,10 @@ class TypeInferenceListener
void asExpressionExit(AsExpression expression, DartType inferredType) =>
debugExpressionExit("asExpression", expression, inferredType);
void blockEnter(Block statement) => debugStatementEnter('block', statement);
void blockExit(Block statement) => debugStatementExit('block', statement);
bool boolLiteralEnter(BoolLiteral expression, DartType typeContext) =>
debugExpressionEnter("boolLiteral", expression, typeContext);
@ -84,6 +100,18 @@ class TypeInferenceListener
void doubleLiteralExit(DoubleLiteral expression, DartType inferredType) =>
debugExpressionExit("doubleLiteral", expression, inferredType);
void expressionStatementEnter(ExpressionStatement statement) =>
debugStatementEnter('expressionStatement', statement);
void expressionStatementExit(ExpressionStatement statement) =>
debugStatementExit('expressionStatement', statement);
void functionDeclarationEnter(FunctionDeclaration statement) =>
debugStatementEnter('functionDeclaration', statement);
void functionDeclarationExit(FunctionDeclaration statement) =>
debugStatementExit('functionDeclaration', statement);
bool functionExpressionEnter(
FunctionExpression expression, DartType typeContext) =>
debugExpressionEnter("functionExpression", expression, typeContext);
@ -92,6 +120,12 @@ class TypeInferenceListener
FunctionExpression expression, DartType inferredType) =>
debugExpressionExit("functionExpression", expression, inferredType);
void ifStatementEnter(IfStatement statement) =>
debugStatementEnter('ifStatement', statement);
void ifStatementExit(IfStatement statement) =>
debugStatementExit('ifStatement', statement);
bool intLiteralEnter(IntLiteral expression, DartType typeContext) =>
debugExpressionEnter("intLiteral", expression, typeContext);
@ -130,6 +164,12 @@ class TypeInferenceListener
void nullLiteralExit(NullLiteral expression, DartType inferredType) =>
debugExpressionExit("nullLiteral", expression, inferredType);
void returnStatementEnter(ReturnStatement statement) =>
debugStatementEnter('returnStatement', statement);
void returnStatementExit(ReturnStatement statement) =>
debugStatementExit('returnStatement', statement);
bool staticGetEnter(StaticGet expression, DartType typeContext) =>
debugExpressionEnter("staticGet", expression, typeContext);
@ -158,6 +198,12 @@ class TypeInferenceListener
void stringLiteralExit(StringLiteral expression, DartType inferredType) =>
debugExpressionExit("StringLiteral", expression, inferredType);
void variableDeclarationEnter(VariableDeclaration statement) =>
debugStatementEnter('variableDeclaration', statement);
void variableDeclarationExit(VariableDeclaration statement) =>
debugStatementExit('variableDeclaration', statement);
bool variableGetEnter(VariableGet expression, DartType typeContext) =>
debugExpressionEnter("variableGet", expression, typeContext);