Skip to content

Commit 4d1bc04

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[cfe] Flatten TypeInferrer(Engine) hierarchies
Makes TypeInferrerImpl and TypeInferenceEngineImpl fully implement the interfaces. Change-Id: Ic058e7c3cb4d6adae98d499df74824e96a395c8c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122780 Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Dmitry Stefantsov <[email protected]>
1 parent 1bd6e20 commit 4d1bc04

File tree

5 files changed

+95
-148
lines changed

5 files changed

+95
-148
lines changed

pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class InferenceVisitor
99
ExpressionVisitor1<ExpressionInferenceResult, DartType>,
1010
StatementVisitor<void>,
1111
InitializerVisitor<void> {
12-
final ShadowTypeInferrer inferrer;
12+
final TypeInferrerImpl inferrer;
1313

1414
Class mapEntryClass;
1515

pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart

Lines changed: 1 addition & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import 'package:kernel/clone.dart';
3030

3131
import '../../base/instrumentation.dart'
3232
show
33-
Instrumentation,
3433
InstrumentationValueForMember,
3534
InstrumentationValueForType,
3635
InstrumentationValueForTypeArgs;
@@ -43,7 +42,6 @@ import '../fasta_codes.dart'
4342
messageCantDisambiguateNotEnoughInformation,
4443
messageNonNullAwareSpreadIsNull,
4544
messageSwitchExpressionNotAssignableCause,
46-
messageVoidExpression,
4745
noLength,
4846
templateCantInferTypeDueToCircularity,
4947
templateForInLoopElementTypeNotAssignable,
@@ -69,8 +67,6 @@ import '../source/source_class_builder.dart' show SourceClassBuilder;
6967

7068
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
7169

72-
import '../type_inference/inference_helper.dart' show InferenceHelper;
73-
7470
import '../type_inference/type_inference_engine.dart';
7571
import '../type_inference/type_inferrer.dart';
7672

@@ -550,7 +546,7 @@ abstract class InitializerJudgment implements Initializer {
550546
}
551547

552548
Expression checkWebIntLiteralsErrorIfUnexact(
553-
ShadowTypeInferrer inferrer, int value, String literal, int charOffset) {
549+
TypeInferrerImpl inferrer, int value, String literal, int charOffset) {
554550
if (value >= 0 && value <= (1 << 53)) return null;
555551
if (inferrer.isTopLevel) return null;
556552
if (!inferrer.library.loader.target.backendTarget
@@ -810,111 +806,6 @@ class ReturnStatementImpl extends ReturnStatement {
810806
: super(expression);
811807
}
812808

813-
/// Concrete implementation of [TypeInferenceEngine] specialized to work with
814-
/// kernel objects.
815-
class ShadowTypeInferenceEngine extends TypeInferenceEngine {
816-
ShadowTypeInferenceEngine(Instrumentation instrumentation)
817-
: super(instrumentation);
818-
819-
@override
820-
ShadowTypeInferrer createLocalTypeInferrer(Uri uri, InterfaceType thisType,
821-
SourceLibraryBuilder library, InferenceDataForTesting dataForTesting) {
822-
return new TypeInferrer(
823-
this, uri, false, thisType, library, dataForTesting);
824-
}
825-
826-
@override
827-
ShadowTypeInferrer createTopLevelTypeInferrer(Uri uri, InterfaceType thisType,
828-
SourceLibraryBuilder library, InferenceDataForTesting dataForTesting) {
829-
return new TypeInferrer(this, uri, true, thisType, library, dataForTesting);
830-
}
831-
}
832-
833-
/// Concrete implementation of [TypeInferrer] specialized to work with kernel
834-
/// objects.
835-
class ShadowTypeInferrer extends TypeInferrerImpl {
836-
@override
837-
final TypePromoter typePromoter;
838-
839-
final InferenceDataForTesting dataForTesting;
840-
841-
ShadowTypeInferrer.private(
842-
ShadowTypeInferenceEngine engine,
843-
Uri uri,
844-
bool topLevel,
845-
InterfaceType thisType,
846-
SourceLibraryBuilder library,
847-
this.dataForTesting)
848-
: typePromoter = new TypePromoter(engine.typeSchemaEnvironment),
849-
super.private(engine, uri, topLevel, thisType, library);
850-
851-
@override
852-
Expression getFieldInitializer(Field field) {
853-
return field.initializer;
854-
}
855-
856-
@override
857-
ExpressionInferenceResult inferExpression(
858-
Expression expression, DartType typeContext, bool typeNeeded,
859-
{bool isVoidAllowed: false}) {
860-
// `null` should never be used as the type context. An instance of
861-
// `UnknownType` should be used instead.
862-
assert(typeContext != null);
863-
864-
// For full (non-top level) inference, we need access to the
865-
// ExpressionGeneratorHelper so that we can perform error recovery.
866-
assert(isTopLevel || helper != null);
867-
868-
// When doing top level inference, we skip subexpressions whose type isn't
869-
// needed so that we don't induce bogus dependencies on fields mentioned in
870-
// those subexpressions.
871-
if (!typeNeeded) return new ExpressionInferenceResult(null, expression);
872-
873-
InferenceVisitor visitor = new InferenceVisitor(this);
874-
ExpressionInferenceResult result;
875-
if (expression is ExpressionJudgment) {
876-
result = expression.acceptInference(visitor, typeContext);
877-
} else {
878-
result = expression.accept1(visitor, typeContext);
879-
}
880-
DartType inferredType = result.inferredType;
881-
assert(inferredType != null, "No type inferred for $expression.");
882-
if (inferredType is VoidType && !isVoidAllowed) {
883-
if (expression.parent is! ArgumentsImpl) {
884-
helper?.addProblem(
885-
messageVoidExpression, expression.fileOffset, noLength);
886-
}
887-
}
888-
return result;
889-
}
890-
891-
@override
892-
void inferInitializer(InferenceHelper helper, Initializer initializer) {
893-
this.helper = helper;
894-
// Use polymorphic dispatch on [KernelInitializer] to perform whatever
895-
// kind of type inference is correct for this kind of initializer.
896-
// TODO(paulberry): experiment to see if dynamic dispatch would be better,
897-
// so that the type hierarchy will be simpler (which may speed up "is"
898-
// checks).
899-
if (initializer is InitializerJudgment) {
900-
initializer.acceptInference(new InferenceVisitor(this));
901-
} else {
902-
initializer.accept(new InferenceVisitor(this));
903-
}
904-
this.helper = null;
905-
}
906-
907-
@override
908-
void inferStatement(Statement statement) {
909-
// For full (non-top level) inference, we need access to the
910-
// ExpressionGeneratorHelper so that we can perform error recovery.
911-
if (!isTopLevel) assert(helper != null);
912-
if (statement != null) {
913-
statement.accept(new InferenceVisitor(this));
914-
}
915-
}
916-
}
917-
918809
/// Concrete implementation of [TypePromoter] specialized to work with kernel
919810
/// objects.
920811
class ShadowTypePromoter extends TypePromoterImpl {

pkg/front_end/lib/src/fasta/source/source_loader.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ import '../fasta_codes.dart'
8080
templateSourceOutlineSummary,
8181
templateUntranslatableUri;
8282

83-
import '../kernel/kernel_shadow_ast.dart' show ShadowTypeInferenceEngine;
84-
8583
import '../kernel/kernel_builder.dart'
8684
show ClassHierarchyBuilder, DelayedMember, DelayedOverrideCheck;
8785

@@ -112,6 +110,8 @@ import '../scanner.dart'
112110
Token,
113111
scan;
114112

113+
import '../type_inference/type_inference_engine.dart';
114+
115115
import '../type_inference/type_inferrer.dart';
116116

117117
import 'diet_listener.dart' show DietListener;
@@ -143,7 +143,7 @@ class SourceLoader extends Loader {
143143
DartType iterableOfBottom;
144144
DartType streamOfBottom;
145145

146-
ShadowTypeInferenceEngine typeInferenceEngine;
146+
TypeInferenceEngineImpl typeInferenceEngine;
147147

148148
Instrumentation instrumentation;
149149

@@ -986,7 +986,7 @@ class SourceLoader extends Loader {
986986
}
987987

988988
void createTypeInferenceEngine() {
989-
typeInferenceEngine = new ShadowTypeInferenceEngine(instrumentation);
989+
typeInferenceEngine = new TypeInferenceEngineImpl(instrumentation);
990990
}
991991

992992
void performTopLevelInference(List<SourceClassBuilder> sourceClasses) {

pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import '../kernel/kernel_builder.dart'
3434

3535
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
3636

37-
import 'type_inferrer.dart' show TypeInferrer;
37+
import 'type_inferrer.dart';
3838

3939
import 'type_schema_environment.dart' show TypeSchemaEnvironment;
4040

@@ -217,6 +217,27 @@ abstract class TypeInferenceEngine {
217217
}
218218
}
219219

220+
/// Concrete implementation of [TypeInferenceEngine] specialized to work with
221+
/// kernel objects.
222+
class TypeInferenceEngineImpl extends TypeInferenceEngine {
223+
TypeInferenceEngineImpl(Instrumentation instrumentation)
224+
: super(instrumentation);
225+
226+
@override
227+
TypeInferrer createLocalTypeInferrer(Uri uri, InterfaceType thisType,
228+
SourceLibraryBuilder library, InferenceDataForTesting dataForTesting) {
229+
return new TypeInferrerImpl(
230+
this, uri, false, thisType, library, dataForTesting);
231+
}
232+
233+
@override
234+
TypeInferrer createTopLevelTypeInferrer(Uri uri, InterfaceType thisType,
235+
SourceLibraryBuilder library, InferenceDataForTesting dataForTesting) {
236+
return new TypeInferrerImpl(
237+
this, uri, true, thisType, library, dataForTesting);
238+
}
239+
}
240+
220241
class InferenceDataForTesting {
221242
final FlowAnalysisResult flowAnalysisResult = new FlowAnalysisResult();
222243
}

pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart

Lines changed: 67 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@ import '../kernel/expression_generator.dart' show buildIsNull;
5757

5858
import '../kernel/kernel_shadow_ast.dart'
5959
show
60-
ShadowTypeInferenceEngine,
61-
ShadowTypeInferrer,
6260
VariableDeclarationImpl,
6361
getExplicitTypeArguments,
6462
getExtensionTypeParameterCount;
@@ -408,18 +406,6 @@ enum MethodContravarianceCheckKind {
408406
/// This class describes the interface for use by clients of type inference
409407
/// (e.g. BodyBuilder). Derived classes should derive from [TypeInferrerImpl].
410408
abstract class TypeInferrer {
411-
final CoreTypes coreTypes;
412-
413-
TypeInferrer.private(this.coreTypes);
414-
415-
factory TypeInferrer(
416-
ShadowTypeInferenceEngine engine,
417-
Uri uri,
418-
bool topLevel,
419-
InterfaceType thisType,
420-
SourceLibraryBuilder library,
421-
InferenceDataForTesting dataForTesting) = ShadowTypeInferrer.private;
422-
423409
SourceLibraryBuilder get library;
424410

425411
/// Gets the [TypePromoter] that can be used to perform type promotion within
@@ -459,19 +445,21 @@ abstract class TypeInferrer {
459445
InferenceHelper helper, Expression initializer, DartType declaredType);
460446
}
461447

462-
/// Derived class containing generic implementations of [TypeInferrer].
463-
///
464-
/// This class contains as much of the implementation of type inference as
465-
/// possible without knowing the identity of the type parameters. It defers to
466-
/// abstract methods for everything else.
467-
abstract class TypeInferrerImpl extends TypeInferrer {
448+
/// Concrete implementation of [TypeInferrer] specialized to work with kernel
449+
/// objects.
450+
class TypeInferrerImpl implements TypeInferrer {
468451
/// Marker object to indicate that a function takes an unknown number
469452
/// of arguments.
470453
static final FunctionType unknownFunction =
471454
new FunctionType(const [], const DynamicType());
472455

473456
final TypeInferenceEngine engine;
474457

458+
@override
459+
final TypePromoter typePromoter;
460+
461+
final InferenceDataForTesting dataForTesting;
462+
475463
@override
476464
final Uri uriForInstrumentation;
477465

@@ -505,20 +493,34 @@ abstract class TypeInferrerImpl extends TypeInferrer {
505493
/// if the last invocation didn't require any inference.
506494
FunctionType lastCalleeType;
507495

508-
TypeInferrerImpl.private(this.engine, this.uriForInstrumentation,
509-
bool topLevel, this.thisType, this.library)
496+
TypeInferrerImpl(this.engine, this.uriForInstrumentation, bool topLevel,
497+
this.thisType, this.library, this.dataForTesting)
510498
: assert(library != null),
511499
classHierarchy = engine.classHierarchy,
512500
instrumentation = topLevel ? null : engine.instrumentation,
513501
typeSchemaEnvironment = engine.typeSchemaEnvironment,
514502
isTopLevel = topLevel,
515-
super.private(engine.coreTypes);
503+
typePromoter = new TypePromoter(engine.typeSchemaEnvironment);
504+
505+
CoreTypes get coreTypes => engine.coreTypes;
516506

517507
bool get isNonNullableByDefault => library.isNonNullableByDefault;
518508

519-
/// Gets the type promoter that should be used to promote types during
520-
/// inference.
521-
TypePromoter get typePromoter;
509+
@override
510+
void inferInitializer(InferenceHelper helper, Initializer initializer) {
511+
this.helper = helper;
512+
// Use polymorphic dispatch on [KernelInitializer] to perform whatever
513+
// kind of type inference is correct for this kind of initializer.
514+
// TODO(paulberry): experiment to see if dynamic dispatch would be better,
515+
// so that the type hierarchy will be simpler (which may speed up "is"
516+
// checks).
517+
if (initializer is InitializerJudgment) {
518+
initializer.acceptInference(new InferenceVisitor(this));
519+
} else {
520+
initializer.accept(new InferenceVisitor(this));
521+
}
522+
this.helper = null;
523+
}
522524

523525
bool isDoubleContext(DartType typeContext) {
524526
// A context is a double context if double is assignable to it but int is
@@ -1266,10 +1268,6 @@ abstract class TypeInferrerImpl extends TypeInferrer {
12661268
return null;
12671269
}
12681270

1269-
/// Gets the initializer for the given [field], or `null` if there is no
1270-
/// initializer.
1271-
Expression getFieldInitializer(Field field);
1272-
12731271
/// If the [member] is a forwarding stub, return the target it forwards to.
12741272
/// Otherwise return the given [member].
12751273
Member getRealTarget(Member member) {
@@ -1424,7 +1422,37 @@ abstract class TypeInferrerImpl extends TypeInferrer {
14241422
/// the expression type and calls the appropriate specialized "infer" method.
14251423
ExpressionInferenceResult inferExpression(
14261424
Expression expression, DartType typeContext, bool typeNeeded,
1427-
{bool isVoidAllowed});
1425+
{bool isVoidAllowed: false}) {
1426+
// `null` should never be used as the type context. An instance of
1427+
// `UnknownType` should be used instead.
1428+
assert(typeContext != null);
1429+
1430+
// For full (non-top level) inference, we need access to the
1431+
// ExpressionGeneratorHelper so that we can perform error recovery.
1432+
assert(isTopLevel || helper != null);
1433+
1434+
// When doing top level inference, we skip subexpressions whose type isn't
1435+
// needed so that we don't induce bogus dependencies on fields mentioned in
1436+
// those subexpressions.
1437+
if (!typeNeeded) return new ExpressionInferenceResult(null, expression);
1438+
1439+
InferenceVisitor visitor = new InferenceVisitor(this);
1440+
ExpressionInferenceResult result;
1441+
if (expression is ExpressionJudgment) {
1442+
result = expression.acceptInference(visitor, typeContext);
1443+
} else {
1444+
result = expression.accept1(visitor, typeContext);
1445+
}
1446+
DartType inferredType = result.inferredType;
1447+
assert(inferredType != null, "No type inferred for $expression.");
1448+
if (inferredType is VoidType && !isVoidAllowed) {
1449+
if (expression.parent is! ArgumentsImpl) {
1450+
helper?.addProblem(
1451+
messageVoidExpression, expression.fileOffset, noLength);
1452+
}
1453+
}
1454+
return result;
1455+
}
14281456

14291457
@override
14301458
Expression inferFieldInitializer(
@@ -2215,7 +2243,14 @@ abstract class TypeInferrerImpl extends TypeInferrer {
22152243
///
22162244
/// Derived classes should override this method with logic that dispatches on
22172245
/// the statement type and calls the appropriate specialized "infer" method.
2218-
void inferStatement(Statement statement);
2246+
void inferStatement(Statement statement) {
2247+
// For full (non-top level) inference, we need access to the
2248+
// ExpressionGeneratorHelper so that we can perform error recovery.
2249+
if (!isTopLevel) assert(helper != null);
2250+
if (statement != null) {
2251+
statement.accept(new InferenceVisitor(this));
2252+
}
2253+
}
22192254

22202255
/// Performs the type inference steps necessary to instantiate a tear-off
22212256
/// (if necessary).

0 commit comments

Comments
 (0)