[cfe] Separate patch from regular libraries
+ handle them through the origin library.
This prepares for supporting multiple patch libraries for the same
library.
Change-Id: Ib4934fd2f2c7f743fa342dae86002ac72d57f9a3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/222304
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/builder.dart b/pkg/front_end/lib/src/fasta/builder/builder.dart
index f933d9f..7b208f1 100644
--- a/pkg/front_end/lib/src/fasta/builder/builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/builder.dart
@@ -200,10 +200,6 @@
/// Returns the number of patches that was finished.
int finishPatch();
- /// Resolve constructors (lookup names in scope) recorded in this builder and
- /// return the number of constructors resolved.
- int resolveConstructors(covariant Builder? parent);
-
/// Return `true` if this builder is a duplicate of another with the same
/// name. This is `false` for the builder first declared amongst duplicates.
bool get isDuplicate;
@@ -305,8 +301,5 @@
}
@override
- int resolveConstructors(covariant Builder parent) => 0;
-
- @override
bool get isDuplicate => next != null;
}
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 1672a7d..f2c63b8 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -29,7 +29,6 @@
import 'builder.dart';
import 'class_builder.dart';
-import 'field_builder.dart';
import 'member_builder.dart';
import 'modifier_builder.dart';
import 'name_iterator.dart';
@@ -101,14 +100,6 @@
String name, Builder declaration, Builder other, int charOffset,
{bool isExport: false, bool isImport: false});
- int finishDeferredLoadTearoffs();
-
- int finishForwarders();
-
- int finishNativeMethods();
-
- int finishPatchMethods();
-
/// Looks up [constructorName] in the class named [className].
///
/// The class is looked up in this library's export scope unless
@@ -124,21 +115,6 @@
MemberBuilder getConstructor(String className,
{String constructorName, bool bypassLibraryPrivacy: false});
- int finishTypeVariables(ClassBuilder object, TypeBuilder dynamicType);
-
- /// Computes variances of type parameters on typedefs.
- ///
- /// The variance property of type parameters on typedefs is computed from the
- /// use of the parameters in the right-hand side of the typedef definition.
- int computeVariances() => 0;
-
- /// This method instantiates type parameters to their bounds in some cases
- /// where they were omitted by the programmer and not provided by the type
- /// inference. The method returns the number of distinct type variables
- /// that were instantiated in this library.
- int computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder nullType,
- TypeBuilder bottomType, ClassBuilder objectClass);
-
void becomeCoreLibrary();
void addSyntheticDeclarationOfDynamic();
@@ -160,10 +136,6 @@
void recordAccess(int charOffset, int length, Uri fileUri);
- void buildOutlineExpressions();
-
- List<FieldBuilder>? takeImplicitlyTypedFields();
-
bool get isNonNullableByDefault;
Nullability get nullable;
@@ -286,18 +258,6 @@
}
@override
- int finishDeferredLoadTearoffs() => 0;
-
- @override
- int finishForwarders() => 0;
-
- @override
- int finishNativeMethods() => 0;
-
- @override
- int finishPatchMethods() => 0;
-
- @override
MemberBuilder getConstructor(String className,
{String? constructorName, bool bypassLibraryPrivacy: false}) {
constructorName ??= "";
@@ -340,18 +300,6 @@
}
@override
- int finishTypeVariables(ClassBuilder object, TypeBuilder dynamicType) => 0;
-
- @override
- int computeVariances() => 0;
-
- @override
- int computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder nullType,
- TypeBuilder bottomType, ClassBuilder objectClass) {
- return 0;
- }
-
- @override
void becomeCoreLibrary() {
if (scope.lookupLocalMember("dynamic", setter: false) == null) {
addSyntheticDeclarationOfDynamic();
@@ -392,12 +340,6 @@
void recordAccess(int charOffset, int length, Uri fileUri) {}
@override
- void buildOutlineExpressions() {}
-
- @override
- List<FieldBuilder>? takeImplicitlyTypedFields() => null;
-
- @override
Nullability get nullable {
return isNonNullableByDefault ? Nullability.nullable : Nullability.legacy;
}
@@ -438,7 +380,7 @@
@override
StringBuffer printOn(StringBuffer buffer) {
- return buffer..write(name ?? importUri);
+ return buffer..write(name ?? (isPart ? fileUri : importUri));
}
}
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index c693edd..a95dd25 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -465,24 +465,17 @@
Set<Library> newDillLibraryBuilders = new Set<Library>();
_userBuilders ??= <Uri, LibraryBuilder>{};
Map<LibraryBuilder, List<LibraryBuilder>>? convertedLibraries;
- for (LibraryBuilder builder
- in nextGoodKernelTarget.loader.libraryBuilders) {
- if (builder is SourceLibraryBuilder) {
- DillLibraryBuilder dillBuilder =
- _dillLoadedData!.loader.appendLibrary(builder.library);
- nextGoodKernelTarget.loader.registerLibraryBuilder(
- // TODO(johnniwinther): Why do we need to create
- // [DillLibraryBuilder]s for the patch library file uris?
- dillBuilder,
- builder.isPatch ? builder.fileUri : null);
- _userBuilders![builder.importUri] = dillBuilder;
- newDillLibraryBuilders.add(builder.library);
- changed = true;
- if (experimentalInvalidation != null) {
- convertedLibraries ??=
- new Map<LibraryBuilder, List<LibraryBuilder>>();
- convertedLibraries[builder] = [dillBuilder];
- }
+ for (SourceLibraryBuilder builder
+ in nextGoodKernelTarget.loader.sourceLibraryBuilders) {
+ DillLibraryBuilder dillBuilder =
+ _dillLoadedData!.loader.appendLibrary(builder.library);
+ nextGoodKernelTarget.loader.registerLibraryBuilder(dillBuilder);
+ _userBuilders![builder.importUri] = dillBuilder;
+ newDillLibraryBuilders.add(builder.library);
+ changed = true;
+ if (experimentalInvalidation != null) {
+ convertedLibraries ??= new Map<LibraryBuilder, List<LibraryBuilder>>();
+ convertedLibraries[builder] = [dillBuilder];
}
}
if (changed) {
@@ -537,6 +530,8 @@
bool _checkEquivalentScopes(
SourceLoader sourceLoader, DillLoader dillLoader) {
+ // TODO(johnniwinther): Use [SourceLoader.sourceLibraryBuilders] here.
+ // Currently this causes a failure in incremental_dartino_suite.dart.
for (LibraryBuilder sourceLibraryBuilder in sourceLoader.libraryBuilders) {
if (sourceLibraryBuilder is SourceLibraryBuilder) {
Uri uri = sourceLibraryBuilder.importUri;
@@ -1733,12 +1728,11 @@
}
SourceLibraryBuilder debugLibrary = new SourceLibraryBuilder(
- libraryUri,
- debugExprUri,
- /*packageUri*/ null,
- new ImplicitLanguageVersion(libraryBuilder.library.languageVersion),
- lastGoodKernelTarget.loader,
- null,
+ importUri: libraryUri,
+ fileUri: debugExprUri,
+ packageLanguageVersion:
+ new ImplicitLanguageVersion(libraryBuilder.library.languageVersion),
+ loader: lastGoodKernelTarget.loader,
scope: libraryBuilder.scope.createNestedScope("expression"),
nameOrigin: libraryBuilder,
);
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 9440adf..031764f0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -361,23 +361,6 @@
return entryPoint;
}
- /// Returns classes defined in libraries in [loader].
- List<SourceClassBuilder> collectMyClasses() {
- List<SourceClassBuilder> result = <SourceClassBuilder>[];
- for (LibraryBuilder library in loader.libraryBuilders) {
- if (library.loader == loader) {
- Iterator<Builder> iterator = library.iterator;
- while (iterator.moveNext()) {
- Builder member = iterator.current;
- if (member is SourceClassBuilder && !member.isPatch) {
- result.add(member);
- }
- }
- }
- }
- return result;
- }
-
/// The class [cls] is involved in a cyclic definition. This method should
/// ensure that the cycle is broken, for example, by removing superclass and
/// implemented interfaces.
@@ -460,10 +443,10 @@
finishSynthesizedParameters();
loader.finishDeferredLoadTearoffs();
loader.finishNoSuchMethodForwarders();
- List<SourceClassBuilder> myClasses = collectMyClasses();
+ List<SourceClassBuilder> sourceClasses = loader.collectSourceClasses();
loader.finishNativeMethods();
loader.finishPatchMethods();
- finishAllConstructors(myClasses);
+ finishAllConstructors(sourceClasses);
runBuildTransformations();
if (verify) this.verify();
@@ -625,33 +608,8 @@
void installDefaultSupertypes() {
Class objectClass = this.objectClass;
- for (LibraryBuilder library in loader.libraryBuilders) {
- if (library.loader == loader) {
- Iterator<Builder> iterator = library.iterator;
- while (iterator.moveNext()) {
- Builder declaration = iterator.current;
- if (declaration is SourceClassBuilder) {
- Class cls = declaration.cls;
- if (cls != objectClass) {
- cls.supertype ??= objectClass.asRawSupertype;
- declaration.supertypeBuilder ??= new NamedTypeBuilder(
- "Object",
- const NullabilityBuilder.omitted(),
- /* arguments = */ null,
- /* fileUri = */ null,
- /* charOffset = */ null,
- instanceTypeVariableAccess:
- InstanceTypeVariableAccessState.Unexpected)
- ..bind(objectClassBuilder);
- }
- if (declaration.isMixinApplication) {
- cls.mixedInType = declaration.mixedInTypeBuilder!
- .buildMixedInType(
- library, declaration.charOffset, declaration.fileUri);
- }
- }
- }
- }
+ for (SourceLibraryBuilder library in loader.sourceLibraryBuilders) {
+ library.installDefaultSupertypes(objectClassBuilder, objectClass);
}
ticker.logMs("Installed Object as implicit superclass");
}
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 8873c4e..23ad100 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
@@ -913,7 +913,6 @@
new ConstructorTearOff(constructorBuilder.member)..parent = literal);
}
- @override
int resolveConstructors(SourceLibraryBuilder library) {
if (constructorReferences == null) return 0;
for (ConstructorReferenceBuilder ref in constructorReferences!) {
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 2666f82..10714d1 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
@@ -17,6 +17,7 @@
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
+import 'package:kernel/core_types.dart';
import 'package:kernel/reference_from_index.dart'
show IndexedClass, IndexedContainer, IndexedLibrary;
@@ -84,6 +85,7 @@
import '../kernel/constructor_tearoff_lowering.dart';
import '../kernel/implicit_field_type.dart';
import '../kernel/internal_ast.dart';
+import '../kernel/kernel_helper.dart';
import '../kernel/load_library_builder.dart';
import '../kernel/type_algorithms.dart'
show
@@ -122,6 +124,7 @@
import '../type_inference/type_inferrer.dart' show TypeInferrerImpl;
+import '../util/helpers.dart';
import 'name_scheme.dart';
import 'source_class_builder.dart' show SourceClassBuilder;
import 'source_extension_builder.dart';
@@ -181,7 +184,7 @@
@override
final Library library;
- final SourceLibraryBuilder? actualOrigin;
+ final SourceLibraryBuilder? _origin;
final List<FunctionBuilder> nativeMethods = <FunctionBuilder>[];
@@ -256,13 +259,15 @@
/// [forEachExtensionInScope].
Set<ExtensionBuilder>? _extensionsInScope;
+ List<SourceLibraryBuilder>? _patchLibraries;
+
SourceLibraryBuilder.internal(
SourceLoader loader,
Uri fileUri,
Uri? packageUri,
LanguageVersion packageLanguageVersion,
Scope? scope,
- SourceLibraryBuilder? actualOrigin,
+ SourceLibraryBuilder? origin,
Library library,
LibraryBuilder? nameOrigin,
Library? referencesFrom,
@@ -274,7 +279,7 @@
packageLanguageVersion,
new TypeParameterScopeBuilder.library(),
scope ?? new Scope.top(),
- actualOrigin,
+ origin,
library,
nameOrigin,
referencesFrom);
@@ -286,7 +291,7 @@
this.packageLanguageVersion,
this._libraryTypeParameterScopeBuilder,
this.importScope,
- this.actualOrigin,
+ SourceLibraryBuilder? origin,
this.library,
this._nameOrigin,
this.referencesFrom)
@@ -294,6 +299,7 @@
currentTypeParameterScopeBuilder = _libraryTypeParameterScopeBuilder,
referencesFromIndexed =
referencesFrom == null ? null : new IndexedLibrary(referencesFrom),
+ _origin = origin,
super(fileUri, _libraryTypeParameterScopeBuilder.toScope(importScope),
new Scope.top()) {
assert(
@@ -457,13 +463,13 @@
}
SourceLibraryBuilder(
- Uri uri,
- Uri fileUri,
+ {required Uri importUri,
+ required Uri fileUri,
Uri? packageUri,
- LanguageVersion packageLanguageVersion,
- SourceLoader loader,
- SourceLibraryBuilder? actualOrigin,
- {Scope? scope,
+ required LanguageVersion packageLanguageVersion,
+ required SourceLoader loader,
+ SourceLibraryBuilder? origin,
+ Scope? scope,
Library? target,
LibraryBuilder? nameOrigin,
Library? referencesFrom,
@@ -474,10 +480,10 @@
packageUri,
packageLanguageVersion,
scope,
- actualOrigin,
+ origin,
target ??
- (actualOrigin?.library ??
- new Library(uri,
+ (origin?.library ??
+ new Library(importUri,
fileUri: fileUri,
reference: referenceIsPartOwner == true
? null
@@ -490,6 +496,17 @@
@override
bool get isPart => partOfName != null || partOfUri != null;
+ // TODO(johnniwinther): Can avoid using this from outside this class?
+ Iterable<SourceLibraryBuilder>? get patchLibraries => _patchLibraries;
+
+ void addPatchLibrary(SourceLibraryBuilder patchLibrary) {
+ assert(patchLibrary.isPatch,
+ "Library ${patchLibrary} must be a patch library.");
+ assert(!patchLibrary.isPart,
+ "Patch library ${patchLibrary} cannot be a part .");
+ (_patchLibraries ??= []).add(patchLibrary);
+ }
+
List<NamedTypeBuilder> get unresolvedNamedTypes =>
_libraryTypeParameterScopeBuilder.unresolvedNamedTypes;
@@ -1045,6 +1062,19 @@
/// Builds the core AST structure of this library as needed for the outline.
Library build(LibraryBuilder coreLibrary, {bool modifyTarget: true}) {
+ // TODO(johnniwinther): Avoid the need to process patch libraries before
+ // the origin. Currently, settings performed by the patch are overridden
+ // by the origin. For instance, the `Map` class is abstract in the origin
+ // but (unintentionally) concrete in the patch. By processing the origin
+ // last the `isAbstract` property set by the patch is corrected by the
+ // origin.
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ patchLibrary.build(coreLibrary, modifyTarget: modifyTarget);
+ }
+ }
+
checkMemberConflicts(this, scope,
checkForInstanceVsStaticConflict: false,
checkForMethodVsSetterConflict: true);
@@ -1291,9 +1321,9 @@
(library.problemsAsJson ??= <String>[])
.addAll(part.library.problemsAsJson!);
}
- List<FieldBuilder>? partImplicitlyTypedFields =
- part.takeImplicitlyTypedFields();
- if (partImplicitlyTypedFields != null) {
+ List<FieldBuilder> partImplicitlyTypedFields = [];
+ part.collectImplicitlyTypedFields(partImplicitlyTypedFields);
+ if (partImplicitlyTypedFields.isNotEmpty) {
if (_implicitlyTypedFields == null) {
_implicitlyTypedFields = partImplicitlyTypedFields;
} else {
@@ -1324,6 +1354,13 @@
}
void buildInitialScopes() {
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ patchLibrary.buildInitialScopes();
+ }
+ }
+
NameIterator iterator = nameIterator;
while (iterator.moveNext()) {
addToExportScope(iterator.name, iterator.current);
@@ -1331,6 +1368,13 @@
}
void addImportsToScope() {
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ patchLibrary.addImportsToScope();
+ }
+ }
+
bool explicitCoreImport = this == loader.coreLibrary;
for (Import import in imports) {
if (import.imported?.isPart ?? false) {
@@ -1433,7 +1477,16 @@
/// Resolves all unresolved types in [unresolvedNamedTypes]. The list of types
/// is cleared when done.
int resolveTypes() {
- int typeCount = unresolvedNamedTypes.length;
+ int typeCount = 0;
+
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ typeCount += patchLibrary.resolveTypes();
+ }
+ }
+
+ typeCount += unresolvedNamedTypes.length;
for (NamedTypeBuilder namedType in unresolvedNamedTypes) {
namedType.resolveIn(
scope, namedType.charOffset!, namedType.fileUri!, this);
@@ -1443,12 +1496,75 @@
return typeCount;
}
- @override
- int resolveConstructors(_) {
- int count = 0;
+ void installDefaultSupertypes(
+ ClassBuilder objectClassBuilder, Class objectClass) {
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ patchLibrary.installDefaultSupertypes(objectClassBuilder, objectClass);
+ }
+ }
+
Iterator<Builder> iterator = this.iterator;
while (iterator.moveNext()) {
- count += iterator.current.resolveConstructors(this);
+ Builder declaration = iterator.current;
+ if (declaration is SourceClassBuilder) {
+ Class cls = declaration.cls;
+ if (cls != objectClass) {
+ cls.supertype ??= objectClass.asRawSupertype;
+ declaration.supertypeBuilder ??= new NamedTypeBuilder(
+ "Object",
+ const NullabilityBuilder.omitted(),
+ /* arguments = */ null,
+ /* fileUri = */ null,
+ /* charOffset = */ null,
+ instanceTypeVariableAccess:
+ InstanceTypeVariableAccessState.Unexpected)
+ ..bind(objectClassBuilder);
+ }
+ if (declaration.isMixinApplication) {
+ cls.mixedInType = declaration.mixedInTypeBuilder!.buildMixedInType(
+ this, declaration.charOffset, declaration.fileUri);
+ }
+ }
+ }
+ }
+
+ void collectSourceClasses(List<SourceClassBuilder> sourceClasses) {
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ patchLibrary.collectSourceClasses(sourceClasses);
+ }
+ }
+
+ Iterator<Builder> iterator = this.iterator;
+ while (iterator.moveNext()) {
+ Builder member = iterator.current;
+ if (member is SourceClassBuilder && !member.isPatch) {
+ sourceClasses.add(member);
+ }
+ }
+ }
+
+ /// Resolve constructors (lookup names in scope) recorded in this builder and
+ /// return the number of constructors resolved.
+ int resolveConstructors() {
+ int count = 0;
+
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ count += patchLibrary.resolveConstructors();
+ }
+ }
+
+ Iterator<Builder> iterator = this.iterator;
+ while (iterator.moveNext()) {
+ Builder builder = iterator.current;
+ if (builder is SourceClassBuilder) {
+ count += builder.resolveConstructors(this);
+ }
}
return count;
}
@@ -1491,7 +1607,7 @@
}
@override
- SourceLibraryBuilder get origin => actualOrigin ?? this;
+ SourceLibraryBuilder get origin => _origin ?? this;
@override
Uri get importUri => library.importUri;
@@ -2800,10 +2916,45 @@
return builder;
}
- @override
- void buildOutlineExpressions() {
+ void buildOutlineExpressions(
+ CoreTypes coreTypes,
+ List<SynthesizedFunctionNode> synthesizedFunctionNodes,
+ List<DelayedActionPerformer> delayedActionPerformers) {
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ patchLibrary.buildOutlineExpressions(
+ coreTypes, synthesizedFunctionNodes, delayedActionPerformers);
+ }
+ }
+
MetadataBuilder.buildAnnotations(
library, metadata, this, null, null, fileUri, scope);
+
+ Iterator<Builder> iterator = this.iterator;
+ while (iterator.moveNext()) {
+ Builder declaration = iterator.current;
+ if (declaration is ClassBuilder) {
+ declaration.buildOutlineExpressions(
+ this, coreTypes, delayedActionPerformers, synthesizedFunctionNodes);
+ } else if (declaration is ExtensionBuilder) {
+ declaration.buildOutlineExpressions(
+ this, coreTypes, delayedActionPerformers, synthesizedFunctionNodes);
+ } else if (declaration is MemberBuilder) {
+ declaration.buildOutlineExpressions(
+ this, coreTypes, delayedActionPerformers, synthesizedFunctionNodes);
+ } else if (declaration is SourceTypeAliasBuilder) {
+ declaration.buildOutlineExpressions(
+ this, coreTypes, delayedActionPerformers, synthesizedFunctionNodes);
+ } else {
+ assert(
+ declaration is PrefixBuilder ||
+ declaration is DynamicTypeDeclarationBuilder ||
+ declaration is NeverTypeDeclarationBuilder,
+ "Unexpected builder in library: ${declaration} "
+ "(${declaration.runtimeType}");
+ }
+ }
}
/// Builds the core AST structures for [declaration] needed for the outline.
@@ -3016,9 +3167,16 @@
suppressMessage: false);
}
- @override
int finishDeferredLoadTearoffs() {
int total = 0;
+
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ total += patchLibrary.finishDeferredLoadTearoffs();
+ }
+ }
+
for (Import import in imports) {
if (import.deferred) {
Procedure? tearoff = import.prefixBuilder!.loadLibraryBuilder!.tearoff;
@@ -3028,12 +3186,20 @@
total++;
}
}
+
return total;
}
- @override
int finishForwarders() {
int count = 0;
+
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ count += patchLibrary.finishForwarders();
+ }
+ }
+
CloneVisitorNotMembers cloner = new CloneVisitorNotMembers();
for (int i = 0; i < forwardersOrigins.length; i += 2) {
Procedure forwarder = forwardersOrigins[i];
@@ -3086,12 +3252,22 @@
nativeMethods.add(method);
}
- @override
int finishNativeMethods() {
+ int count = 0;
+
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ count += patchLibrary.finishNativeMethods();
+ }
+ }
+
for (FunctionBuilder method in nativeMethods) {
method.becomeNative(loader);
}
- return nativeMethods.length;
+ count += nativeMethods.length;
+
+ return count;
}
/// Creates a copy of [original] into the scope of [declaration].
@@ -3123,9 +3299,18 @@
return copy;
}
- @override
int finishTypeVariables(ClassBuilder object, TypeBuilder dynamicType) {
- int count = unboundTypeVariables.length;
+ int count = 0;
+
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ count += patchLibrary.finishTypeVariables(object, dynamicType);
+ }
+ }
+
+ count += unboundTypeVariables.length;
+
// Ensure that type parameters are built after their dependencies by sorting
// them topologically using references in bounds.
for (TypeVariableBuilder builder
@@ -3230,9 +3415,20 @@
_pendingNullabilities.clear();
}
- @override
+ /// Computes variances of type parameters on typedefs.
+ ///
+ /// The variance property of type parameters on typedefs is computed from the
+ /// use of the parameters in the right-hand side of the typedef definition.
int computeVariances() {
int count = 0;
+
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ count += patchLibrary.computeVariances();
+ }
+ }
+
for (Builder? declaration
in _libraryTypeParameterScopeBuilder.members!.values) {
while (declaration != null) {
@@ -3336,11 +3532,22 @@
return false;
}
- @override
+ /// This method instantiates type parameters to their bounds in some cases
+ /// where they were omitted by the programmer and not provided by the type
+ /// inference. The method returns the number of distinct type variables
+ /// that were instantiated in this library.
int computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder nullType,
TypeBuilder bottomType, ClassBuilder objectClass) {
int count = 0;
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ count += patchLibrary.computeDefaultTypes(
+ dynamicType, nullType, bottomType, objectClass);
+ }
+ }
+
int computeDefaultTypesForVariables(List<TypeVariableBuilder>? variables,
{required bool inErrorRecovery}) {
if (variables == null) return 0;
@@ -3560,7 +3767,6 @@
}
}
}
-
return count;
}
@@ -3628,13 +3834,21 @@
}
}
- @override
int finishPatchMethods() {
- if (!isPatch) return 0;
int count = 0;
- Iterator<Builder> iterator = this.iterator;
- while (iterator.moveNext()) {
- count += iterator.current.finishPatch();
+
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ count += patchLibrary.finishPatchMethods();
+ }
+ }
+
+ if (isPatch) {
+ Iterator<Builder> iterator = this.iterator;
+ while (iterator.moveNext()) {
+ count += iterator.current.finishPatch();
+ }
}
return count;
}
@@ -4269,6 +4483,13 @@
}
void checkTypesInOutline(TypeEnvironment typeEnvironment) {
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ patchLibrary.checkTypesInOutline(typeEnvironment);
+ }
+ }
+
Iterator<Builder> iterator = this.iterator;
while (iterator.moveNext()) {
Builder declaration = iterator.current;
@@ -4302,6 +4523,13 @@
}
void computeShowHideElements(ClassMembersBuilder membersBuilder) {
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ patchLibrary.computeShowHideElements(membersBuilder);
+ }
+ }
+
assert(currentTypeParameterScopeBuilder.kind ==
TypeParameterScopeKind.library);
for (SourceExtensionBuilder extensionBuilder
@@ -4513,11 +4741,19 @@
(_implicitlyTypedFields ??= <FieldBuilder>[]).add(fieldBuilder);
}
- @override
- List<FieldBuilder>? takeImplicitlyTypedFields() {
- List<FieldBuilder>? result = _implicitlyTypedFields;
- _implicitlyTypedFields = null;
- return result;
+ void collectImplicitlyTypedFields(
+ List<FieldBuilder> implicitlyTypedFieldBuilders) {
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ patchLibrary.collectImplicitlyTypedFields(implicitlyTypedFieldBuilders);
+ }
+ }
+
+ if (_implicitlyTypedFields != null) {
+ implicitlyTypedFieldBuilders.addAll(_implicitlyTypedFields!);
+ _implicitlyTypedFields = null;
+ }
}
void forEachExtensionInScope(void Function(ExtensionBuilder) f) {
@@ -4583,6 +4819,13 @@
}
void installTypedefTearOffs() {
+ Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ patchLibrary.installTypedefTearOffs();
+ }
+ }
+
Iterator<Builder> iterator = this.iterator;
while (iterator.moveNext()) {
Builder? declaration = iterator.current;
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 5568bb4..7bc120f 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -42,7 +42,6 @@
import '../builder/class_builder.dart';
import '../builder/constructor_builder.dart';
import '../builder/declaration_builder.dart';
-import '../builder/dynamic_type_declaration_builder.dart';
import '../builder/enum_builder.dart';
import '../builder/extension_builder.dart';
import '../builder/field_builder.dart';
@@ -51,8 +50,6 @@
import '../builder/member_builder.dart';
import '../builder/modifier_builder.dart';
import '../builder/named_type_builder.dart';
-import '../builder/never_type_declaration_builder.dart';
-import '../builder/prefix_builder.dart';
import '../builder/procedure_builder.dart';
import '../builder/type_alias_builder.dart';
import '../builder/type_builder.dart';
@@ -88,11 +85,10 @@
import 'source_class_builder.dart' show SourceClassBuilder;
import 'source_library_builder.dart'
show
- LanguageVersion,
- InvalidLanguageVersion,
ImplicitLanguageVersion,
+ InvalidLanguageVersion,
+ LanguageVersion,
SourceLibraryBuilder;
-import 'source_type_alias_builder.dart';
import 'stack_listener_impl.dart' show offsetForToken;
class SourceLoader extends Loader {
@@ -153,6 +149,8 @@
final Map<Uri, LibraryBuilder> _builders = <Uri, LibraryBuilder>{};
+ List<SourceLibraryBuilder>? _sourceLibraryBuilders;
+
final Queue<LibraryBuilder> _unparsedLibraries = new Queue<LibraryBuilder>();
final List<Library> libraries = <Library>[];
@@ -228,12 +226,28 @@
@override
LibraryBuilder? lookupLibraryBuilder(Uri importUri) => _builders[importUri];
+ /// The [LibraryBuilder]s for libraries built from source or loaded from dill.
+ ///
+ /// Before [resolveParts] have been called, this includes parts and patches.
Iterable<LibraryBuilder> get libraryBuilders => _builders.values;
+ /// The [SourceLibraryBuilder]s for the libraries built from source by this
+ /// source loader.
+ ///
+ /// This is available after [resolveParts] have been called and doesn't
+ /// include parts or patches. Orphaned parts _are_ included.
+ List<SourceLibraryBuilder> get sourceLibraryBuilders {
+ assert(
+ _sourceLibraryBuilders != null,
+ "Source library builder hasn't been computed yet. "
+ "The source libraries are in SourceLoader.resolveParts.");
+ return _sourceLibraryBuilders!;
+ }
+
Iterable<Uri> get libraryImportUris => _builders.keys;
- void registerLibraryBuilder(LibraryBuilder libraryBuilder, [Uri? uri]) {
- uri ??= libraryBuilder.importUri;
+ void registerLibraryBuilder(LibraryBuilder libraryBuilder) {
+ Uri uri = libraryBuilder.importUri;
if (uri.scheme == "dart" && uri.path == "core") {
_coreLibrary = libraryBuilder;
}
@@ -253,8 +267,8 @@
Ticker get ticker => target.ticker;
- /// Creates a [SourceLibraryBuilder] corresponding to [uri], if one doesn't
- /// exist already.
+ /// Creates a [SourceLibraryBuilder] corresponding to [importUri], if one
+ /// doesn't exist already.
///
/// [fileUri] must not be null and is a URI that can be passed to FileSystem
/// to locate the corresponding file.
@@ -278,15 +292,20 @@
/// which the library belongs to, or the current sdk version if the library
/// doesn't belong to a package.
SourceLibraryBuilder createLibraryBuilder(
- Uri uri,
- Uri fileUri,
+ {required Uri importUri,
+ required Uri fileUri,
Uri? packageUri,
- LanguageVersion packageLanguageVersion,
+ required LanguageVersion packageLanguageVersion,
SourceLibraryBuilder? origin,
Library? referencesFrom,
- bool? referenceIsPartOwner) {
+ bool? referenceIsPartOwner}) {
return new SourceLibraryBuilder(
- uri, fileUri, packageUri, packageLanguageVersion, this, origin,
+ importUri: importUri,
+ fileUri: fileUri,
+ packageUri: packageUri,
+ packageLanguageVersion: packageLanguageVersion,
+ loader: this,
+ origin: origin,
referencesFrom: referencesFrom,
referenceIsPartOwner: referenceIsPartOwner);
}
@@ -370,13 +389,13 @@
new ImplicitLanguageVersion(target.currentSdkVersion);
SourceLibraryBuilder libraryBuilder = createLibraryBuilder(
- uri,
- fileUri,
- packageUri,
- packageLanguageVersion,
- origin,
- referencesFrom,
- referenceIsPartOwner);
+ importUri: uri,
+ fileUri: fileUri,
+ packageUri: packageUri,
+ packageLanguageVersion: packageLanguageVersion,
+ origin: origin,
+ referencesFrom: referencesFrom,
+ referenceIsPartOwner: referenceIsPartOwner);
if (packageLanguageVersionProblem != null) {
libraryBuilder.addPostponedProblem(
packageLanguageVersionProblem, 0, noLength, libraryBuilder.fileUri);
@@ -537,11 +556,9 @@
Future<Null> buildBodies() async {
assert(_coreLibrary != null);
- for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this) {
- currentUriForCrashReporting = library.importUri;
- await buildBody(library);
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ currentUriForCrashReporting = library.importUri;
+ await buildBody(library);
}
currentUriForCrashReporting = null;
logSummary(templateSourceBodySummary);
@@ -551,7 +568,12 @@
ticker.log((Duration elapsed, Duration sinceStart) {
int libraryCount = 0;
for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this) libraryCount++;
+ if (library.loader == this) {
+ libraryCount++;
+ if (library is SourceLibraryBuilder) {
+ libraryCount += library.patchLibraries?.length ?? 0;
+ }
+ }
}
double ms = elapsed.inMicroseconds / Duration.microsecondsPerMillisecond;
Message message = template.withArguments(
@@ -970,29 +992,34 @@
}
/// Builds all the method bodies found in the given [library].
- Future<Null> buildBody(LibraryBuilder library) async {
- if (library is SourceLibraryBuilder) {
- // We tokenize source files twice to keep memory usage low. This is the
- // second time, and the first time was in [buildOutline] above. So this
- // time we suppress lexical errors.
- Token tokens = await tokenize(library, suppressLexicalErrors: true);
+ Future<Null> buildBody(SourceLibraryBuilder library) async {
+ Iterable<SourceLibraryBuilder>? patches = library.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ await buildBody(patchLibrary);
+ }
+ }
+
+ // We tokenize source files twice to keep memory usage low. This is the
+ // second time, and the first time was in [buildOutline] above. So this
+ // time we suppress lexical errors.
+ Token tokens = await tokenize(library, suppressLexicalErrors: true);
+ // ignore: unnecessary_null_comparison
+ if (tokens == null) return;
+ DietListener listener = createDietListener(library);
+ DietParser parser = new DietParser(listener);
+ parser.parseUnit(tokens);
+ for (LibraryBuilder part in library.parts) {
+ if (part.partOfLibrary != library) {
+ // Part was included in multiple libraries. Skip it here.
+ continue;
+ }
+ Token tokens = await tokenize(part as SourceLibraryBuilder,
+ suppressLexicalErrors: true);
// ignore: unnecessary_null_comparison
- if (tokens == null) return;
- DietListener listener = createDietListener(library);
- DietParser parser = new DietParser(listener);
- parser.parseUnit(tokens);
- for (LibraryBuilder part in library.parts) {
- if (part.partOfLibrary != library) {
- // Part was included in multiple libraries. Skip it here.
- continue;
- }
- Token tokens = await tokenize(part as SourceLibraryBuilder,
- suppressLexicalErrors: true);
- // ignore: unnecessary_null_comparison
- if (tokens != null) {
- listener.uri = part.fileUri;
- parser.parseUnit(tokens);
- }
+ if (tokens != null) {
+ listener.uri = part.fileUri;
+ parser.parseUnit(tokens);
}
}
}
@@ -1068,13 +1095,20 @@
void resolveParts() {
List<Uri> parts = <Uri>[];
- List<SourceLibraryBuilder> libraries = <SourceLibraryBuilder>[];
+ List<SourceLibraryBuilder> libraries = [];
+ List<SourceLibraryBuilder> sourceLibraries = [];
+ List<SourceLibraryBuilder> patchLibraries = [];
_builders.forEach((Uri uri, LibraryBuilder library) {
- if (library.loader == this) {
+ if (library.loader == this && library is SourceLibraryBuilder) {
if (library.isPart) {
parts.add(uri);
} else {
- libraries.add(library as SourceLibraryBuilder);
+ if (library.isPatch) {
+ patchLibraries.add(library);
+ } else {
+ sourceLibraries.add(library);
+ }
+ libraries.add(library);
}
}
});
@@ -1093,6 +1127,7 @@
lookupLibraryBuilder(uri) as SourceLibraryBuilder;
part.addProblem(messagePartOrphan, 0, 1, part.fileUri);
part.validatePart(null, null);
+ sourceLibraries.add(part);
}
}
ticker.logMs("Resolved parts");
@@ -1102,6 +1137,25 @@
library.applyPatches();
}
}
+ for (SourceLibraryBuilder patchLibrary in patchLibraries) {
+ _builders.remove(patchLibrary.fileUri);
+ patchLibrary.origin.addPatchLibrary(patchLibrary);
+ }
+ _sourceLibraryBuilders = sourceLibraries;
+ assert(
+ libraryBuilders.every((library) => !library.isPatch),
+ "Patch library found in libraryBuilders: "
+ "${libraryBuilders.where((library) => library.isPatch)}.");
+ assert(
+ sourceLibraries.every((library) => !library.isPatch),
+ "Patch library found in sourceLibraryBuilders: "
+ "${sourceLibraries.where((library) => library.isPatch)}.");
+ assert(
+ libraryBuilders.every((library) =>
+ library.loader != this || sourceLibraries.contains(library)),
+ "Source library not found in sourceLibraryBuilders:"
+ "${libraryBuilders.where((library) => // force line break
+ library.loader == this && !sourceLibraries.contains(library))}");
ticker.logMs("Applied patches");
}
@@ -1119,6 +1173,19 @@
exporters.add(exporter.exporter);
}
}
+
+ Iterable<SourceLibraryBuilder>? patches =
+ library is SourceLibraryBuilder ? library.patchLibraries : null;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ if (patchLibrary.exporters.isNotEmpty) {
+ exportees.add(patchLibrary);
+ for (Export exporter in patchLibrary.exporters) {
+ exporters.add(exporter.exporter);
+ }
+ }
+ }
+ }
}
Set<SourceLibraryBuilder> both = new Set<SourceLibraryBuilder>();
for (LibraryBuilder exported in exportees) {
@@ -1185,11 +1252,8 @@
void resolveTypes() {
int typeCount = 0;
- for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this) {
- SourceLibraryBuilder sourceLibrary = library as SourceLibraryBuilder;
- typeCount += sourceLibrary.resolveTypes();
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ typeCount += library.resolveTypes();
}
ticker.logMs("Resolved $typeCount types");
}
@@ -1325,8 +1389,8 @@
return macros.isNotEmpty ? new MacroApplications(macros) : null;
}
- for (LibraryBuilder libraryBuilder in libraryBuilders) {
- if (libraryBuilder.loader != this) continue;
+ for (SourceLibraryBuilder libraryBuilder in sourceLibraryBuilders) {
+ // TODO(johnniwinther): Handle patch libraries.
LibraryMacroApplicationData libraryMacroApplicationData =
new LibraryMacroApplicationData();
Library library = libraryBuilder.library;
@@ -1381,60 +1445,48 @@
void finishDeferredLoadTearoffs() {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this) {
- count += library.finishDeferredLoadTearoffs();
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ count += library.finishDeferredLoadTearoffs();
}
ticker.logMs("Finished deferred load tearoffs $count");
}
void finishNoSuchMethodForwarders() {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this) {
- count += library.finishForwarders();
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ count += library.finishForwarders();
}
ticker.logMs("Finished forwarders for $count procedures");
}
void resolveConstructors() {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this) {
- count += library.resolveConstructors(null);
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ count += library.resolveConstructors();
}
ticker.logMs("Resolved $count constructors");
}
void installTypedefTearOffs() {
if (target.backendTarget.isTypedefTearOffLoweringEnabled) {
- for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this && library is SourceLibraryBuilder) {
- library.installTypedefTearOffs();
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ library.installTypedefTearOffs();
}
}
}
void finishTypeVariables(ClassBuilder object, TypeBuilder dynamicType) {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this) {
- count += library.finishTypeVariables(object, dynamicType);
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ count += library.finishTypeVariables(object, dynamicType);
}
ticker.logMs("Resolved $count type-variable bounds");
}
void computeVariances() {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this) {
- count += library.computeVariances();
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ count += library.computeVariances();
}
ticker.logMs("Computed variances of $count type variables");
}
@@ -1442,31 +1494,25 @@
void computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder nullType,
TypeBuilder bottomType, ClassBuilder objectClass) {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this) {
- count += library.computeDefaultTypes(
- dynamicType, nullType, bottomType, objectClass);
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ count += library.computeDefaultTypes(
+ dynamicType, nullType, bottomType, objectClass);
}
ticker.logMs("Computed default types for $count type variables");
}
void finishNativeMethods() {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this) {
- count += library.finishNativeMethods();
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ count += library.finishNativeMethods();
}
ticker.logMs("Finished $count native methods");
}
void finishPatchMethods() {
int count = 0;
- for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this) {
- count += library.finishPatchMethods();
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ count += library.finishPatchMethods();
}
ticker.logMs("Finished $count patch methods");
}
@@ -1494,6 +1540,15 @@
}
}
+ /// Returns classes defined in libraries in this [SourceLoader].
+ List<SourceClassBuilder> collectSourceClasses() {
+ List<SourceClassBuilder> sourceClasses = <SourceClassBuilder>[];
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ library.collectSourceClasses(sourceClasses);
+ }
+ return sourceClasses;
+ }
+
/// Returns a list of all class builders declared in this loader. As the
/// classes are sorted, any cycles in the hierarchy are reported as
/// errors. Recover by breaking the cycles. This means that the rest of the
@@ -1516,7 +1571,8 @@
}
// Sort the classes topologically.
- _SourceClassGraph classGraph = new _SourceClassGraph(this, objectClass);
+ _SourceClassGraph classGraph =
+ new _SourceClassGraph(collectSourceClasses(), objectClass);
TopologicalSortResult<SourceClassBuilder> result =
topologicalSort(classGraph);
List<SourceClassBuilder> classes = result.sortedVertices;
@@ -1661,19 +1717,14 @@
/// Builds the core AST structure needed for the outline of the component.
void buildComponent() {
- for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this) {
- SourceLibraryBuilder sourceLibrary = library as SourceLibraryBuilder;
- Library target = sourceLibrary.build(coreLibrary);
- if (!library.isPatch) {
- if (sourceLibrary.referencesFrom != null) {
- referenceFromIndex ??= new ReferenceFromIndex();
- referenceFromIndex!.addIndexedLibrary(
- target, sourceLibrary.referencesFromIndexed!);
- }
- libraries.add(target);
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ Library target = library.build(coreLibrary);
+ if (library.referencesFrom != null) {
+ referenceFromIndex ??= new ReferenceFromIndex();
+ referenceFromIndex!
+ .addIndexedLibrary(target, library.referencesFromIndexed!);
}
+ libraries.add(target);
}
ticker.logMs("Built component");
}
@@ -1728,11 +1779,8 @@
}
void computeShowHideElements() {
- for (LibraryBuilder libraryBuilder in libraryBuilders) {
- if (libraryBuilder.loader == this &&
- libraryBuilder is SourceLibraryBuilder) {
- libraryBuilder.computeShowHideElements(membersBuilder);
- }
+ for (SourceLibraryBuilder libraryBuilder in sourceLibraryBuilders) {
+ libraryBuilder.computeShowHideElements(membersBuilder);
}
ticker.logMs("Computed show and hide elements");
}
@@ -1776,13 +1824,8 @@
}
void checkTypes() {
- for (LibraryBuilder library in libraryBuilders) {
- if (library is SourceLibraryBuilder) {
- if (library.loader == this) {
- library
- .checkTypesInOutline(typeInferenceEngine.typeSchemaEnvironment);
- }
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ library.checkTypesInOutline(typeInferenceEngine.typeSchemaEnvironment);
}
ticker.logMs("Checked type arguments of supers against the bounds");
}
@@ -1857,34 +1900,9 @@
List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
List<DelayedActionPerformer> delayedActionPerformers =
<DelayedActionPerformer>[];
- for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this) {
- (library as SourceLibraryBuilder).buildOutlineExpressions();
- Iterator<Builder> iterator = library.iterator;
- while (iterator.moveNext()) {
- Builder declaration = iterator.current;
- if (declaration is ClassBuilder) {
- declaration.buildOutlineExpressions(library, coreTypes,
- delayedActionPerformers, synthesizedFunctionNodes);
- } else if (declaration is ExtensionBuilder) {
- declaration.buildOutlineExpressions(library, coreTypes,
- delayedActionPerformers, synthesizedFunctionNodes);
- } else if (declaration is MemberBuilder) {
- declaration.buildOutlineExpressions(library, coreTypes,
- delayedActionPerformers, synthesizedFunctionNodes);
- } else if (declaration is SourceTypeAliasBuilder) {
- declaration.buildOutlineExpressions(library, coreTypes,
- delayedActionPerformers, synthesizedFunctionNodes);
- } else {
- assert(
- declaration is PrefixBuilder ||
- declaration is DynamicTypeDeclarationBuilder ||
- declaration is NeverTypeDeclarationBuilder,
- "Unexpected builder in library: ${declaration} "
- "(${declaration.runtimeType}");
- }
- }
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ library.buildOutlineExpressions(
+ coreTypes, synthesizedFunctionNodes, delayedActionPerformers);
}
for (DelayedActionPerformer delayedActionPerformer
in delayedActionPerformers) {
@@ -1918,14 +1936,8 @@
membersBuilder.computeTypes();
List<FieldBuilder> allImplicitlyTypedFields = <FieldBuilder>[];
- for (LibraryBuilder library in libraryBuilders) {
- if (library.loader == this) {
- List<FieldBuilder>? implicitlyTypedFields =
- library.takeImplicitlyTypedFields();
- if (implicitlyTypedFields != null) {
- allImplicitlyTypedFields.addAll(implicitlyTypedFields);
- }
- }
+ for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+ library.collectImplicitlyTypedFields(allImplicitlyTypedFields);
}
for (int i = 0; i < allImplicitlyTypedFields.length; i++) {
@@ -2011,27 +2023,48 @@
isTopLevel: isTopLevel);
}
- void checkMainMethods() {
- DartType? listOfString;
+ void _checkMainMethods(
+ SourceLibraryBuilder libraryBuilder, DartType listOfString) {
+ Iterable<SourceLibraryBuilder>? patches = libraryBuilder.patchLibraries;
+ if (patches != null) {
+ for (SourceLibraryBuilder patchLibrary in patches) {
+ _checkMainMethods(patchLibrary, listOfString);
+ }
+ }
- for (LibraryBuilder libraryBuilder in libraryBuilders) {
- if (libraryBuilder.loader == this &&
- libraryBuilder.isNonNullableByDefault) {
- Builder? mainBuilder =
- libraryBuilder.exportScope.lookupLocalMember('main', setter: false);
- mainBuilder ??=
- libraryBuilder.exportScope.lookupLocalMember('main', setter: true);
- if (mainBuilder is MemberBuilder) {
- if (mainBuilder is InvalidTypeDeclarationBuilder) {
- // This is an ambiguous export, skip the check.
- return;
+ if (libraryBuilder.isNonNullableByDefault) {
+ Builder? mainBuilder =
+ libraryBuilder.exportScope.lookupLocalMember('main', setter: false);
+ mainBuilder ??=
+ libraryBuilder.exportScope.lookupLocalMember('main', setter: true);
+ if (mainBuilder is MemberBuilder) {
+ if (mainBuilder is InvalidTypeDeclarationBuilder) {
+ // This is an ambiguous export, skip the check.
+ return;
+ }
+ if (mainBuilder.isField ||
+ mainBuilder.isGetter ||
+ mainBuilder.isSetter) {
+ if (mainBuilder.parent != libraryBuilder) {
+ libraryBuilder.addProblem(messageMainNotFunctionDeclarationExported,
+ libraryBuilder.charOffset, noLength, libraryBuilder.fileUri,
+ context: [
+ messageExportedMain.withLocation(mainBuilder.fileUri!,
+ mainBuilder.charOffset, mainBuilder.name.length)
+ ]);
+ } else {
+ libraryBuilder.addProblem(
+ messageMainNotFunctionDeclaration,
+ mainBuilder.charOffset,
+ mainBuilder.name.length,
+ mainBuilder.fileUri);
}
- if (mainBuilder.isField ||
- mainBuilder.isGetter ||
- mainBuilder.isSetter) {
+ } else {
+ Procedure procedure = mainBuilder.member as Procedure;
+ if (procedure.function.requiredParameterCount > 2) {
if (mainBuilder.parent != libraryBuilder) {
libraryBuilder.addProblem(
- messageMainNotFunctionDeclarationExported,
+ messageMainTooManyRequiredParametersExported,
libraryBuilder.charOffset,
noLength,
libraryBuilder.fileUri,
@@ -2041,17 +2074,42 @@
]);
} else {
libraryBuilder.addProblem(
- messageMainNotFunctionDeclaration,
+ messageMainTooManyRequiredParameters,
mainBuilder.charOffset,
mainBuilder.name.length,
mainBuilder.fileUri);
}
- } else {
- Procedure procedure = mainBuilder.member as Procedure;
- if (procedure.function.requiredParameterCount > 2) {
+ } else if (procedure.function.namedParameters
+ .any((parameter) => parameter.isRequired)) {
+ if (mainBuilder.parent != libraryBuilder) {
+ libraryBuilder.addProblem(
+ messageMainRequiredNamedParametersExported,
+ libraryBuilder.charOffset,
+ noLength,
+ libraryBuilder.fileUri,
+ context: [
+ messageExportedMain.withLocation(mainBuilder.fileUri!,
+ mainBuilder.charOffset, mainBuilder.name.length)
+ ]);
+ } else {
+ libraryBuilder.addProblem(
+ messageMainRequiredNamedParameters,
+ mainBuilder.charOffset,
+ mainBuilder.name.length,
+ mainBuilder.fileUri);
+ }
+ } else if (procedure.function.positionalParameters.length > 0) {
+ DartType parameterType =
+ procedure.function.positionalParameters.first.type;
+
+ if (!typeEnvironment.isSubtypeOf(listOfString, parameterType,
+ SubtypeCheckMode.withNullabilities)) {
if (mainBuilder.parent != libraryBuilder) {
libraryBuilder.addProblem(
- messageMainTooManyRequiredParametersExported,
+ templateMainWrongParameterTypeExported.withArguments(
+ parameterType,
+ listOfString,
+ libraryBuilder.isNonNullableByDefault),
libraryBuilder.charOffset,
noLength,
libraryBuilder.fileUri,
@@ -2061,84 +2119,40 @@
]);
} else {
libraryBuilder.addProblem(
- messageMainTooManyRequiredParameters,
+ templateMainWrongParameterType.withArguments(parameterType,
+ listOfString, libraryBuilder.isNonNullableByDefault),
mainBuilder.charOffset,
mainBuilder.name.length,
mainBuilder.fileUri);
}
- } else if (procedure.function.namedParameters
- .any((parameter) => parameter.isRequired)) {
- if (mainBuilder.parent != libraryBuilder) {
- libraryBuilder.addProblem(
- messageMainRequiredNamedParametersExported,
- libraryBuilder.charOffset,
- noLength,
- libraryBuilder.fileUri,
- context: [
- messageExportedMain.withLocation(mainBuilder.fileUri!,
- mainBuilder.charOffset, mainBuilder.name.length)
- ]);
- } else {
- libraryBuilder.addProblem(
- messageMainRequiredNamedParameters,
- mainBuilder.charOffset,
- mainBuilder.name.length,
- mainBuilder.fileUri);
- }
- } else if (procedure.function.positionalParameters.length > 0) {
- DartType parameterType =
- procedure.function.positionalParameters.first.type;
-
- listOfString ??= new InterfaceType(
- coreTypes.listClass,
- Nullability.nonNullable,
- [coreTypes.stringNonNullableRawType]);
-
- if (!typeEnvironment.isSubtypeOf(listOfString, parameterType,
- SubtypeCheckMode.withNullabilities)) {
- if (mainBuilder.parent != libraryBuilder) {
- libraryBuilder.addProblem(
- templateMainWrongParameterTypeExported.withArguments(
- parameterType,
- listOfString,
- libraryBuilder.isNonNullableByDefault),
- libraryBuilder.charOffset,
- noLength,
- libraryBuilder.fileUri,
- context: [
- messageExportedMain.withLocation(mainBuilder.fileUri!,
- mainBuilder.charOffset, mainBuilder.name.length)
- ]);
- } else {
- libraryBuilder.addProblem(
- templateMainWrongParameterType.withArguments(
- parameterType,
- listOfString,
- libraryBuilder.isNonNullableByDefault),
- mainBuilder.charOffset,
- mainBuilder.name.length,
- mainBuilder.fileUri);
- }
- }
}
}
- } else if (mainBuilder != null) {
- if (mainBuilder.parent != libraryBuilder) {
- libraryBuilder.addProblem(messageMainNotFunctionDeclarationExported,
- libraryBuilder.charOffset, noLength, libraryBuilder.fileUri,
- context: [
- messageExportedMain.withLocation(
- mainBuilder.fileUri!, mainBuilder.charOffset, noLength)
- ]);
- } else {
- libraryBuilder.addProblem(messageMainNotFunctionDeclaration,
- mainBuilder.charOffset, noLength, mainBuilder.fileUri);
- }
+ }
+ } else if (mainBuilder != null) {
+ if (mainBuilder.parent != libraryBuilder) {
+ libraryBuilder.addProblem(messageMainNotFunctionDeclarationExported,
+ libraryBuilder.charOffset, noLength, libraryBuilder.fileUri,
+ context: [
+ messageExportedMain.withLocation(
+ mainBuilder.fileUri!, mainBuilder.charOffset, noLength)
+ ]);
+ } else {
+ libraryBuilder.addProblem(messageMainNotFunctionDeclaration,
+ mainBuilder.charOffset, noLength, mainBuilder.fileUri);
}
}
}
}
+ void checkMainMethods() {
+ DartType listOfString = new InterfaceType(coreTypes.listClass,
+ Nullability.nonNullable, [coreTypes.stringNonNullableRawType]);
+
+ for (SourceLibraryBuilder libraryBuilder in sourceLibraryBuilders) {
+ _checkMainMethods(libraryBuilder, listOfString);
+ }
+ }
+
void releaseAncillaryResources() {
hierarchy = null;
_hierarchyBuilder = null;
@@ -2453,26 +2467,13 @@
class _SourceClassGraph implements Graph<SourceClassBuilder> {
@override
- final List<SourceClassBuilder> vertices = [];
+ final List<SourceClassBuilder> vertices;
final ClassBuilder _objectClass;
final Map<SourceClassBuilder, Map<TypeDeclarationBuilder?, TypeAliasBuilder?>>
directSupertypeMap = {};
final Map<SourceClassBuilder, List<SourceClassBuilder>> _supertypeMap = {};
- _SourceClassGraph(SourceLoader loader, this._objectClass) {
- // Compute the vertices as all classes declared in this loader.
- for (LibraryBuilder library in loader.libraryBuilders) {
- if (library.loader == loader) {
- Iterator<Builder> members = library.iterator;
- while (members.moveNext()) {
- Builder member = members.current;
- if (member is SourceClassBuilder && !member.isPatch) {
- vertices.add(member);
- }
- }
- }
- }
- }
+ _SourceClassGraph(this.vertices, this._objectClass);
List<SourceClassBuilder> computeSuperClasses(SourceClassBuilder cls) {
Map<TypeDeclarationBuilder?, TypeAliasBuilder?> directSupertypes =
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
index 5fdfef0..f4790b9 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -84,18 +84,17 @@
Expression index = new VariableGet(new VariableDeclaration("index"));
UriTranslator uriTranslator = await c.options.getUriTranslator();
SourceLibraryBuilder libraryBuilder = new SourceLibraryBuilder(
- uri,
- uri,
- /*packageUri*/ null,
- new ImplicitLanguageVersion(defaultLanguageVersion),
- new KernelTarget(
+ importUri: uri,
+ fileUri: uri,
+ packageLanguageVersion:
+ new ImplicitLanguageVersion(defaultLanguageVersion),
+ loader: new KernelTarget(
const MockFileSystem(),
false,
new DillTarget(c.options.ticker, uriTranslator,
new NoneTarget(new TargetFlags())),
uriTranslator)
- .loader,
- null);
+ .loader);
libraryBuilder.markLanguageVersionFinal();
LoadLibraryBuilder loadLibraryBuilder =
new LoadLibraryBuilder(libraryBuilder, dummyLibraryDependency, -1);
diff --git a/pkg/front_end/test/patching/data/abstract_class/libraries.json b/pkg/front_end/test/patching/data/abstract_class/libraries.json
new file mode 100644
index 0000000..a697508
--- /dev/null
+++ b/pkg/front_end/test/patching/data/abstract_class/libraries.json
@@ -0,0 +1,12 @@
+{
+ "none": {
+ "libraries": {
+ "test": {
+ "patches": [
+ "patch.dart"
+ ],
+ "uri": "origin.dart"
+ }
+ }
+ }
+}
diff --git a/pkg/front_end/test/patching/data/abstract_class/main.dart b/pkg/front_end/test/patching/data/abstract_class/main.dart
new file mode 100644
index 0000000..faf7854
--- /dev/null
+++ b/pkg/front_end/test/patching/data/abstract_class/main.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*cfe.library: nnbd=false*/
+
+/*cfe:nnbd.library: nnbd=true*/
+
+// ignore: uri_does_not_exist
+import 'dart:test';
+
+void test(Class cls) {}
+
+main() {}
diff --git a/pkg/front_end/test/patching/data/abstract_class/origin.dart b/pkg/front_end/test/patching/data/abstract_class/origin.dart
new file mode 100644
index 0000000..c8359e2
--- /dev/null
+++ b/pkg/front_end/test/patching/data/abstract_class/origin.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*cfe.library: nnbd=false*/
+
+/*cfe:nnbd.library: nnbd=true*/
+
+/*class: Interface:
+ isAbstract,
+ kernel-members=[
+ Interface.,
+ interfaceMethod],
+ scope=[interfaceMethod]
+*/
+/*member: Interface.:initializers=[SuperInitializer]*/
+abstract class Interface {
+ void interfaceMethod();
+}
+
+/*class: Class:
+ isAbstract,
+ kernel-members=[
+ Class.,
+ classMethod],
+ scope=[classMethod]
+*/
+/*member: Class.:initializers=[SuperInitializer]*/
+abstract class Class implements Interface {
+ external void classMethod();
+}
diff --git a/pkg/front_end/test/patching/data/abstract_class/patch.dart b/pkg/front_end/test/patching/data/abstract_class/patch.dart
new file mode 100644
index 0000000..9d11f24
--- /dev/null
+++ b/pkg/front_end/test/patching/data/abstract_class/patch.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// ignore: import_internal_library
+import 'dart:_internal';
+
+@patch
+class Class {
+ @patch
+ /*member: Class.classMethod:patch*/
+ void classMethod() {}
+}
diff --git a/pkg/front_end/test/patching/patching_test.dart b/pkg/front_end/test/patching/patching_test.dart
index 1cd2220..60129e5 100644
--- a/pkg/front_end/test/patching/patching_test.dart
+++ b/pkg/front_end/test/patching/patching_test.dart
@@ -118,6 +118,7 @@
static const String error = 'message';
static const String isNonNullableByDefault = 'nnbd';
static const String patch = 'patch';
+ static const String isAbstract = 'isAbstract';
}
class PatchingDataExtractor extends CfeDataExtractor<Features> {
@@ -137,6 +138,9 @@
ClassBuilder clsBuilder = lookupClassBuilder(compilerResult, cls)!;
Features features = new Features();
+ if (cls.isAbstract) {
+ features.add(Tags.isAbstract);
+ }
clsBuilder.scope.forEach((String name, Builder builder) {
features.addElement(Tags.scope, name);
});
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 89cc303..9b57834 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -292,6 +292,7 @@
dartbug
dartdoc
dartfix
+dartino
dartlang
dashes
dc
@@ -1243,6 +1244,7 @@
substitutes
substitutor
suggests
+suite
sum
summarizing
superclasses
@@ -1383,6 +1385,7 @@
unify
uninstantiable
uninstantiated
+unintentionally
unions
uniqueness
unittest
diff --git a/pkg/front_end/tool/dart_doctest_impl.dart b/pkg/front_end/tool/dart_doctest_impl.dart
index 64d0aa7..9be9af8 100644
--- a/pkg/front_end/tool/dart_doctest_impl.dart
+++ b/pkg/front_end/tool/dart_doctest_impl.dart
@@ -826,12 +826,11 @@
SourceLibraryBuilder createDartDocTestLibrary(
SourceLoader loader, LibraryBuilder libraryBuilder) {
SourceLibraryBuilder dartDocTestLibrary = new SourceLibraryBuilder(
- dartDocTestUri,
- dartDocTestUri,
- /*packageUri*/ null,
- new ImplicitLanguageVersion(libraryBuilder.library.languageVersion),
- loader,
- null,
+ importUri: dartDocTestUri,
+ fileUri: dartDocTestUri,
+ packageLanguageVersion:
+ new ImplicitLanguageVersion(libraryBuilder.library.languageVersion),
+ loader: loader,
scope: libraryBuilder.scope.createNestedScope("dartdoctest"),
nameOrigin: libraryBuilder,
);
@@ -899,14 +898,14 @@
@override
SourceLibraryBuilder createLibraryBuilder(
- Uri uri,
- Uri fileUri,
+ {required Uri importUri,
+ required Uri fileUri,
Uri? packageUri,
- LanguageVersion packageLanguageVersion,
+ required LanguageVersion packageLanguageVersion,
SourceLibraryBuilder? origin,
kernel.Library? referencesFrom,
- bool? referenceIsPartOwner) {
- if (uri == DocTestIncrementalCompiler.dartDocTestUri) {
+ bool? referenceIsPartOwner}) {
+ if (importUri == DocTestIncrementalCompiler.dartDocTestUri) {
HybridFileSystem hfs = target.fileSystem as HybridFileSystem;
MemoryFileSystem fs = hfs.memory;
fs
@@ -915,7 +914,13 @@
return compiler.createDartDocTestLibrary(
this, compiler._dartDocTestLibraryBuilder!);
}
- return super.createLibraryBuilder(uri, fileUri, packageUri,
- packageLanguageVersion, origin, referencesFrom, referenceIsPartOwner);
+ return super.createLibraryBuilder(
+ importUri: importUri,
+ fileUri: fileUri,
+ packageUri: packageUri,
+ packageLanguageVersion: packageLanguageVersion,
+ origin: origin,
+ referencesFrom: referencesFrom,
+ referenceIsPartOwner: referenceIsPartOwner);
}
}