Remove Declaration.prepareTopLevelInference
Change-Id: I3c31cdf200c77749e4465be99d832b65be4a775d
Reviewed-on: https://dart-review.googlesource.com/57508
Reviewed-by: Kevin Millikin <kmillikin@google.com>
Commit-Queue: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index f787b69..1fc5bc5 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -226,4 +226,6 @@
}
int get typeVariablesCount;
+
+ void prepareTopLevelInference() {}
}
diff --git a/pkg/front_end/lib/src/fasta/builder/declaration.dart b/pkg/front_end/lib/src/fasta/builder/declaration.dart
index f68699e..d340033 100644
--- a/pkg/front_end/lib/src/fasta/builder/declaration.dart
+++ b/pkg/front_end/lib/src/fasta/builder/declaration.dart
@@ -76,7 +76,5 @@
/// return the number of constructors resolved.
int resolveConstructors(covariant Declaration parent) => 0;
- void prepareTopLevelInference(covariant library, covariant currentClass) {}
-
void instrumentTopLevelInference(covariant instrumentation) {}
}
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index 054a552..8e780a5 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -28,4 +28,6 @@
bool get isField => true;
bool get hasTypeInferredFromInitializer;
+
+ void prepareTopLevelInference() {}
}
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index 8d73995..7e81d10 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -67,6 +67,8 @@
@override
R get target;
+ bool get disableTypeInference => true;
+
Uri get uri;
Declaration addBuilder(String name, Declaration declaration, int charOffset);
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 b5eced7..fad4a2d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -117,6 +117,7 @@
abstract class BodyBuilder<Expression, Statement, Arguments>
extends ScopeListener<JumpTarget>
implements ExpressionGeneratorHelper<Expression, Statement, Arguments> {
+ // TODO(ahe): Rename [library] to 'part'.
@override
final KernelLibraryBuilder library;
@@ -148,6 +149,7 @@
// https://github.com/dart-lang/sdk/issues/28989.
final bool ignoreMainInGetMainClosure;
+ // TODO(ahe): Consider renaming [uri] to 'partUri'.
@override
final Uri uri;
@@ -210,9 +212,9 @@
Map<String, int> initializedFields;
BodyBuilder(
- KernelLibraryBuilder library,
+ this.library,
this.member,
- Scope scope,
+ this.enclosingScope,
this.formalParameterScope,
this.hierarchy,
this.coreTypes,
@@ -220,9 +222,7 @@
this.isInstanceMember,
this.uri,
this._typeInferrer)
- : enclosingScope = scope,
- library = library,
- enableNative =
+ : enableNative =
library.loader.target.backendTarget.enableNative(library.uri),
stringExpectedAfterNative =
library.loader.target.backendTarget.nativeExtensionExpectsString,
@@ -231,7 +231,38 @@
needsImplicitSuperInitializer =
coreTypes?.objectClass != classBuilder?.cls,
typePromoter = _typeInferrer?.typePromoter,
- super(scope);
+ super(enclosingScope);
+
+ BodyBuilder.withParents(
+ KernelFieldBuilder field,
+ KernelLibraryBuilder part,
+ KernelClassBuilder classBuilder,
+ ClassHierarchy hierarchy,
+ CoreTypes coreTypes,
+ TypeInferrer typeInferrer)
+ : this(
+ part,
+ field,
+ classBuilder?.scope ?? field.library.scope,
+ null,
+ hierarchy,
+ coreTypes,
+ classBuilder,
+ field.isInstanceMember,
+ field.fileUri,
+ typeInferrer);
+
+ BodyBuilder.forField(KernelFieldBuilder field, ClassHierarchy hierarchy,
+ CoreTypes coreTypes, TypeInferrer typeInferrer)
+ : this.withParents(
+ field,
+ field.parent is KernelClassBuilder
+ ? field.parent.parent
+ : field.parent,
+ field.parent is KernelClassBuilder ? field.parent : null,
+ hierarchy,
+ coreTypes,
+ typeInferrer);
bool get hasParserError => recoverableErrors.isNotEmpty;
@@ -766,6 +797,14 @@
return toExpression(fakeReturn.expression);
}
+ Expression parseFieldInitializer(Token token) {
+ Parser parser = new Parser(this);
+ token = parser.parseExpression(parser.syntheticPreviousToken(token));
+ Expression expression = popForValue();
+ checkEmpty(token.charOffset);
+ return expression;
+ }
+
void finishConstructor(
KernelConstructorBuilder builder, AsyncMarker asyncModifier) {
/// Quotes below are from [Dart Programming Language Specification, 4th
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
index f2ff3b6..9b1651a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
@@ -40,6 +40,10 @@
: super(library, member, scope, formalParameterScope, hierarchy,
coreTypes, classBuilder, isInstanceMember, uri, typeInferrer);
+ KernelBodyBuilder.forField(ModifierBuilder member, ClassHierarchy hierarchy,
+ CoreTypes coreTypes, TypeInferrer typeInferrer)
+ : super.forField(member, hierarchy, coreTypes, typeInferrer);
+
@override
void enterThenForTypePromotion(Expression condition) {
typePromoter.enterThen(condition);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
index 27516bf..873d0f0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
@@ -4,28 +4,27 @@
library fasta.kernel_field_builder;
-import 'package:front_end/src/base/instrumentation.dart'
- show Instrumentation, InstrumentationValueForType;
-
import 'package:kernel/ast.dart'
show DartType, Expression, Field, Name, NullLiteral;
-import '../../scanner/token.dart' show Token;
+import '../../base/instrumentation.dart'
+ show Instrumentation, InstrumentationValueForType;
-import '../builder/class_builder.dart' show ClassBuilder;
+import '../../scanner/token.dart' show Token;
import '../fasta_codes.dart' show messageInternalProblemAlreadyInitialized;
-import '../parser/parser.dart' show Parser;
-
import '../problems.dart' show internalProblem;
-import '../source/source_library_builder.dart' show SourceLibraryBuilder;
-
import 'kernel_body_builder.dart' show KernelBodyBuilder;
import 'kernel_builder.dart'
- show Declaration, FieldBuilder, KernelTypeBuilder, MetadataBuilder;
+ show
+ Declaration,
+ FieldBuilder,
+ KernelTypeBuilder,
+ LibraryBuilder,
+ MetadataBuilder;
import 'kernel_shadow_ast.dart' show ShadowField;
@@ -61,7 +60,7 @@
bool get isEligibleForInference =>
type == null && (hasInitializer || isInstanceMember);
- Field build(SourceLibraryBuilder library) {
+ Field build(LibraryBuilder library) {
field.name ??= new Name(name, library.target);
if (type != null) {
field.type = type.build(library);
@@ -86,35 +85,20 @@
Field get target => field;
@override
- void prepareTopLevelInference(
- SourceLibraryBuilder library, ClassBuilder currentClass) {
- if (isEligibleForInference) {
- var memberScope =
- currentClass == null ? library.scope : currentClass.scope;
- var typeInferenceEngine = library.loader.typeInferenceEngine;
- var typeInferrer = typeInferenceEngine.createTopLevelTypeInferrer(
- field.enclosingClass?.thisType, field);
- if (hasInitializer) {
- KernelBodyBuilder bodyBuilder = new KernelBodyBuilder(
- library,
- this,
- memberScope,
- null,
- typeInferenceEngine.classHierarchy,
- typeInferenceEngine.coreTypes,
- currentClass,
- isInstanceMember,
- library.fileUri,
- typeInferrer);
- Parser parser = new Parser(bodyBuilder);
- Token token = parser
- .parseExpression(
- parser.syntheticPreviousToken(initializerTokenForInference))
- .next;
- Expression expression = bodyBuilder.popForValue();
- bodyBuilder.checkEmpty(token.charOffset);
- initializer = expression;
- }
+ void prepareTopLevelInference() {
+ if (!isEligibleForInference) return;
+ var typeInferenceEngine = library.loader.typeInferenceEngine;
+ var typeInferrer = typeInferenceEngine.createTopLevelTypeInferrer(
+ field.enclosingClass?.thisType, field);
+ if (hasInitializer) {
+ initializer = new KernelBodyBuilder.forField(
+ this,
+ // TODO(ahe): Why can't we use the loader's classHierarchy and
+ // coreTypes?
+ typeInferenceEngine.classHierarchy,
+ typeInferenceEngine.coreTypes,
+ typeInferrer)
+ .parseFieldInitializer(initializerTokenForInference);
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 2e03b94..5a912e3 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -252,15 +252,9 @@
loader.resolveConstructors();
component =
link(new List<Library>.from(loader.libraries), nameRoot: nameRoot);
- if (metadataCollector != null) {
- component.addMetadataRepository(metadataCollector.repository);
- }
computeCoreTypes();
loader.computeHierarchy();
- if (!loader.target.disableTypeInference) {
- loader.prepareTopLevelInference(myClasses);
- loader.performTopLevelInference(myClasses);
- }
+ loader.performTopLevelInference(myClasses);
loader.checkOverrides(myClasses);
loader.checkAbstractMembers(myClasses);
loader.addNoSuchMethodForwarders(myClasses);
@@ -397,6 +391,10 @@
}
}
+ if (metadataCollector != null) {
+ component.addMetadataRepository(metadataCollector.repository);
+ }
+
ticker.logMs("Linked component");
return component;
}
diff --git a/pkg/front_end/lib/src/fasta/loader.dart b/pkg/front_end/lib/src/fasta/loader.dart
index f1d940a..d2e21c5 100644
--- a/pkg/front_end/lib/src/fasta/loader.dart
+++ b/pkg/front_end/lib/src/fasta/loader.dart
@@ -32,6 +32,8 @@
import 'ticker.dart' show Ticker;
+import 'type_inference/type_inference_engine.dart' show TypeInferenceEngine;
+
abstract class Loader<L> {
final Map<Uri, LibraryBuilder> builders = <Uri, LibraryBuilder>{};
@@ -73,6 +75,8 @@
Template<SummaryTemplate> get outlineSummaryTemplate;
+ TypeInferenceEngine get typeInferenceEngine => null;
+
/// Look up a library builder by the name [uri], or if such doesn't
/// exist, create one. The canonical URI of the library is [uri], and its
/// actual location is [fileUri].
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 3a6d2f1..ebb30da 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -23,9 +23,9 @@
import '../kernel/kernel_builder.dart'
show
- ClassBuilder,
ConstructorReferenceBuilder,
Declaration,
+ FieldBuilder,
KernelClassBuilder,
KernelFieldBuilder,
KernelFunctionBuilder,
@@ -42,8 +42,6 @@
import '../problems.dart' show unexpected, unhandled;
-import 'source_library_builder.dart' show SourceLibraryBuilder;
-
ShadowClass initializeClass(
ShadowClass cls,
List<TypeVariableBuilder> typeVariables,
@@ -100,7 +98,11 @@
ShadowClass.setBuilder(this.cls, this);
}
- Class get cls => origin.actualCls;
+ @override
+ ShadowClass get cls => origin.actualCls;
+
+ @override
+ KernelLibraryBuilder get library => super.library;
Class build(KernelLibraryBuilder library, LibraryBuilder coreLibrary) {
void buildBuilders(String name, Declaration declaration) {
@@ -201,11 +203,13 @@
}
@override
- void prepareTopLevelInference(
- SourceLibraryBuilder library, ClassBuilder currentClass) {
- scope.forEach((name, declaration) {
- declaration.prepareTopLevelInference(library, this);
+ void prepareTopLevelInference() {
+ scope.forEach((String name, Declaration declaration) {
+ if (declaration is FieldBuilder) {
+ declaration.prepareTopLevelInference();
+ }
});
+ cls.setupApiMembers(library.loader.interfaceResolver);
}
@override
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 2124101..8e28bcc 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -89,6 +89,7 @@
/// Indicates whether type inference (and type promotion) should be disabled
/// for this library.
+ @override
final bool disableTypeInference;
String documentationComment;
@@ -724,18 +725,6 @@
}
@override
- void prepareTopLevelInference(
- SourceLibraryBuilder library, ClassBuilder currentClass) {
- forEach((String name, Declaration member) {
- if (member is ClassBuilder) {
- // Classes are handled separately, in class hierarchy order.
- return;
- }
- member.prepareTopLevelInference(library, currentClass);
- });
- }
-
- @override
void instrumentTopLevelInference(Instrumentation instrumentation) {
forEach((String name, Declaration member) {
member.instrumentTopLevelInference(instrumentation);
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 68dffd5..7d6952a 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -37,6 +37,7 @@
ClassBuilder,
Declaration,
EnumBuilder,
+ FieldBuilder,
LibraryBuilder,
NamedTypeBuilder,
TypeBuilder;
@@ -115,6 +116,7 @@
ClassHierarchy hierarchy;
CoreTypes coreTypes;
+ @override
TypeInferenceEngine typeInferenceEngine;
InterfaceResolver interfaceResolver;
@@ -722,11 +724,13 @@
new ShadowTypeInferenceEngine(instrumentation, target.strongMode);
}
- /// Performs the first phase of top level initializer inference, which
- /// consists of creating kernel objects for all fields and top level variables
- /// that might be subject to type inference, and records dependencies between
- /// them.
- void prepareTopLevelInference(List<SourceClassBuilder> sourceClasses) {
+ void performTopLevelInference(List<SourceClassBuilder> sourceClasses) {
+ if (target.disableTypeInference) return;
+
+ /// The first phase of top level initializer inference, which consists of
+ /// creating kernel objects for all fields and top level variables that
+ /// might be subject to type inference, and records dependencies between
+ /// them.
typeInferenceEngine.prepareTopLevel(coreTypes, hierarchy);
interfaceResolver = new InterfaceResolver(
typeInferenceEngine,
@@ -735,30 +739,38 @@
target.strongMode);
builders.forEach((Uri uri, LibraryBuilder library) {
if (library.loader == this) {
- library.prepareTopLevelInference(library, null);
+ library.forEach((String name, Declaration member) {
+ if (member is FieldBuilder) {
+ member.prepareTopLevelInference();
+ }
+ });
}
});
- // Note: we need to create a list before iterating, since calling
- // builder.prepareTopLevelInference causes further class hierarchy queries
- // to be made which would otherwise result in a concurrent modification
- // exception.
- orderedClasses = hierarchy
- .getOrderedClasses(sourceClasses.map((builder) => builder.target))
- .map((class_) => ShadowClass.getClassInferenceInfo(class_).builder)
- .toList();
- for (var builder in orderedClasses) {
- ShadowClass class_ = builder.target;
- builder.prepareTopLevelInference(builder.library, builder);
- class_.setupApiMembers(interfaceResolver);
+ {
+ // Note: we need to create a list before iterating, since calling
+ // builder.prepareTopLevelInference causes further class hierarchy
+ // queries to be made which would otherwise result in a concurrent
+ // modification exception.
+ List<Class> classes = new List<Class>(sourceClasses.length);
+ for (int i = 0; i < sourceClasses.length; i++) {
+ classes[i] = sourceClasses[i].target;
+ }
+ List<ClassBuilder> result = new List<ClassBuilder>(sourceClasses.length);
+ int i = 0;
+ for (Class cls in hierarchy.getOrderedClasses(classes)) {
+ result[i++] = ShadowClass.getClassInferenceInfo(cls).builder;
+ }
+ orderedClasses = result;
+ }
+ for (ClassBuilder cls in orderedClasses) {
+ cls.prepareTopLevelInference();
}
typeInferenceEngine.isTypeInferencePrepared = true;
ticker.logMs("Prepared top level inference");
- }
- /// Performs the second phase of top level initializer inference, which is to
- /// visit fields and top level variables in topologically-sorted order and
- /// assign their types.
- void performTopLevelInference(List<SourceClassBuilder> sourceClasses) {
+ /// The second phase of top level initializer inference, which is to visit
+ /// fields and top level variables in topologically-sorted order and assign
+ /// their types.
typeInferenceEngine.finishTopLevelFields();
List<Class> changedClasses = new List<Class>();
for (var builder in orderedClasses) {