diff --git a/pkg/front_end/lib/src/base/incremental_compiler.dart b/pkg/front_end/lib/src/base/incremental_compiler.dart index 3889fe61d7b..856b8b022ec 100644 --- a/pkg/front_end/lib/src/base/incremental_compiler.dart +++ b/pkg/front_end/lib/src/base/incremental_compiler.dart @@ -660,6 +660,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator { } } nextGoodKernelTarget.loader.buildersCreatedWithReferences.clear(); + nextGoodKernelTarget.loader.fragmentsCreatedWithReferences.clear(); nextGoodKernelTarget.loader.hierarchyBuilder.clear(); nextGoodKernelTarget.loader.membersBuilder.clear(); nextGoodKernelTarget.loader.referenceFromIndex = null; diff --git a/pkg/front_end/lib/src/builder/type_alias_builder.dart b/pkg/front_end/lib/src/builder/type_alias_builder.dart index bb3bc0df50d..ab233fcc5f1 100644 --- a/pkg/front_end/lib/src/builder/type_alias_builder.dart +++ b/pkg/front_end/lib/src/builder/type_alias_builder.dart @@ -131,9 +131,8 @@ abstract class TypeAliasBuilderImpl extends TypeDeclarationBuilderImpl List _typeAliasesUsedInUnaliasing = []; TypeAliasBuilderImpl(List? metadata, String name, - LibraryBuilder parent, int charOffset) - : fileUri = parent.fileUri, - super(metadata, 0, name, parent, charOffset); + LibraryBuilder parent, this.fileUri, int fileOffset) + : super(metadata, 0, name, parent, fileOffset); @override String get debugName => "TypeAliasBuilder"; diff --git a/pkg/front_end/lib/src/dill/dill_library_builder.dart b/pkg/front_end/lib/src/dill/dill_library_builder.dart index 23ae761e2cc..914deb42f4f 100644 --- a/pkg/front_end/lib/src/dill/dill_library_builder.dart +++ b/pkg/front_end/lib/src/dill/dill_library_builder.dart @@ -24,6 +24,7 @@ import '../builder/name_iterator.dart'; import '../builder/never_type_declaration_builder.dart'; import '../codes/cfe_codes.dart' show LocatedMessage, Message, Severity, noLength, templateUnspecified; +import '../fragment/fragment.dart'; import '../kernel/constructor_tearoff_lowering.dart'; import '../kernel/utils.dart'; import 'dill_class_builder.dart' show DillClassBuilder; @@ -403,13 +404,17 @@ class DillLibraryBuilder extends LibraryBuilderImpl { Map? sourceBuildersMap = loader.currentSourceLoader?.buildersCreatedWithReferences; + Map? fragmentMap = + loader.currentSourceLoader?.fragmentsCreatedWithReferences; for (Reference reference in library.additionalExports) { NamedNode node = reference.node as NamedNode; - Builder declaration; + Builder? declaration = sourceBuildersMap?[reference] ?? + fragmentMap?[reference] + // Coverage-ignore(suite): Not run. + ?.builder; String name; - if (sourceBuildersMap?.containsKey(reference) == true) { + if (declaration != null) { // Coverage-ignore-block(suite): Not run. - declaration = sourceBuildersMap![reference]!; if (declaration is TypeDeclarationBuilder) { name = declaration.name; } else if (declaration is MemberBuilder) { diff --git a/pkg/front_end/lib/src/dill/dill_type_alias_builder.dart b/pkg/front_end/lib/src/dill/dill_type_alias_builder.dart index eef68e4e64c..bc9dd6d5f84 100644 --- a/pkg/front_end/lib/src/dill/dill_type_alias_builder.dart +++ b/pkg/front_end/lib/src/dill/dill_type_alias_builder.dart @@ -29,7 +29,7 @@ class DillTypeAliasBuilder extends TypeAliasBuilderImpl { DartType? thisType; DillTypeAliasBuilder(this.typedef, this.tearOffs, DillLibraryBuilder parent) - : super(null, typedef.name, parent, typedef.fileOffset); + : super(null, typedef.name, parent, typedef.fileUri, typedef.fileOffset); @override // Coverage-ignore(suite): Not run. diff --git a/pkg/front_end/lib/src/fragment/fragment.dart b/pkg/front_end/lib/src/fragment/fragment.dart new file mode 100644 index 00000000000..14cb4ee5c34 --- /dev/null +++ b/pkg/front_end/lib/src/fragment/fragment.dart @@ -0,0 +1,53 @@ +// Copyright (c) 2024, 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. + +import 'package:front_end/src/source/source_type_alias_builder.dart'; +import 'package:kernel/ast.dart'; + +import '../builder/builder.dart'; +import '../builder/declaration_builders.dart'; +import '../builder/metadata_builder.dart'; +import '../builder/type_builder.dart'; + +sealed class Fragment { + Builder get builder; +} + +class TypedefFragment implements Fragment { + final List? metadata; + final String name; + final List? typeVariables; + final TypeBuilder type; + final Uri fileUri; + final int fileOffset; + final Reference? reference; + + SourceTypeAliasBuilder? _builder; + + TypedefFragment( + {required this.metadata, + required this.name, + required this.typeVariables, + required this.type, + required this.fileUri, + required this.fileOffset, + required this.reference}); + + @override + // Coverage-ignore(suite): Not run. + SourceTypeAliasBuilder get builder { + assert(_builder != null, "Builder has not been computed for $this."); + return _builder!; + } + + void set builder(SourceTypeAliasBuilder value) { + assert( + _builder == null, // Coverage-ignore(suite): Not run. + "Builder has already been computed for $this."); + _builder = value; + } + + @override + String toString() => "$runtimeType($name,$fileUri,$fileOffset)"; +} diff --git a/pkg/front_end/lib/src/source/source_builder_factory.dart b/pkg/front_end/lib/src/source/source_builder_factory.dart index 3f2011ef0ff..44c2d230c0b 100644 --- a/pkg/front_end/lib/src/source/source_builder_factory.dart +++ b/pkg/front_end/lib/src/source/source_builder_factory.dart @@ -51,6 +51,7 @@ import '../builder/omitted_type_builder.dart'; import '../builder/synthesized_type_builder.dart'; import '../builder/type_builder.dart'; import '../builder/void_type_declaration_builder.dart'; +import '../fragment/fragment.dart'; import '../util/local_stack.dart'; import 'builder_factory.dart'; import 'name_scheme.dart'; @@ -66,7 +67,6 @@ import 'source_function_builder.dart'; import 'source_library_builder.dart'; import 'source_loader.dart' show SourceLoader; import 'source_procedure_builder.dart'; -import 'source_type_alias_builder.dart'; import 'type_parameter_scope_builder.dart'; class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult { @@ -1029,7 +1029,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult { _constructorReferences.clear(); - _addBuilderInternal(name, enumBuilder, charOffset, + _addBuilder(name, enumBuilder, charOffset, getterReference: referencesFromIndexedClass?.cls.reference); offsetMap.registerNamedDeclaration(identifier, enumBuilder); @@ -1170,7 +1170,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult { _constructorReferences.clear(); - _addBuilderInternal(className, classBuilder, nameOffset, + _addBuilder(className, classBuilder, nameOffset, getterReference: _indexedContainer?.reference); offsetMap.registerNamedDeclaration(identifier, classBuilder); } @@ -1448,7 +1448,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult { // pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart can't // handle that :( application.cls.isAnonymousMixin = !isNamedMixinApplication; - _addBuilderInternal(fullname, application, charOffset, + _addBuilder(fullname, application, charOffset, getterReference: referencesFromIndexedClass?.cls.reference); supertype = new NamedTypeBuilderImpl.fromTypeDeclarationBuilder( application, const NullabilityBuilder.omitted(), @@ -1528,7 +1528,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult { declarationFragment.bodyScope.declarationBuilder = extensionBuilder; _constructorReferences.clear(); - _addBuilderInternal(extensionBuilder.name, extensionBuilder, nameOffset, + _addBuilder(extensionBuilder.name, extensionBuilder, nameOffset, getterReference: referenceFrom?.reference); if (identifier != null) { offsetMap.registerNamedDeclaration(identifier, extensionBuilder); @@ -1593,7 +1593,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult { extensionTypeDeclarationBuilder; _constructorReferences.clear(); - _addBuilderInternal(extensionTypeDeclarationBuilder.name, + _addBuilder(extensionTypeDeclarationBuilder.name, extensionTypeDeclarationBuilder, identifier.nameOffset, getterReference: indexedContainer?.reference); offsetMap.registerNamedDeclaration( @@ -1614,16 +1614,19 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult { } } Typedef? referenceFrom = indexedLibrary?.lookupTypedef(name); - TypeAliasBuilder typedefBuilder = new SourceTypeAliasBuilder( - metadata, name, typeVariables, type, _parent, charOffset, - referenceFrom: referenceFrom); _nominalParameterNameSpaces.pop().addTypeVariables( _problemReporting, typeVariables, ownerName: name, allowNameConflict: true); // Nested declaration began in `OutlineBuilder.beginFunctionTypeAlias`. endTypedef(); - _addBuilderInternal(name, typedefBuilder, charOffset, - getterReference: referenceFrom?.reference); + _addFragment(new TypedefFragment( + metadata: metadata, + name: name, + typeVariables: typeVariables, + type: type, + fileUri: _compilationUnit.fileUri, + fileOffset: charOffset, + reference: referenceFrom?.reference)); } @override @@ -1991,7 +1994,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult { _problemReporting, typeVariables, ownerName: constructorBuilder.name, allowNameConflict: true); // TODO(johnniwinther): There is no way to pass the tear off reference here. - _addBuilderInternal(constructorName, constructorBuilder, charOffset, + _addBuilder(constructorName, constructorBuilder, charOffset, getterReference: constructorReference); if (nativeMethodName != null) { _addNativeMethod(constructorBuilder); @@ -2166,7 +2169,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult { _problemReporting, typeVariables, ownerName: identifier.name, allowNameConflict: true); - _addBuilderInternal(procedureName, procedureBuilder, charOffset, + _addBuilder(procedureName, procedureBuilder, charOffset, getterReference: constructorReference); if (nativeMethodName != null) { _addNativeMethod(procedureBuilder); @@ -2363,7 +2366,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult { _nominalParameterNameSpaces.pop().addTypeVariables( _problemReporting, typeVariables, ownerName: procedureBuilder.name, allowNameConflict: true); - _addBuilderInternal(name, procedureBuilder, charOffset, + _addBuilder(name, procedureBuilder, charOffset, getterReference: procedureReference); if (nativeMethodName != null) { _addNativeMethod(procedureBuilder); @@ -2540,7 +2543,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult { lateSetterReference: lateSetterReference, initializerToken: initializerToken, constInitializerToken: constInitializerToken); - _addBuilderInternal(name, fieldBuilder, charOffset, + _addBuilder(name, fieldBuilder, charOffset, getterReference: fieldGetterReference, setterReference: fieldSetterReference); return fieldBuilder; @@ -2790,7 +2793,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult { return _compilationUnit.loader.inferableTypes.addInferableType(); } - void _addBuilderInternal(String name, Builder declaration, int charOffset, + void _addBuilder(String name, Builder declaration, int charOffset, {Reference? getterReference, Reference? setterReference}) { if (getterReference != null) { loader.buildersCreatedWithReferences[getterReference] = declaration; @@ -2798,28 +2801,31 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult { if (setterReference != null) { loader.buildersCreatedWithReferences[setterReference] = declaration; } - _addBuilder(name, declaration, charOffset); - } - - void _addBuilder(String name, Builder declaration, int charOffset) { if (_declarationFragments.isEmpty) { - _addBuilderToLibrary(name, declaration, charOffset); + _libraryNameSpaceBuilder.addBuilder( + name, declaration, _compilationUnit.fileUri, charOffset); } else { - _addBuilderToDeclaration(name, declaration, charOffset); + _declarationFragments.current + .addBuilder(name, declaration, _compilationUnit.fileUri, charOffset); } } - void _addBuilderToLibrary(String name, Builder declaration, int charOffset) { - assert(_declarationFragments.isEmpty); - _libraryNameSpaceBuilder.addBuilder( - name, declaration, _compilationUnit.fileUri, charOffset); - } - - void _addBuilderToDeclaration( - String name, Builder declaration, int charOffset) { - assert(_declarationFragments.hasCurrent); - _declarationFragments.current - .addBuilder(name, declaration, _compilationUnit.fileUri, charOffset); + void _addFragment(Fragment fragment, + {Reference? getterReference, Reference? setterReference}) { + if (getterReference != null) { + // Coverage-ignore-block(suite): Not run. + loader.fragmentsCreatedWithReferences[getterReference] = fragment; + } + if (setterReference != null) { + // Coverage-ignore-block(suite): Not run. + loader.fragmentsCreatedWithReferences[setterReference] = fragment; + } + if (_declarationFragments.isEmpty) { + _libraryNameSpaceBuilder.addFragment(fragment); + } else { + // Coverage-ignore-block(suite): Not run. + _declarationFragments.current.addFragment(fragment); + } } @override diff --git a/pkg/front_end/lib/src/source/source_loader.dart b/pkg/front_end/lib/src/source/source_loader.dart index fe1a3b13327..758bf299915 100644 --- a/pkg/front_end/lib/src/source/source_loader.dart +++ b/pkg/front_end/lib/src/source/source_loader.dart @@ -61,6 +61,7 @@ import '../codes/cfe_codes.dart'; import '../codes/denylisted_classes.dart' show denylistedCoreClasses, denylistedTypedDataClasses; import '../dill/dill_library_builder.dart'; +import '../fragment/fragment.dart'; import '../kernel/benchmarker.dart' show BenchmarkSubdivides; import '../kernel/body_builder.dart' show BodyBuilder; import '../kernel/body_builder_context.dart'; @@ -124,6 +125,8 @@ class SourceLoader extends Loader { /// exports in dill builders. Map buildersCreatedWithReferences = {}; + Map fragmentsCreatedWithReferences = {}; + /// Used when checking whether a return type of an async function is valid. /// /// The said return type is valid if it's a subtype of [futureOfBottom]. diff --git a/pkg/front_end/lib/src/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/source/source_type_alias_builder.dart index 94133d8e178..8be38bef9ce 100644 --- a/pkg/front_end/lib/src/source/source_type_alias_builder.dart +++ b/pkg/front_end/lib/src/source/source_type_alias_builder.dart @@ -45,23 +45,22 @@ class SourceTypeAliasBuilder extends TypeAliasBuilderImpl { Map? tearOffs; SourceTypeAliasBuilder( - List? metadata, - String name, - this._typeVariables, - this.type, - SourceLibraryBuilder parent, - int charOffset, - {Typedef? typedef, - Typedef? referenceFrom}) - : typedef = typedef ?? - (new Typedef(name, null, - typeParameters: - NominalVariableBuilder.typeParametersFromBuilders( - _typeVariables), - fileUri: parent.fileUri, - reference: referenceFrom?.reference) - ..fileOffset = charOffset), - super(metadata, name, parent, charOffset); + {required List? metadata, + required String name, + required List? typeVariables, + required this.type, + required SourceLibraryBuilder enclosingLibraryBuilder, + required Uri fileUri, + required int fileOffset, + required Reference? reference}) + : typedef = new Typedef(name, null, + typeParameters: NominalVariableBuilder.typeParametersFromBuilders( + typeVariables), + fileUri: fileUri, + reference: reference) + ..fileOffset = fileOffset, + _typeVariables = typeVariables, + super(metadata, name, enclosingLibraryBuilder, fileUri, fileOffset); @override SourceLibraryBuilder get libraryBuilder => diff --git a/pkg/front_end/lib/src/source/type_parameter_scope_builder.dart b/pkg/front_end/lib/src/source/type_parameter_scope_builder.dart index d3986faecb7..116e86a9224 100644 --- a/pkg/front_end/lib/src/source/type_parameter_scope_builder.dart +++ b/pkg/front_end/lib/src/source/type_parameter_scope_builder.dart @@ -13,25 +13,71 @@ import '../builder/function_builder.dart'; import '../builder/member_builder.dart'; import '../builder/prefix_builder.dart'; import '../builder/type_builder.dart'; +import '../fragment/fragment.dart'; import 'name_scheme.dart'; import 'source_extension_builder.dart'; import 'source_field_builder.dart'; import 'source_library_builder.dart'; +import 'source_type_alias_builder.dart'; + +sealed class _Added { + _AddBuilder getAddBuilder(Builder parent); +} + +class _AddedBuilder implements _Added { + final _AddBuilder builder; + + _AddedBuilder(this.builder); + + @override + _AddBuilder getAddBuilder(Builder parent) => builder; +} + +class _AddedFragment implements _Added { + final Fragment fragment; + + _AddedFragment(this.fragment); + + @override + _AddBuilder getAddBuilder(Builder parent) { + Fragment fragment = this.fragment; + switch (fragment) { + case TypedefFragment(): + SourceTypeAliasBuilder typedefBuilder = new SourceTypeAliasBuilder( + metadata: fragment.metadata, + name: fragment.name, + typeVariables: fragment.typeVariables, + type: fragment.type, + enclosingLibraryBuilder: parent as SourceLibraryBuilder, + fileUri: fragment.fileUri, + fileOffset: fragment.fileOffset, + reference: fragment.reference); + fragment.builder = typedefBuilder; + return new _AddBuilder(fragment.name, typedefBuilder, fragment.fileUri, + fragment.fileOffset); + } + } +} class LibraryNameSpaceBuilder { final Map> augmentations = {}; final Map> setterAugmentations = {}; - List<_AddBuilder> _addedBuilders = []; + List<_Added> _added = []; void addBuilder( String name, Builder declaration, Uri fileUri, int charOffset) { - _addedBuilders.add(new _AddBuilder(name, declaration, fileUri, charOffset)); + _added.add(new _AddedBuilder( + new _AddBuilder(name, declaration, fileUri, charOffset))); + } + + void addFragment(Fragment fragment) { + _added.add(new _AddedFragment(fragment)); } void includeBuilders(LibraryNameSpaceBuilder other) { - _addedBuilders.addAll(other._addedBuilders); + _added.addAll(other._added); } NameSpace toNameSpace( @@ -151,7 +197,8 @@ class LibraryNameSpaceBuilder { members[name] = declaration; } - for (_AddBuilder addBuilder in _addedBuilders) { + for (_Added added in _added) { + _AddBuilder addBuilder = added.getAddBuilder(_parent); _addBuilder(addBuilder.name, addBuilder.declaration, addBuilder.fileUri, addBuilder.charOffset); } @@ -224,7 +271,7 @@ sealed class DeclarationFragment { final int nameOffset; final LookupScope typeParameterScope; final DeclarationBuilderScope bodyScope = new DeclarationBuilderScope(); - final List<_AddBuilder> _addedBuilders = []; + final List<_Added> _added = []; List? primaryConstructorFields; @@ -249,13 +296,19 @@ sealed class DeclarationFragment { void addBuilder( String name, Builder declaration, Uri fileUri, int charOffset) { - _addedBuilders.add(new _AddBuilder(name, declaration, fileUri, charOffset)); + _added.add(new _AddedBuilder( + new _AddBuilder(name, declaration, fileUri, charOffset))); + } + + // Coverage-ignore(suite): Not run. + void addFragment(Fragment fragment) { + _added.add(new _AddedFragment(fragment)); } DeclarationNameSpaceBuilder toDeclarationNameSpaceBuilder( NominalParameterNameSpace? nominalParameterNameSpace) { return new DeclarationNameSpaceBuilder._( - name, nominalParameterNameSpace, _addedBuilders); + name, nominalParameterNameSpace, _added); } } @@ -416,15 +469,15 @@ class _AddBuilder { class DeclarationNameSpaceBuilder { final String _name; final NominalParameterNameSpace? _nominalParameterNameSpace; - final List<_AddBuilder> _addedBuilders; + final List<_Added> _added; DeclarationNameSpaceBuilder.empty() : _name = '', _nominalParameterNameSpace = null, - _addedBuilders = const []; + _added = const []; DeclarationNameSpaceBuilder._( - this._name, this._nominalParameterNameSpace, this._addedBuilders); + this._name, this._nominalParameterNameSpace, this._added); void _addBuilder( ProblemReporting problemReporting, @@ -522,9 +575,10 @@ class DeclarationNameSpaceBuilder { Map setables = {}; Map constructors = {}; - for (_AddBuilder addedBuilder in _addedBuilders) { + for (_Added added in _added) { + _AddBuilder addBuilder = added.getAddBuilder(parent); _addBuilder( - problemReporting, getables, setables, constructors, addedBuilder); + problemReporting, getables, setables, constructors, addBuilder); } void setParent(MemberBuilder? member) {