From b3e1eec36f1551d00bca7caea883ff7ccc73c435 Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Thu, 12 Sep 2024 14:03:30 +0000 Subject: [PATCH] [cfe] Create SourceTypeAliasBuilder via fragments This adds TypedefFragment as the first Fragment class and creates this instead of the SourceTypeAliasBuilder during outline builder. The SourceTypeAliasBuilder is created when the library name space is built. Change-Id: Ib35a6f3b501ab1732cec84f5dcbd95ac7d54f5f8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/384741 Reviewed-by: Jens Johansen Commit-Queue: Johnni Winther --- .../lib/src/base/incremental_compiler.dart | 1 + .../lib/src/builder/type_alias_builder.dart | 5 +- .../lib/src/dill/dill_library_builder.dart | 11 ++- .../lib/src/dill/dill_type_alias_builder.dart | 2 +- pkg/front_end/lib/src/fragment/fragment.dart | 53 +++++++++++++ .../src/source/source_builder_factory.dart | 72 +++++++++-------- .../lib/src/source/source_loader.dart | 3 + .../src/source/source_type_alias_builder.dart | 33 ++++---- .../source/type_parameter_scope_builder.dart | 78 ++++++++++++++++--- 9 files changed, 189 insertions(+), 69 deletions(-) create mode 100644 pkg/front_end/lib/src/fragment/fragment.dart 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) {