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

Unified Diff: pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart

Issue 2829223007: Introduce initial plumbing for type promotion in fasta. (Closed)
Patch Set: Add missing copyrights Created 3 years, 8 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/kernel_shadow_ast.dart
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index 0b6af073e67b018e7e24b006aecd0719b9b6f6ef..c61fe0bb5a2db33dab7c98bd626c7711a8b17f38 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -20,6 +20,7 @@
import 'package:front_end/src/base/instrumentation.dart';
import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
import 'package:front_end/src/fasta/type_inference/type_inferrer.dart';
+import 'package:front_end/src/fasta/type_inference/type_promotion.dart';
import 'package:kernel/ast.dart';
/// Concrete shadow object representing a statement block in kernel form.
@@ -43,6 +44,17 @@ abstract class KernelExpression implements Expression {
KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded);
}
+/// Concrete shadow object representing an expression statement in kernel form.
+class KernelExpressionStatement extends ExpressionStatement
+ implements KernelStatement {
+ KernelExpressionStatement(Expression expression) : super(expression);
+
+ @override
+ void _inferStatement(KernelTypeInferrer inferrer) {
+ inferrer.inferExpressionStatement(expression);
+ }
+}
+
/// Concrete shadow object representing a field in kernel form.
class KernelField extends Field {
bool _implicitlyTyped = true;
@@ -83,8 +95,32 @@ class KernelFunctionExpression extends FunctionExpression
@override
DartType _inferExpression(
KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) {
- // TODO(paulberry): implement.
- return typeNeeded ? const DynamicType() : null;
+ var asyncMarker = function.asyncMarker;
+ bool isAsync = asyncMarker == AsyncMarker.Async ||
+ asyncMarker == AsyncMarker.AsyncStar;
+ bool isGenerator = asyncMarker == AsyncMarker.SyncStar ||
+ asyncMarker == AsyncMarker.AsyncStar;
+ return inferrer.inferFunctionExpression(
+ typeContext,
+ typeNeeded,
+ function.body,
+ function.body is ReturnStatement,
+ isAsync,
+ isGenerator,
+ fileOffset, (type) {
+ function.returnType = type;
+ }, () => function.functionType);
+ }
+}
+
+/// Concrete shadow object representing an if statement in kernel form.
+class KernelIfStatement extends IfStatement implements KernelStatement {
+ KernelIfStatement(Expression condition, Statement then, Statement otherwise)
+ : super(condition, then, otherwise);
+
+ @override
+ void _inferStatement(KernelTypeInferrer inferrer) {
+ inferrer.inferIfStatement(condition, then, otherwise);
}
}
@@ -99,6 +135,31 @@ class KernelIntLiteral extends IntLiteral implements KernelExpression {
}
}
+/// Concrete shadow object representing a non-inverted "is" test in kernel form.
+class KernelIsExpression extends IsExpression implements KernelExpression {
+ KernelIsExpression(Expression operand, DartType type) : super(operand, type);
+
+ @override
+ DartType _inferExpression(
+ KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) {
+ return inferrer.inferIsExpression(typeContext, typeNeeded, operand);
+ }
+}
+
+/// Concrete shadow object representing an inverted "is" test in kernel form.
+class KernelIsNotExpression extends Not implements KernelExpression {
+ KernelIsNotExpression(Expression operand, DartType type, int charOffset)
+ : super(new IsExpression(operand, type)..fileOffset = charOffset);
+
+ @override
+ DartType _inferExpression(
+ KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) {
+ IsExpression isExpression = this.operand;
+ return inferrer.inferIsExpression(
+ typeContext, typeNeeded, isExpression.operand);
+ }
+}
+
/// Concrete shadow object representing a list literal in kernel form.
class KernelListLiteral extends ListLiteral implements KernelExpression {
KernelListLiteral(List<KernelExpression> expressions,
@@ -226,7 +287,10 @@ class KernelTypeInferenceEngine extends TypeInferenceEngineImpl<KernelField> {
/// Concrete implementation of [TypeInferrer] specialized to work with kernel
/// objects.
class KernelTypeInferrer extends TypeInferrerImpl<Statement, Expression,
- KernelVariableDeclaration, KernelField> {
+ VariableDeclaration, KernelField> {
+ @override
+ final typePromoter = new KernelTypePromoter();
+
KernelTypeInferrer._(KernelTypeInferenceEngine engine, String uri)
: super(engine, uri);
@@ -287,12 +351,83 @@ class KernelTypeInferrer extends TypeInferrerImpl<Statement, Expression,
}
}
+/// Concrete implementation of [TypePromoter] specialized to work with kernel
+/// objects.
+///
+/// Note: the second type parameter really ought to be
+/// KernelVariableDeclaration, but we can't do that yet because BodyBuilder
+/// still uses raw VariableDeclaration objects sometimes.
+/// TODO(paulberry): fix this.
+class KernelTypePromoter
+ extends TypePromoterImpl<Expression, VariableDeclaration> {
+ @override
+ int getVariableFunctionNestingLevel(VariableDeclaration variable) {
+ if (variable is KernelVariableDeclaration) {
+ return variable._functionNestingLevel;
+ } else {
+ // Hack to deal with the fact that BodyBuilder still creates raw
+ // VariableDeclaration objects sometimes.
+ // TODO(paulberry): get rid of this once the type parameter is
+ // KernelVariableDeclaration.
+ return 0;
+ }
+ }
+
+ @override
+ bool sameExpressions(Expression a, Expression b) {
+ return identical(a, b);
+ }
+
+ @override
+ void setVariableMutatedAnywhere(VariableDeclaration variable) {
+ if (variable is KernelVariableDeclaration) {
+ variable._mutatedAnywhere = true;
+ } else {
+ // Hack to deal with the fact that BodyBuilder still creates raw
+ // VariableDeclaration objects sometimes.
+ // TODO(paulberry): get rid of this once the type parameter is
+ // KernelVariableDeclaration.
+ }
+ }
+
+ @override
+ void setVariableMutatedInClosure(VariableDeclaration variable) {
+ if (variable is KernelVariableDeclaration) {
+ variable._mutatedInClosure = true;
+ } else {
+ // Hack to deal with the fact that BodyBuilder still creates raw
+ // VariableDeclaration objects sometimes.
+ // TODO(paulberry): get rid of this once the type parameter is
+ // KernelVariableDeclaration.
+ }
+ }
+
+ @override
+ bool wasVariableMutatedAnywhere(VariableDeclaration variable) {
+ if (variable is KernelVariableDeclaration) {
+ return variable._mutatedAnywhere;
+ } else {
+ // Hack to deal with the fact that BodyBuilder still creates raw
+ // VariableDeclaration objects sometimes.
+ // TODO(paulberry): get rid of this once the type parameter is
+ // KernelVariableDeclaration.
+ return true;
+ }
+ }
+}
+
/// Concrete shadow object representing a variable declaration in kernel form.
class KernelVariableDeclaration extends VariableDeclaration
implements KernelStatement {
final bool _implicitlyTyped;
- KernelVariableDeclaration(String name,
+ final int _functionNestingLevel;
+
+ bool _mutatedInClosure = false;
+
+ bool _mutatedAnywhere = false;
+
+ KernelVariableDeclaration(String name, this._functionNestingLevel,
{Expression initializer,
DartType type,
bool isFinal: false,
@@ -304,6 +439,8 @@ class KernelVariableDeclaration extends VariableDeclaration
isFinal: isFinal,
isConst: isConst);
+ DartType get _declaredType => _implicitlyTyped ? null : type;
+
@override
void _inferStatement(KernelTypeInferrer inferrer) {
inferrer.inferVariableDeclaration(
@@ -315,13 +452,33 @@ class KernelVariableDeclaration extends VariableDeclaration
/// Concrete shadow object representing a read from a variable in kernel form.
class KernelVariableGet extends VariableGet implements KernelExpression {
- KernelVariableGet(VariableDeclaration variable, [DartType promotedType])
- : super(variable, promotedType);
+ final TypePromotionFact<VariableDeclaration> _fact;
+
+ final TypePromotionScope _scope;
+
+ KernelVariableGet(VariableDeclaration variable, this._fact, this._scope)
+ : super(variable);
@override
DartType _inferExpression(
KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) {
- // TODO(paulberry): implement.
- return typeNeeded ? const DynamicType() : null;
+ bool mutatedInClosure;
+ DartType declaredType;
+ var variable = this.variable;
+ if (variable is KernelVariableDeclaration) {
+ mutatedInClosure = variable._mutatedInClosure;
+ declaredType = variable._declaredType;
+ } else {
+ // Hack to deal with the fact that BodyBuilder still creates raw
+ // VariableDeclaration objects sometimes.
+ // TODO(paulberry): get rid of this once the type parameter is
+ // KernelVariableDeclaration.
+ mutatedInClosure = true;
+ declaredType = variable.type;
+ }
+ return inferrer.inferVariableGet(typeContext, typeNeeded, mutatedInClosure,
+ _fact, _scope, fileOffset, declaredType, (type) {
+ promotedType = type;
+ });
}
}

Powered by Google App Engine
This is Rietveld 408576698