diff --git a/pkg/front_end/lib/src/fragment/constructor/declaration.dart b/pkg/front_end/lib/src/fragment/constructor/declaration.dart index 9639a2dce9d..a3c02d2e63f 100644 --- a/pkg/front_end/lib/src/fragment/constructor/declaration.dart +++ b/pkg/front_end/lib/src/fragment/constructor/declaration.dart @@ -11,6 +11,7 @@ import 'package:kernel/type_environment.dart'; import '../../base/constant_context.dart'; import '../../base/identifiers.dart'; import '../../base/local_scope.dart'; +import '../../base/messages.dart'; import '../../base/name_space.dart'; import '../../base/scope.dart'; import '../../builder/constructor_builder.dart'; @@ -23,19 +24,18 @@ import '../../builder/type_builder.dart'; import '../../builder/variable_builder.dart'; import '../../kernel/body_builder.dart'; import '../../kernel/body_builder_context.dart'; -import '../../kernel/internal_ast.dart'; import '../../kernel/kernel_helper.dart'; import '../../kernel/type_algorithms.dart'; import '../../source/name_scheme.dart'; import '../../source/source_class_builder.dart'; import '../../source/source_constructor_builder.dart'; -import '../../source/source_extension_builder.dart'; import '../../source/source_extension_type_declaration_builder.dart'; import '../../source/source_function_builder.dart'; import '../../source/source_library_builder.dart'; import '../../source/source_loader.dart'; import '../../source/source_member_builder.dart'; import '../../source/source_type_parameter_builder.dart'; +import '../../source/type_parameter_scope_builder.dart'; import '../fragment.dart'; import 'encoding.dart'; @@ -55,9 +55,14 @@ abstract class ConstructorDeclaration { List get initializers; - void createEncoding(SourceConstructorBuilder builder); - - void registerInferable(Inferable inferable); + void createEncoding({ + required ProblemReporting problemReporting, + required SourceLoader loader, + required DeclarationBuilder declarationBuilder, + required SourceConstructorBuilder constructorBuilder, + required List unboundNominalParameters, + required ConstructorEncodingStrategy encodingStrategy, + }); void buildOutlineNodes( BuildNodesCallback f, { @@ -593,15 +598,27 @@ mixin _ConstructorDeclarationMixin } mixin _ConstructorEncodingMixin - implements ConstructorDeclaration, ConstructorFragmentDeclaration { + implements + ConstructorDeclaration, + _ConstructorDeclarationMixin, + ConstructorFragmentDeclaration { ConstructorEncoding get _encoding; + String? get _nativeMethodName; + + @override + late final bool _hasSuperInitializingFormals = + formals?.any((formal) => formal.isSuperInitializingFormal) ?? false; + @override FunctionNode get function => _encoding.function; @override List get initializers => _encoding.initializers; + @override + bool get isRedirecting => _encoding.isRedirecting; + @override void prepareInitializers() { _encoding.prepareInitializers(); @@ -626,15 +643,12 @@ mixin _ConstructorEncodingMixin void markAsErroneous() { _encoding.markAsErroneous(); } -} -mixin _RegularConstructorDeclarationMixin - implements - _ConstructorDeclarationMixin, - _ConstructorEncodingMixin, - InferredTypeListener { @override - RegularConstructorEncoding get _encoding; + VariableDeclaration? get thisVariable => _encoding.thisVariable; + + @override + List? get thisTypeParameters => _encoding.thisTypeParameters; @override void registerFunctionBody(Statement value) { @@ -647,36 +661,10 @@ mixin _RegularConstructorDeclarationMixin } @override - VariableDeclaration? get thisVariable => null; - - @override - List? get thisTypeParameters => null; - - @override - Substitution computeFieldTypeSubstitution( - DeclarationBuilder declarationBuilder) { - // Nothing to substitute. Regular generative constructors don't have their - // own type parameters. - return Substitution.empty; + void buildBody() { + _encoding.buildBody(); } - @override - void buildBody() {} - - @override - bool get isRedirecting { - for (Initializer initializer in initializers) { - if (initializer is RedirectingInitializer) { - return true; - } - } - return false; - } - - @override - late final bool _hasSuperInitializingFormals = - formals?.any((formal) => formal.isSuperInitializingFormal) ?? false; - @override void _addSuperParameterDefaultValueCloners( {required List delayedDefaultValueCloners, @@ -692,6 +680,24 @@ mixin _RegularConstructorDeclarationMixin libraryBuilder: libraryBuilder); } + @override + Substitution computeFieldTypeSubstitution( + DeclarationBuilder declarationBuilder) { + return _encoding.computeFieldTypeSubstitution( + declarationBuilder, _typeParameters); + } + + @override + void becomeNative(SourceLoader loader) { + _encoding.becomeNative(loader, _nativeMethodName!); + } +} + +mixin _RegularConstructorDeclarationMixin + implements + _ConstructorDeclarationMixin, + _ConstructorEncodingMixin, + InferredTypeListener { void _buildTypeParametersAndFormals({ required SourceLibraryBuilder libraryBuilder, required DeclarationBuilder declarationBuilder, @@ -729,8 +735,7 @@ mixin _RegularConstructorDeclarationMixin function.returnType = type; } - @override - void registerInferable(Inferable inferable) { + void _registerInferable(Inferable inferable) { returnType.registerInferredTypeListener(this); if (formals != null) { for (FormalParameterBuilder formal in formals!) { @@ -749,41 +754,25 @@ class RegularConstructorDeclaration _RegularConstructorDeclarationMixin implements ConstructorDeclaration, ConstructorFragmentDeclaration { final ConstructorFragment _fragment; - final List? _syntheticFormals; @override - final RegularConstructorEncoding _encoding; + late final ConstructorEncoding _encoding; + + late final List? _formals; @override - final List? _typeParameters; + late final List? _typeParameters; @override Token? _beginInitializers; - RegularConstructorDeclaration(this._fragment, - {required List? syntheticFormals, - required List? typeParameters, - // TODO(johnniwinther): Create a separate [ConstructorDeclaration] for - // enum constructors. - required bool isEnumConstructor}) - : _typeParameters = typeParameters, - _syntheticFormals = syntheticFormals, - _beginInitializers = _fragment.beginInitializers, - _encoding = new RegularConstructorEncoding( - isExternal: _fragment.modifiers.isExternal, - isEnumConstructor: isEnumConstructor) { + RegularConstructorDeclaration(this._fragment) + : _beginInitializers = _fragment.beginInitializers { _fragment.declaration = this; } @override - void createEncoding(SourceConstructorBuilder builder) { - _fragment.builder = builder; - } - - @override - void becomeNative(SourceLoader loader) { - _encoding.becomeNative(loader, _fragment.nativeMethodName!); - } + String? get _nativeMethodName => _fragment.nativeMethodName; @override LookupScope get _typeParameterScope => _fragment.typeParameterScope; @@ -795,17 +784,51 @@ class RegularConstructorDeclaration @override OmittedTypeBuilder get returnType => _fragment.returnType; - @override - late final List? formals = _syntheticFormals != null - ? [..._syntheticFormals, ...?_fragment.formals] - : _fragment.formals; - @override bool get isConst => _fragment.modifiers.isConst; @override bool get isExternal => _fragment.modifiers.isExternal; + @override + int get fileOffset => _fragment.fullNameOffset; + + @override + Uri get fileUri => _fragment.fileUri; + + @override + void createEncoding({ + required ProblemReporting problemReporting, + required SourceLoader loader, + required DeclarationBuilder declarationBuilder, + required SourceConstructorBuilder constructorBuilder, + required List unboundNominalParameters, + required ConstructorEncodingStrategy encodingStrategy, + }) { + _fragment.builder = constructorBuilder; + _typeParameters = encodingStrategy.createTypeParameters( + declarationBuilder: declarationBuilder, + declarationTypeParameterFragments: + _fragment.enclosingDeclaration.typeParameters, + typeParameters: createNominalParameterBuilders( + _fragment.typeParameters, unboundNominalParameters), + unboundNominalParameters: unboundNominalParameters); + _fragment.typeParameterNameSpace.addTypeParameters( + problemReporting, _typeParameters, + ownerName: _fragment.name, allowNameConflict: true); + _formals = encodingStrategy.createFormals( + loader: loader, + formals: _fragment.formals, + fileUri: _fragment.fileUri, + fileOffset: _fragment.fullNameOffset); + _encoding = encodingStrategy.createEncoding( + isExternal: _fragment.modifiers.isExternal); + _registerInferable(constructorBuilder); + } + + @override + List? get formals => _formals; + @override void buildOutlineNodes(BuildNodesCallback f, {required SourceConstructorBuilder constructorBuilder, @@ -816,8 +839,7 @@ class RegularConstructorDeclaration _encoding.buildOutlineNodes(f, constructorBuilder: constructorBuilder, libraryBuilder: libraryBuilder, - declarationBuilder: - constructorBuilder.declarationBuilder as SourceClassBuilder, + declarationBuilder: constructorBuilder.declarationBuilder, name: _fragment.name, nameScheme: nameScheme, constructorReferences: constructorReferences, @@ -868,129 +890,6 @@ class RegularConstructorDeclaration classHierarchy: classHierarchy, typeParameterScope: _fragment.typeParameterScope); } - - @override - int get fileOffset => _fragment.fullNameOffset; - - @override - Uri get fileUri => _fragment.fileUri; -} - -// Coverage-ignore(suite): Not run. -class PrimaryConstructorDeclaration - with - _ConstructorDeclarationMixin, - _ConstructorEncodingMixin, - _RegularConstructorDeclarationMixin - implements ConstructorDeclaration, ConstructorFragmentDeclaration { - final PrimaryConstructorFragment _fragment; - - @override - final RegularConstructorEncoding _encoding; - - @override - Token? _beginInitializers; - - PrimaryConstructorDeclaration(this._fragment) - : _beginInitializers = _fragment.beginInitializers, - _encoding = new RegularConstructorEncoding( - isExternal: _fragment.modifiers.isExternal, - isEnumConstructor: false) { - _fragment.declaration = this; - } - - @override - void createEncoding(SourceConstructorBuilder builder) { - _fragment.builder = builder; - } - - @override - void becomeNative(SourceLoader loader) { - throw new UnsupportedError("$runtimeType.becomeNative()"); - } - - @override - LookupScope get _typeParameterScope => _fragment.typeParameterScope; - - @override - OmittedTypeBuilder get returnType => _fragment.returnType; - - @override - List? get metadata => null; - - @override - List? get formals => _fragment.formals; - - @override - List? get _typeParameters => null; - - @override - bool get isConst => _fragment.modifiers.isConst; - - @override - bool get isExternal => _fragment.modifiers.isExternal; - - @override - void buildOutlineNodes(BuildNodesCallback f, - {required SourceConstructorBuilder constructorBuilder, - required SourceLibraryBuilder libraryBuilder, - required NameScheme nameScheme, - required ConstructorReferences? constructorReferences, - required List delayedDefaultValueCloners}) { - _encoding.buildOutlineNodes(f, - constructorBuilder: constructorBuilder, - libraryBuilder: libraryBuilder, - declarationBuilder: - constructorBuilder.declarationBuilder as SourceClassBuilder, - name: _fragment.name, - nameScheme: nameScheme, - constructorReferences: constructorReferences, - fileUri: _fragment.fileUri, - startOffset: _fragment.startOffset, - fileOffset: _fragment.fileOffset, - formalsOffset: _fragment.formalsOffset, - // TODO(johnniwinther): Provide `endOffset`. - endOffset: _fragment.formalsOffset, - isSynthetic: false, - forAbstractClassOrEnumOrMixin: _fragment.forAbstractClassOrMixin, - isConst: _fragment.modifiers.isConst, - returnType: returnType, - typeParameters: _typeParameters, - formals: formals, - delayedDefaultValueCloners: delayedDefaultValueCloners); - } - - @override - void _buildMetadataForOutlineExpressions( - {required Iterable annotatables, - required Uri annotatablesFileUri, - required SourceLibraryBuilder libraryBuilder, - required DeclarationBuilder declarationBuilder, - required SourceConstructorBuilder constructorBuilder, - required BodyBuilderContext bodyBuilderContext, - required ClassHierarchy classHierarchy}) { - // There is no metadata on a primary constructor. - } - - @override - void _buildTypeParametersAndFormalsForOutlineExpressions( - {required SourceLibraryBuilder libraryBuilder, - required DeclarationBuilder declarationBuilder, - required BodyBuilderContext bodyBuilderContext, - required ClassHierarchy classHierarchy}) { - _buildTypeParametersAndFormals( - libraryBuilder: libraryBuilder, - declarationBuilder: declarationBuilder, - bodyBuilderContext: bodyBuilderContext, - classHierarchy: classHierarchy, - typeParameterScope: _fragment.typeParameterScope); - } - - @override - int get fileOffset => _fragment.fileOffset; - - @override - Uri get fileUri => _fragment.fileUri; } class DefaultEnumConstructorDeclaration @@ -1012,8 +911,7 @@ class DefaultEnumConstructorDeclaration final List formals; @override - final RegularConstructorEncoding _encoding = new RegularConstructorEncoding( - isExternal: false, isEnumConstructor: true); + late final ConstructorEncoding _encoding; /// The scope in which to build the formal parameters. final LookupScope _lookupScope; @@ -1036,8 +934,17 @@ class DefaultEnumConstructorDeclaration _beginInitializers = new Token.eof(-1); @override - // Coverage-ignore(suite): Not run. - void createEncoding(SourceConstructorBuilder builder) {} + void createEncoding({ + required ProblemReporting problemReporting, + required SourceLoader loader, + required DeclarationBuilder declarationBuilder, + required SourceConstructorBuilder constructorBuilder, + required List unboundNominalParameters, + required ConstructorEncodingStrategy encodingStrategy, + }) { + _encoding = encodingStrategy.createEncoding(isExternal: false); + _registerInferable(constructorBuilder); + } @override void becomeNative(SourceLoader loader) { @@ -1070,8 +977,7 @@ class DefaultEnumConstructorDeclaration _encoding.buildOutlineNodes(f, constructorBuilder: constructorBuilder, libraryBuilder: libraryBuilder, - declarationBuilder: - constructorBuilder.declarationBuilder as SourceClassBuilder, + declarationBuilder: constructorBuilder.declarationBuilder, name: '', nameScheme: nameScheme, constructorReferences: constructorReferences, @@ -1114,84 +1020,67 @@ class DefaultEnumConstructorDeclaration classHierarchy: classHierarchy, typeParameterScope: _lookupScope); } + + @override + // Coverage-ignore(suite): Not run. + String? get _nativeMethodName => null; } -mixin _ExtensionTypeConstructorDeclarationMixin +class PrimaryConstructorDeclaration + with _ConstructorDeclarationMixin, _ConstructorEncodingMixin implements - _ConstructorDeclarationMixin, - _ConstructorEncodingMixin, + ConstructorDeclaration, + ConstructorFragmentDeclaration, InferredTypeListener { - @override - ExtensionTypeConstructorEncoding get _encoding; + final PrimaryConstructorFragment _fragment; + + late final List? _formals; @override - void registerFunctionBody(Statement value) { - _encoding.registerFunctionBody(value); + late final List? _typeParameters; + + @override + late final ConstructorEncoding _encoding; + + @override + Token? _beginInitializers; + + PrimaryConstructorDeclaration(this._fragment) + : _beginInitializers = _fragment.beginInitializers { + _fragment.declaration = this; } @override - void registerNoBodyConstructor() { - _encoding.registerNoBodyConstructor(); - } + // Coverage-ignore(suite): Not run. + String? get _nativeMethodName => null; @override - VariableDeclaration? get thisVariable => _encoding.thisVariable; - - @override - List? get thisTypeParameters => _encoding.thisTypeParameters; - - @override - void becomeNative(SourceLoader loader) { - throw new UnsupportedError("$runtimeType.becomeNative()"); - } - - @override - Substitution computeFieldTypeSubstitution( - DeclarationBuilder declarationBuilder) { - if (_typeParameters != null) { - assert( - declarationBuilder.typeParameters!.length == _typeParameters?.length); - return Substitution.fromPairs( - (declarationBuilder as SourceExtensionTypeDeclarationBuilder) - .extensionTypeDeclaration - .typeParameters, - new List.generate( - declarationBuilder.typeParameters!.length, - (int index) => new TypeParameterType.withDefaultNullability( - function.typeParameters[index]))); - } else { - return Substitution.empty; - } - } - - @override - void buildBody() { - _encoding.buildBody(); - } - - @override - bool get isRedirecting { - for (Initializer initializer in initializers) { - if (initializer is ExtensionTypeRedirectingInitializer) { - return true; - } - } - return false; - } - - @override - late final bool _hasSuperInitializingFormals = - formals?.any((formal) => formal.isSuperInitializingFormal) ?? false; - - @override - void _addSuperParameterDefaultValueCloners( - {required List delayedDefaultValueCloners, - required Member superTarget, - required List? positionalSuperParameters, - required List? namedSuperParameters, - required SourceLibraryBuilder libraryBuilder}) { - throw new UnsupportedError( - '$runtimeType.addSuperParameterDefaultValueCloners'); + void createEncoding({ + required ProblemReporting problemReporting, + required SourceLoader loader, + required DeclarationBuilder declarationBuilder, + required SourceConstructorBuilder constructorBuilder, + required List unboundNominalParameters, + required ConstructorEncodingStrategy encodingStrategy, + }) { + _fragment.builder = constructorBuilder; + _typeParameters = encodingStrategy.createTypeParameters( + declarationBuilder: declarationBuilder, + declarationTypeParameterFragments: + _fragment.enclosingDeclaration.typeParameters, + typeParameters: null, + unboundNominalParameters: unboundNominalParameters); + _fragment.typeParameterNameSpace.addTypeParameters( + problemReporting, _typeParameters, + ownerName: _fragment.name, allowNameConflict: true); + _formals = encodingStrategy.createFormals( + loader: loader, + formals: _fragment.formals, + fileUri: _fragment.fileUri, + fileOffset: _fragment.fileOffset); + _encoding = encodingStrategy.createEncoding( + isExternal: _fragment.modifiers.isExternal); + _registerInferable(constructorBuilder); } void _buildTypeParametersAndFormals({ @@ -1231,167 +1120,18 @@ mixin _ExtensionTypeConstructorDeclarationMixin function.returnType = type; } - @override - void registerInferable(Inferable inferable) { + void _registerInferable(Inferable inferable) { returnType.registerInferredTypeListener(this); if (formals != null) { for (FormalParameterBuilder formal in formals!) { - if (formal.isInitializingFormal || formal.isSuperInitializingFormal) { + if (formal.isInitializingFormal || + // Coverage-ignore(suite): Not run. + formal.isSuperInitializingFormal) { formal.type.registerInferable(inferable); } } } } -} - -class ExtensionTypeConstructorDeclaration - with - _ConstructorDeclarationMixin, - _ConstructorEncodingMixin, - _ExtensionTypeConstructorDeclarationMixin - implements ConstructorDeclaration, ConstructorFragmentDeclaration { - final ConstructorFragment _fragment; - - @override - final List? _typeParameters; - - @override - final ExtensionTypeConstructorEncoding _encoding; - - @override - Token? _beginInitializers; - - ExtensionTypeConstructorDeclaration(this._fragment, - {required List? typeParameters}) - : _typeParameters = typeParameters, - _beginInitializers = _fragment.beginInitializers, - _encoding = new ExtensionTypeConstructorEncoding( - isExternal: _fragment.modifiers.isExternal) { - _fragment.declaration = this; - } - - @override - void createEncoding(SourceConstructorBuilder builder) { - _fragment.builder = builder; - } - - @override - LookupScope get _typeParameterScope => _fragment.typeParameterScope; - - @override - // Coverage-ignore(suite): Not run. - List? get metadata => _fragment.metadata; - - @override - OmittedTypeBuilder get returnType => _fragment.returnType; - - @override - List? get formals => _fragment.formals; - - @override - bool get isConst => _fragment.modifiers.isConst; - - @override - bool get isExternal => _fragment.modifiers.isExternal; - - @override - void buildOutlineNodes(BuildNodesCallback f, - {required SourceConstructorBuilder constructorBuilder, - required SourceLibraryBuilder libraryBuilder, - required NameScheme nameScheme, - required ConstructorReferences? constructorReferences, - required List delayedDefaultValueCloners}) { - _encoding.buildOutlineNodes(f, - constructorBuilder: constructorBuilder, - libraryBuilder: libraryBuilder, - declarationBuilder: constructorBuilder.declarationBuilder - as SourceExtensionTypeDeclarationBuilder, - name: _fragment.name, - nameScheme: nameScheme, - constructorReferences: constructorReferences, - fileUri: _fragment.fileUri, - fileOffset: _fragment.fullNameOffset, - formalsOffset: _fragment.formalsOffset, - endOffset: _fragment.endOffset, - forAbstractClassOrEnumOrMixin: _fragment.forAbstractClassOrMixin, - isConst: _fragment.modifiers.isConst, - returnType: returnType, - typeParameters: _typeParameters, - formals: formals, - delayedDefaultValueCloners: delayedDefaultValueCloners); - } - - @override - void _buildMetadataForOutlineExpressions( - {required Iterable annotatables, - required Uri annotatablesFileUri, - required SourceLibraryBuilder libraryBuilder, - required DeclarationBuilder declarationBuilder, - required SourceConstructorBuilder constructorBuilder, - required BodyBuilderContext bodyBuilderContext, - required ClassHierarchy classHierarchy}) { - for (Annotatable annotatable in annotatables) { - MetadataBuilder.buildAnnotations( - annotatable: annotatable, - annotatableFileUri: annotatablesFileUri, - metadata: _fragment.metadata, - bodyBuilderContext: bodyBuilderContext, - libraryBuilder: libraryBuilder, - scope: _fragment.enclosingScope); - } - } - - @override - void _buildTypeParametersAndFormalsForOutlineExpressions( - {required SourceLibraryBuilder libraryBuilder, - required DeclarationBuilder declarationBuilder, - required BodyBuilderContext bodyBuilderContext, - required ClassHierarchy classHierarchy}) { - _buildTypeParametersAndFormals( - libraryBuilder: libraryBuilder, - declarationBuilder: declarationBuilder, - bodyBuilderContext: bodyBuilderContext, - classHierarchy: classHierarchy, - typeParameterScope: _fragment.typeParameterScope); - } - - @override - int get fileOffset => _fragment.fullNameOffset; - - @override - Uri get fileUri => _fragment.fileUri; -} - -class ExtensionTypePrimaryConstructorDeclaration - with - _ConstructorDeclarationMixin, - _ConstructorEncodingMixin, - _ExtensionTypeConstructorDeclarationMixin - implements ConstructorDeclaration, ConstructorFragmentDeclaration { - final PrimaryConstructorFragment _fragment; - - @override - final List? _typeParameters; - - @override - final ExtensionTypeConstructorEncoding _encoding; - - @override - Token? _beginInitializers; - - ExtensionTypePrimaryConstructorDeclaration(this._fragment, - {required List? typeParameters}) - : _typeParameters = typeParameters, - _beginInitializers = _fragment.beginInitializers, - _encoding = new ExtensionTypeConstructorEncoding( - isExternal: _fragment.modifiers.isExternal) { - _fragment.declaration = this; - } - - @override - void createEncoding(SourceConstructorBuilder builder) { - _fragment.builder = builder; - } @override LookupScope get _typeParameterScope => _fragment.typeParameterScope; @@ -1404,7 +1144,7 @@ class ExtensionTypePrimaryConstructorDeclaration OmittedTypeBuilder get returnType => _fragment.returnType; @override - List? get formals => _fragment.formals; + List? get formals => _formals; @override bool get isConst => _fragment.modifiers.isConst; @@ -1429,11 +1169,13 @@ class ExtensionTypePrimaryConstructorDeclaration constructorReferences: constructorReferences, fileUri: _fragment.fileUri, fileOffset: _fragment.fileOffset, + startOffset: _fragment.startOffset, formalsOffset: _fragment.formalsOffset, // TODO(johnniwinther): Provide `endOffset`. endOffset: _fragment.formalsOffset, forAbstractClassOrEnumOrMixin: _fragment.forAbstractClassOrMixin, isConst: _fragment.modifiers.isConst, + isSynthetic: false, returnType: returnType, typeParameters: _typeParameters, formals: formals, @@ -1473,267 +1215,6 @@ class ExtensionTypePrimaryConstructorDeclaration Uri get fileUri => _fragment.fileUri; } -mixin _ExtensionConstructorDeclarationMixin - implements - _ConstructorDeclarationMixin, - _ConstructorEncodingMixin, - InferredTypeListener { - @override - ExtensionConstructorEncoding get _encoding; - - @override - // Coverage-ignore(suite): Not run. - void registerFunctionBody(Statement value) { - _encoding.registerFunctionBody(value); - } - - @override - // Coverage-ignore(suite): Not run. - void registerNoBodyConstructor() { - _encoding.registerNoBodyConstructor(); - } - - @override - // Coverage-ignore(suite): Not run. - VariableDeclaration? get thisVariable => _encoding.thisVariable; - - @override - // Coverage-ignore(suite): Not run. - List? get thisTypeParameters => _encoding.thisTypeParameters; - - @override - void becomeNative(SourceLoader loader) { - throw new UnsupportedError("$runtimeType.becomeNative()"); - } - - @override - // Coverage-ignore(suite): Not run. - Substitution computeFieldTypeSubstitution( - DeclarationBuilder declarationBuilder) { - if (_typeParameters != null) { - assert( - declarationBuilder.typeParameters!.length == _typeParameters?.length); - return Substitution.fromPairs( - (declarationBuilder as SourceExtensionTypeDeclarationBuilder) - .extensionTypeDeclaration - .typeParameters, - new List.generate( - declarationBuilder.typeParameters!.length, - (int index) => new TypeParameterType.withDefaultNullability( - function.typeParameters[index]))); - } else { - return Substitution.empty; - } - } - - @override - void buildBody() { - _encoding.buildBody(); - } - - @override - // Coverage-ignore(suite): Not run. - bool get isRedirecting { - for (Initializer initializer in initializers) { - if (initializer is ExtensionTypeRedirectingInitializer) { - return true; - } - } - return false; - } - - @override - late final bool _hasSuperInitializingFormals = - formals?.any((formal) => formal.isSuperInitializingFormal) ?? false; - - @override - void _addSuperParameterDefaultValueCloners( - {required List delayedDefaultValueCloners, - required Member superTarget, - required List? positionalSuperParameters, - required List? namedSuperParameters, - required SourceLibraryBuilder libraryBuilder}) { - throw new UnsupportedError( - '$runtimeType.addSuperParameterDefaultValueCloners'); - } - - // Coverage-ignore(suite): Not run. - void _buildTypeParametersAndFormals({ - required SourceLibraryBuilder libraryBuilder, - required DeclarationBuilder declarationBuilder, - required BodyBuilderContext bodyBuilderContext, - required ClassHierarchy classHierarchy, - required LookupScope typeParameterScope, - }) { - if (_typeParameters != null) { - for (int i = 0; i < _typeParameters!.length; i++) { - _typeParameters![i].buildOutlineExpressions( - libraryBuilder, bodyBuilderContext, classHierarchy); - } - } - - if (formals != null) { - // For const constructors we need to include default parameter values - // into the outline. For all other formals we need to call - // buildOutlineExpressions to clear initializerToken to prevent - // consuming too much memory. - for (FormalParameterBuilder formal in formals!) { - formal.buildOutlineExpressions(libraryBuilder, declarationBuilder, - scope: typeParameterScope, buildDefaultValue: true); - } - } - } - - @override - // Coverage-ignore(suite): Not run. - BodyBuilderContext createBodyBuilderContext( - SourceConstructorBuilder constructorBuilder) { - return _encoding.createBodyBuilderContext(constructorBuilder, this); - } - - @override - void onInferredType(DartType type) { - function.returnType = type; - } - - @override - void registerInferable(Inferable inferable) { - returnType.registerInferredTypeListener(this); - if (formals != null) { - for (FormalParameterBuilder formal in formals!) { - if (formal.isInitializingFormal || formal.isSuperInitializingFormal) { - // Coverage-ignore-block(suite): Not run. - formal.type.registerInferable(inferable); - } - } - } - } -} - -class ExtensionConstructorDeclaration - with - _ConstructorDeclarationMixin, - _ConstructorEncodingMixin, - _ExtensionConstructorDeclarationMixin - implements ConstructorDeclaration, ConstructorFragmentDeclaration { - final ConstructorFragment _fragment; - - @override - final List? _typeParameters; - - @override - final ExtensionConstructorEncoding _encoding; - - @override - Token? _beginInitializers; - - ExtensionConstructorDeclaration(this._fragment, - {required List? typeParameters}) - : _typeParameters = typeParameters, - _beginInitializers = _fragment.beginInitializers, - _encoding = new ExtensionConstructorEncoding( - isExternal: _fragment.modifiers.isExternal) { - _fragment.declaration = this; - } - - @override - void createEncoding(SourceConstructorBuilder builder) { - _fragment.builder = builder; - } - - @override - // Coverage-ignore(suite): Not run. - LookupScope get _typeParameterScope => _fragment.typeParameterScope; - - @override - // Coverage-ignore(suite): Not run. - List? get metadata => _fragment.metadata; - - @override - OmittedTypeBuilder get returnType => _fragment.returnType; - - @override - List? get formals => _fragment.formals; - - @override - // Coverage-ignore(suite): Not run. - bool get isConst => _fragment.modifiers.isConst; - - @override - bool get isExternal => _fragment.modifiers.isExternal; - - @override - void buildOutlineNodes(BuildNodesCallback f, - {required SourceConstructorBuilder constructorBuilder, - required SourceLibraryBuilder libraryBuilder, - required NameScheme nameScheme, - required ConstructorReferences? constructorReferences, - required List delayedDefaultValueCloners}) { - _encoding.buildOutlineNodes(f, - constructorBuilder: constructorBuilder, - libraryBuilder: libraryBuilder, - declarationBuilder: - constructorBuilder.declarationBuilder as SourceExtensionBuilder, - name: _fragment.name, - nameScheme: nameScheme, - constructorReferences: constructorReferences, - fileUri: _fragment.fileUri, - fileOffset: _fragment.fullNameOffset, - formalsOffset: _fragment.formalsOffset, - endOffset: _fragment.endOffset, - forAbstractClassOrEnumOrMixin: _fragment.forAbstractClassOrMixin, - isConst: _fragment.modifiers.isConst, - returnType: returnType, - typeParameters: _typeParameters, - formals: formals, - delayedDefaultValueCloners: delayedDefaultValueCloners); - } - - @override - // Coverage-ignore(suite): Not run. - void _buildMetadataForOutlineExpressions( - {required Iterable annotatables, - required Uri annotatablesFileUri, - required SourceLibraryBuilder libraryBuilder, - required DeclarationBuilder declarationBuilder, - required SourceConstructorBuilder constructorBuilder, - required BodyBuilderContext bodyBuilderContext, - required ClassHierarchy classHierarchy}) { - for (Annotatable annotatable in annotatables) { - MetadataBuilder.buildAnnotations( - annotatable: annotatable, - annotatableFileUri: annotatablesFileUri, - metadata: _fragment.metadata, - bodyBuilderContext: bodyBuilderContext, - libraryBuilder: libraryBuilder, - scope: _fragment.enclosingScope); - } - } - - @override - // Coverage-ignore(suite): Not run. - void _buildTypeParametersAndFormalsForOutlineExpressions( - {required SourceLibraryBuilder libraryBuilder, - required DeclarationBuilder declarationBuilder, - required BodyBuilderContext bodyBuilderContext, - required ClassHierarchy classHierarchy}) { - _buildTypeParametersAndFormals( - libraryBuilder: libraryBuilder, - declarationBuilder: declarationBuilder, - bodyBuilderContext: bodyBuilderContext, - classHierarchy: classHierarchy, - typeParameterScope: _fragment.typeParameterScope); - } - - @override - // Coverage-ignore(suite): Not run. - int get fileOffset => _fragment.fullNameOffset; - - @override - // Coverage-ignore(suite): Not run. - Uri get fileUri => _fragment.fileUri; -} - /// Interface for using a [ConstructorFragment] or [PrimaryConstructorFragment] /// to create a [BodyBuilderContext]. abstract class ConstructorFragmentDeclaration { @@ -1850,13 +1331,6 @@ mixin _SyntheticConstructorDeclarationMixin implements ConstructorDeclaration { kind: BuiltMemberKind.Constructor); } - @override - Substitution computeFieldTypeSubstitution( - DeclarationBuilder declarationBuilder) { - throw new UnsupportedError( - "Unexpected call to $runtimeType.computeFieldTypeSubstitution"); - } - @override List get initializers { throw new UnsupportedError("Unexpected call to $runtimeType.initializers"); @@ -1875,7 +1349,11 @@ mixin _SyntheticConstructorDeclarationMixin implements ConstructorDeclaration { } @override - void registerInferable(Inferable inferable) {} + // Coverage-ignore(suite): Not run. + Substitution computeFieldTypeSubstitution( + DeclarationBuilder declarationBuilder) { + return Substitution.empty; + } } class DefaultConstructorDeclaration @@ -1895,7 +1373,14 @@ class DefaultConstructorDeclaration @override // Coverage-ignore(suite): Not run. - void createEncoding(SourceConstructorBuilder builder) {} + void createEncoding({ + required ProblemReporting problemReporting, + required SourceLoader loader, + required DeclarationBuilder declarationBuilder, + required SourceConstructorBuilder constructorBuilder, + required List unboundNominalParameters, + required ConstructorEncodingStrategy encodingStrategy, + }) {} @override void addSuperParameterDefaultValueCloners( @@ -1957,7 +1442,14 @@ class ForwardingConstructorDeclaration @override // Coverage-ignore(suite): Not run. - void createEncoding(SourceConstructorBuilder builder) {} + void createEncoding({ + required ProblemReporting problemReporting, + required SourceLoader loader, + required DeclarationBuilder declarationBuilder, + required SourceConstructorBuilder constructorBuilder, + required List unboundNominalParameters, + required ConstructorEncodingStrategy encodingStrategy, + }) {} @override void addSuperParameterDefaultValueCloners( diff --git a/pkg/front_end/lib/src/fragment/constructor/encoding.dart b/pkg/front_end/lib/src/fragment/constructor/encoding.dart index c82cf9f983b..02aabb0a285 100644 --- a/pkg/front_end/lib/src/fragment/constructor/encoding.dart +++ b/pkg/front_end/lib/src/fragment/constructor/encoding.dart @@ -2,18 +2,22 @@ // 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:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart'; import 'package:kernel/ast.dart'; import 'package:kernel/type_algebra.dart'; import '../../api_prototype/lowering_predicates.dart'; +import '../../base/modifiers.dart'; import '../../builder/declaration_builders.dart'; import '../../builder/formal_parameter_builder.dart'; +import '../../builder/named_type_builder.dart'; import '../../builder/omitted_type_builder.dart'; import '../../builder/type_builder.dart'; import '../../kernel/body_builder_context.dart'; import '../../kernel/constructor_tearoff_lowering.dart'; import '../../kernel/internal_ast.dart'; import '../../kernel/kernel_helper.dart'; +import '../../source/builder_factory.dart'; import '../../source/name_scheme.dart'; import '../../source/source_class_builder.dart'; import '../../source/source_constructor_builder.dart'; @@ -25,6 +29,7 @@ import '../../source/source_loader.dart'; import '../../source/source_member_builder.dart'; import '../../source/source_type_parameter_builder.dart'; import '../../type_inference/type_schema.dart'; +import '../fragment.dart'; import 'body_builder_context.dart'; import 'declaration.dart'; @@ -41,12 +46,63 @@ abstract class ConstructorEncoding { VariableDeclaration? getTearOffParameter(int index); + VariableDeclaration? get thisVariable; + + List? get thisTypeParameters; + /// Mark the constructor as erroneous. /// /// This is used during the compilation phase to set the appropriate flag on /// the input AST node. The flag helps the verifier to skip apriori erroneous /// members and to avoid reporting cascading errors. void markAsErroneous(); + + void buildOutlineNodes( + BuildNodesCallback f, { + required SourceConstructorBuilder constructorBuilder, + required SourceLibraryBuilder libraryBuilder, + required covariant DeclarationBuilder declarationBuilder, + required String name, + required NameScheme nameScheme, + required ConstructorReferences? constructorReferences, + required Uri fileUri, + required int startOffset, + required int fileOffset, + required int formalsOffset, + required int endOffset, + required bool forAbstractClassOrEnumOrMixin, + required bool isConst, + required bool isSynthetic, + required TypeBuilder returnType, + required List? typeParameters, + required List? formals, + required List delayedDefaultValueCloners, + }); + + void buildBody(); + + BodyBuilderContext createBodyBuilderContext( + SourceConstructorBuilder constructorBuilder, + ConstructorFragmentDeclaration constructorDeclaration); + + void registerFunctionBody(Statement value); + + void registerNoBodyConstructor(); + + void addSuperParameterDefaultValueCloners( + {required List delayedDefaultValueCloners, + required Member superTarget, + required List? positionalSuperParameters, + required List? namedSuperParameters, + required SourceLibraryBuilder libraryBuilder}); + + void becomeNative(SourceLoader loader, String nativeMethodName); + + Substitution computeFieldTypeSubstitution( + covariant DeclarationBuilder declarationBuilder, + List? typeParameters); + + bool get isRedirecting; } class RegularConstructorEncoding implements ConstructorEncoding { @@ -65,10 +121,12 @@ class RegularConstructorEncoding implements ConstructorEncoding { : _isExternal = isExternal, _isEnumConstructor = isEnumConstructor; + @override void registerFunctionBody(Statement value) { function.body = value..parent = function; } + @override void registerNoBodyConstructor() { if (!_isExternal) { registerFunctionBody(new EmptyStatement()); @@ -87,6 +145,23 @@ class RegularConstructorEncoding implements ConstructorEncoding { @override List get initializers => _constructor.initializers; + @override + bool get isRedirecting { + for (Initializer initializer in initializers) { + if (initializer is RedirectingInitializer) { + return true; + } + } + return false; + } + + @override + VariableDeclaration? get thisVariable => null; + + @override + List? get thisTypeParameters => null; + + @override void buildOutlineNodes( BuildNodesCallback f, { required SourceConstructorBuilder constructorBuilder, @@ -232,6 +307,9 @@ class RegularConstructorEncoding implements ConstructorEncoding { } } + @override + void buildBody() {} + @override void prepareInitializers() { // For const constructors we parse initializers already at the outlining @@ -256,6 +334,7 @@ class RegularConstructorEncoding implements ConstructorEncoding { _constructor.initializers.insert(0, initializer); } + @override void becomeNative(SourceLoader loader, String nativeMethodName) { _constructor.isExternal = true; @@ -295,6 +374,7 @@ class RegularConstructorEncoding implements ConstructorEncoding { bool _hasAddedDefaultValueCloners = false; + @override void addSuperParameterDefaultValueCloners( {required List delayedDefaultValueCloners, required Member superTarget, @@ -323,6 +403,7 @@ class RegularConstructorEncoding implements ConstructorEncoding { } } + @override BodyBuilderContext createBodyBuilderContext( SourceConstructorBuilder constructorBuilder, ConstructorFragmentDeclaration constructorDeclaration) { @@ -334,6 +415,15 @@ class RegularConstructorEncoding implements ConstructorEncoding { void markAsErroneous() { _constructor.isErroneous = true; } + + @override + Substitution computeFieldTypeSubstitution( + covariant DeclarationBuilder declarationBuilder, + List? typeParameters) { + // Nothing to substitute. Regular generative constructors don't have their + // own type parameters. + return Substitution.empty; + } } mixin _ExtensionTypeConstructorEncodingMixin @@ -365,10 +455,12 @@ mixin _ExtensionTypeConstructorEncodingMixin @override List get initializers => _initializers; + @override void registerFunctionBody(Statement value) { function.body = value..parent = function; } + @override void registerNoBodyConstructor() { if (!_hasBuiltBody && !_isExternal) { registerFunctionBody(new EmptyStatement()); @@ -495,12 +587,14 @@ mixin _ExtensionTypeConstructorEncodingMixin } } + @override VariableDeclaration? get thisVariable { assert(_thisVariable != null, "ProcedureBuilder.thisVariable has not been set."); return _thisVariable; } + @override List? get thisTypeParameters { // Use [_thisVariable] as marker for whether this type parameters have // been computed. @@ -561,6 +655,7 @@ mixin _ExtensionTypeConstructorEncodingMixin bool _hasBuiltBody = false; + @override void buildBody() { if (_hasBuiltBody) { return; @@ -583,6 +678,7 @@ mixin _ExtensionTypeConstructorEncodingMixin _hasBuiltBody = true; } + @override BodyBuilderContext createBodyBuilderContext( SourceConstructorBuilder constructorBuilder, ConstructorFragmentDeclaration constructorDeclaration) { @@ -594,6 +690,22 @@ mixin _ExtensionTypeConstructorEncodingMixin void markAsErroneous() { _constructor.isErroneous = true; } + + @override + void addSuperParameterDefaultValueCloners( + {required List delayedDefaultValueCloners, + required Member superTarget, + required List? positionalSuperParameters, + required List? namedSuperParameters, + required SourceLibraryBuilder libraryBuilder}) { + throw new UnsupportedError( + '$runtimeType.addSuperParameterDefaultValueCloners'); + } + + @override + void becomeNative(SourceLoader loader, String nativeMethodName) { + throw new UnsupportedError('$runtimeType.becomeNative'); + } } class _ExtensionTypeInitializerToStatementConverter @@ -687,6 +799,7 @@ class ExtensionTypeConstructorEncoding extensionTypeDeclaration, Nullability.nonNullable, typeArguments); } + @override void buildOutlineNodes( BuildNodesCallback f, { required SourceConstructorBuilder constructorBuilder, @@ -696,11 +809,13 @@ class ExtensionTypeConstructorEncoding required NameScheme nameScheme, required ConstructorReferences? constructorReferences, required Uri fileUri, + required int startOffset, required int fileOffset, required int formalsOffset, required int endOffset, required bool forAbstractClassOrEnumOrMixin, required bool isConst, + required bool isSynthetic, required TypeBuilder returnType, required List? typeParameters, required List? formals, @@ -734,6 +849,36 @@ class ExtensionTypeConstructorEncoding @override bool get _isExtensionTypeMember => true; + + @override + Substitution computeFieldTypeSubstitution( + DeclarationBuilder declarationBuilder, + List? typeParameters) { + if (typeParameters != null) { + assert( + declarationBuilder.typeParameters!.length == typeParameters.length); + return Substitution.fromPairs( + (declarationBuilder as SourceExtensionTypeDeclarationBuilder) + .extensionTypeDeclaration + .typeParameters, + new List.generate( + declarationBuilder.typeParameters!.length, + (int index) => new TypeParameterType.withDefaultNullability( + function.typeParameters[index]))); + } else { + return Substitution.empty; + } + } + + @override + bool get isRedirecting { + for (Initializer initializer in initializers) { + if (initializer is ExtensionTypeRedirectingInitializer) { + return true; + } + } + return false; + } } class ExtensionConstructorEncoding @@ -745,6 +890,7 @@ class ExtensionConstructorEncoding ExtensionConstructorEncoding({required bool isExternal}) : _isExternal = isExternal; + @override void buildOutlineNodes( BuildNodesCallback f, { required SourceConstructorBuilder constructorBuilder, @@ -754,11 +900,13 @@ class ExtensionConstructorEncoding required NameScheme nameScheme, required ConstructorReferences? constructorReferences, required Uri fileUri, + required int startOffset, required int fileOffset, required int formalsOffset, required int endOffset, required bool forAbstractClassOrEnumOrMixin, required bool isConst, + required bool isSynthetic, required TypeBuilder returnType, required List? typeParameters, required List? formals, @@ -798,4 +946,221 @@ class ExtensionConstructorEncoding return Substitution.fromPairs(extension.typeParameters, typeArguments) .substituteType(extension.onType); } + + @override + // Coverage-ignore(suite): Not run. + Substitution computeFieldTypeSubstitution( + SourceExtensionBuilder declarationBuilder, + List? typeParameters) { + if (typeParameters != null) { + assert( + declarationBuilder.typeParameters!.length == typeParameters.length); + return Substitution.fromPairs( + declarationBuilder.extension.typeParameters, + new List.generate( + declarationBuilder.typeParameters!.length, + (int index) => new TypeParameterType.withDefaultNullability( + function.typeParameters[index]))); + } else { + return Substitution.empty; + } + } + + @override + // Coverage-ignore(suite): Not run. + bool get isRedirecting { + // TODO(johnniwinther): Update this if redirecting extension constructors + // are supported. + return false; + } +} + +abstract class ConstructorEncodingStrategy { + factory ConstructorEncodingStrategy(DeclarationBuilder declarationBuilder) { + switch (declarationBuilder) { + case ClassBuilder(): + if (declarationBuilder.isEnum) { + return const EnumConstructorEncodingStrategy(); + } else { + return const RegularConstructorEncodingStrategy(); + } + case ExtensionBuilder(): + return const ExtensionConstructorEncodingStrategy(); + case ExtensionTypeDeclarationBuilder(): + return const ExtensionTypeConstructorEncodingStrategy(); + } + } + + List? createFormals({ + required SourceLoader loader, + required List? formals, + required Uri fileUri, + required int fileOffset, + }); + + List? createTypeParameters({ + required DeclarationBuilder declarationBuilder, + required List? declarationTypeParameterFragments, + required List? typeParameters, + required List unboundNominalParameters, + }); + + ConstructorEncoding createEncoding({required bool isExternal}); +} + +class RegularConstructorEncodingStrategy + implements ConstructorEncodingStrategy { + const RegularConstructorEncodingStrategy(); + + @override + ConstructorEncoding createEncoding({required bool isExternal}) { + return new RegularConstructorEncoding( + isExternal: isExternal, isEnumConstructor: false); + } + + @override + List? createFormals( + {required SourceLoader loader, + required List? formals, + required Uri fileUri, + required int fileOffset}) { + return formals; + } + + @override + List? createTypeParameters( + {required DeclarationBuilder declarationBuilder, + required List? declarationTypeParameterFragments, + required List? typeParameters, + required List unboundNominalParameters}) { + return typeParameters; + } +} + +class EnumConstructorEncodingStrategy implements ConstructorEncodingStrategy { + const EnumConstructorEncodingStrategy(); + + @override + ConstructorEncoding createEncoding({required bool isExternal}) { + return new RegularConstructorEncoding( + isExternal: isExternal, isEnumConstructor: true); + } + + @override + List? createFormals({ + required SourceLoader loader, + required List? formals, + required Uri fileUri, + required int fileOffset, + }) { + return [ + new FormalParameterBuilder(FormalParameterKind.requiredPositional, + Modifiers.empty, loader.target.intType, "#index", fileOffset, + fileUri: fileUri, hasImmediatelyDeclaredInitializer: false), + new FormalParameterBuilder(FormalParameterKind.requiredPositional, + Modifiers.empty, loader.target.stringType, "#name", fileOffset, + fileUri: fileUri, hasImmediatelyDeclaredInitializer: false), + ...?formals + ]; + } + + @override + List? createTypeParameters( + {required DeclarationBuilder declarationBuilder, + required List? declarationTypeParameterFragments, + required List? typeParameters, + required List unboundNominalParameters}) { + return typeParameters; + } +} + +class ExtensionConstructorEncodingStrategy + implements ConstructorEncodingStrategy { + const ExtensionConstructorEncodingStrategy(); + + @override + ConstructorEncoding createEncoding({required bool isExternal}) { + return new ExtensionConstructorEncoding(isExternal: isExternal); + } + + @override + List? createFormals( + {required SourceLoader loader, + required List? formals, + required Uri fileUri, + required int fileOffset}) { + return formals; + } + + @override + List? createTypeParameters( + {required DeclarationBuilder declarationBuilder, + required List? declarationTypeParameterFragments, + required List? typeParameters, + required List unboundNominalParameters}) { + NominalParameterCopy? nominalVariableCopy = + NominalParameterCopy.copyTypeParameters( + unboundNominalParameters: unboundNominalParameters, + oldParameterBuilders: declarationBuilder.typeParameters, + oldParameterFragments: declarationTypeParameterFragments, + kind: TypeParameterKind.extensionSynthesized, + instanceTypeParameterAccess: + InstanceTypeParameterAccessState.Allowed); + if (nominalVariableCopy != null) { + if (typeParameters != null) { + // Coverage-ignore-block(suite): Not run. + typeParameters = nominalVariableCopy.newParameterBuilders + ..addAll(typeParameters); + } else { + typeParameters = nominalVariableCopy.newParameterBuilders; + } + } + return typeParameters; + } +} + +class ExtensionTypeConstructorEncodingStrategy + implements ConstructorEncodingStrategy { + const ExtensionTypeConstructorEncodingStrategy(); + + @override + List? createFormals( + {required SourceLoader loader, + required List? formals, + required Uri fileUri, + required int fileOffset}) { + return formals; + } + + @override + List? createTypeParameters({ + required DeclarationBuilder declarationBuilder, + required List? declarationTypeParameterFragments, + required List? typeParameters, + required List unboundNominalParameters, + }) { + NominalParameterCopy? nominalVariableCopy = + NominalParameterCopy.copyTypeParameters( + unboundNominalParameters: unboundNominalParameters, + oldParameterBuilders: declarationBuilder.typeParameters, + oldParameterFragments: declarationTypeParameterFragments, + kind: TypeParameterKind.extensionSynthesized, + instanceTypeParameterAccess: + InstanceTypeParameterAccessState.Allowed); + if (nominalVariableCopy != null) { + if (typeParameters != null) { + // Coverage-ignore-block(suite): Not run. + typeParameters = nominalVariableCopy.newParameterBuilders + ..addAll(typeParameters); + } else { + typeParameters = nominalVariableCopy.newParameterBuilders; + } + } + return typeParameters; + } + + @override + ConstructorEncoding createEncoding({required bool isExternal}) { + return new ExtensionTypeConstructorEncoding(isExternal: isExternal); + } } diff --git a/pkg/front_end/lib/src/source/source_constructor_builder.dart b/pkg/front_end/lib/src/source/source_constructor_builder.dart index 1a6ead6c6d5..200970af283 100644 --- a/pkg/front_end/lib/src/source/source_constructor_builder.dart +++ b/pkg/front_end/lib/src/source/source_constructor_builder.dart @@ -160,11 +160,6 @@ class SourceConstructorBuilder extends SourceMemberBuilderImpl _augmentedDeclarations = [_introductory, ..._augmentations]; _lastDeclaration = _augmentedDeclarations.removeLast(); } - - _introductory.registerInferable(this); - for (ConstructorDeclaration augmentation in _augmentations) { - augmentation.registerInferable(this); - } } // TODO(johnniwinther): Add annotations to tear-offs. diff --git a/pkg/front_end/lib/src/source/source_enum_builder.dart b/pkg/front_end/lib/src/source/source_enum_builder.dart index e745f8f896c..ea88097f2eb 100644 --- a/pkg/front_end/lib/src/source/source_enum_builder.dart +++ b/pkg/front_end/lib/src/source/source_enum_builder.dart @@ -6,6 +6,7 @@ import 'package:_fe_analyzer_shared/src/metadata/expressions.dart' as shared; import 'package:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart'; import 'package:front_end/src/base/messages.dart'; import 'package:front_end/src/builder/property_builder.dart'; +import 'package:front_end/src/fragment/constructor/encoding.dart'; import 'package:front_end/src/fragment/method/encoding.dart'; import 'package:front_end/src/source/source_method_builder.dart'; import 'package:kernel/ast.dart'; @@ -286,6 +287,9 @@ class SourceEnumBuilder extends SourceClassBuilder { } } if (needsSynthesizedDefaultConstructor) { + ConstructorEncodingStrategy encodingStrategy = + new ConstructorEncodingStrategy(this); + FormalParameterBuilder nameFormalParameterBuilder = new FormalParameterBuilder( FormalParameterKind.requiredPositional, @@ -343,6 +347,14 @@ class SourceEnumBuilder extends SourceClassBuilder { introductory: constructorDeclaration, isConst: true, isExternal: false); + constructorDeclaration.createEncoding( + problemReporting: libraryBuilder, + loader: libraryBuilder.loader, + declarationBuilder: this, + constructorBuilder: constructorBuilder, + unboundNominalParameters: const [], + encodingStrategy: encodingStrategy); + constructorBuilder.registerInitializedField(valuesBuilder); addConstructorInternal(constructorBuilder, addToNameSpace: true); nameSpaceBuilder.checkTypeParameterConflict( 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 a7ff41c500f..a4a72464f65 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 @@ -2,7 +2,7 @@ // 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:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart'; +import 'package:front_end/src/fragment/constructor/encoding.dart'; import 'package:kernel/ast.dart'; import 'package:kernel/reference_from_index.dart'; import 'package:kernel/src/bounds_checks.dart' show VarianceCalculationValue; @@ -18,7 +18,6 @@ import '../builder/builder.dart'; import '../builder/constructor_builder.dart'; import '../builder/declaration_builders.dart'; import '../builder/factory_builder.dart'; -import '../builder/formal_parameter_builder.dart'; import '../builder/function_builder.dart'; import '../builder/member_builder.dart'; import '../builder/named_type_builder.dart'; @@ -2760,119 +2759,8 @@ _AddBuilder _createConstructorBuilder( bool isConst = fragment.modifiers.isConst; bool isExternal = fragment.modifiers.isExternal; - NameScheme nameScheme = new NameScheme( - isInstanceMember: false, - containerName: containerName, - containerType: containerType, - libraryName: indexedLibrary != null - ? new LibraryName(indexedLibrary.library.reference) - : enclosingLibraryBuilder.libraryName); - - createNominalParameterBuilders( - fragment.typeParameters, unboundNominalParameters); - - ConstructorReferences constructorReferences = new ConstructorReferences( - name: name, - nameScheme: nameScheme, - indexedContainer: indexedContainer, - loader: loader, - declarationBuilder: declarationBuilder!); - - ConstructorDeclaration createConstructorDeclaration( - ConstructorFragment fragment) { - switch (declarationBuilder) { - case ExtensionTypeDeclarationBuilder(): - List? typeParameters = fragment - .typeParameters - // Coverage-ignore(suite): Not run. - ?.builders; - NominalParameterCopy? nominalVariableCopy = - NominalParameterCopy.copyTypeParameters( - unboundNominalParameters: unboundNominalParameters, - oldParameterBuilders: declarationBuilder.typeParameters, - oldParameterFragments: - fragment.enclosingDeclaration.typeParameters, - kind: TypeParameterKind.extensionSynthesized, - instanceTypeParameterAccess: - InstanceTypeParameterAccessState.Allowed); - if (nominalVariableCopy != null) { - if (typeParameters != null) { - // Coverage-ignore-block(suite): Not run. - typeParameters = nominalVariableCopy.newParameterBuilders - ..addAll(typeParameters); - } else { - typeParameters = nominalVariableCopy.newParameterBuilders; - } - } - fragment.typeParameterNameSpace.addTypeParameters( - problemReporting, typeParameters, - ownerName: fragment.name, allowNameConflict: true); - return new ExtensionTypeConstructorDeclaration(fragment, - typeParameters: typeParameters); - case ClassBuilder(): - List? syntheticFormals; - if (declarationBuilder.isEnum) { - syntheticFormals = [ - new FormalParameterBuilder( - FormalParameterKind.requiredPositional, - Modifiers.empty, - loader.target.intType, - "#index", - fragment.fullNameOffset, - fileUri: fragment.fileUri, - hasImmediatelyDeclaredInitializer: false), - new FormalParameterBuilder( - FormalParameterKind.requiredPositional, - Modifiers.empty, - loader.target.stringType, - "#name", - fragment.fullNameOffset, - fileUri: fragment.fileUri, - hasImmediatelyDeclaredInitializer: false), - ]; - } - List? typeParameters = - fragment.typeParameters?.builders; - fragment.typeParameterNameSpace.addTypeParameters( - problemReporting, typeParameters, - ownerName: fragment.name, allowNameConflict: true); - return new RegularConstructorDeclaration(fragment, - typeParameters: typeParameters, - syntheticFormals: syntheticFormals, - isEnumConstructor: declarationBuilder.isEnum); - case ExtensionBuilder(): - List? typeParameters = fragment - .typeParameters - // Coverage-ignore(suite): Not run. - ?.builders; - NominalParameterCopy? nominalVariableCopy = - NominalParameterCopy.copyTypeParameters( - unboundNominalParameters: unboundNominalParameters, - oldParameterBuilders: declarationBuilder.typeParameters, - oldParameterFragments: - fragment.enclosingDeclaration.typeParameters, - kind: TypeParameterKind.extensionSynthesized, - instanceTypeParameterAccess: - InstanceTypeParameterAccessState.Allowed); - if (nominalVariableCopy != null) { - if (typeParameters != null) { - // Coverage-ignore-block(suite): Not run. - typeParameters = nominalVariableCopy.newParameterBuilders - ..addAll(typeParameters); - } else { - typeParameters = nominalVariableCopy.newParameterBuilders; - } - } - fragment.typeParameterNameSpace.addTypeParameters( - problemReporting, typeParameters, - ownerName: fragment.name, allowNameConflict: true); - return new ExtensionConstructorDeclaration(fragment, - typeParameters: typeParameters); - } - } - ConstructorDeclaration constructorDeclaration = - createConstructorDeclaration(fragment); + new RegularConstructorDeclaration(fragment); List augmentationDeclarations = []; if (augmentations != null) { @@ -2880,10 +2768,8 @@ _AddBuilder _createConstructorBuilder( // Promote [augmentation] to [ConstructorFragment]. augmentation as ConstructorFragment; - createNominalParameterBuilders( - augmentation.typeParameters, unboundNominalParameters); - - augmentationDeclarations.add(createConstructorDeclaration(augmentation)); + augmentationDeclarations + .add(new RegularConstructorDeclaration(augmentation)); if (!augmentation.modifiers.isExternal) { isExternal = false; @@ -2898,7 +2784,6 @@ _AddBuilder _createConstructorBuilder( loader: loader, name: name, uriOffset: fragment.uriOffset, - nameScheme: nameScheme, enclosingLibraryBuilder: enclosingLibraryBuilder, declarationBuilder: declarationBuilder, unboundNominalParameters: unboundNominalParameters, @@ -2906,7 +2791,6 @@ _AddBuilder _createConstructorBuilder( containerType: containerType, indexedContainer: indexedContainer, containerName: containerName, - constructorReferences: constructorReferences, nativeMethodName: fragment.nativeMethodName, isConst: isConst, isExternal: isExternal, @@ -2920,7 +2804,6 @@ _AddBuilder _createConstructorBuilderFromDeclarations( required SourceLoader loader, required String name, required UriOffsetLength uriOffset, - required NameScheme nameScheme, required SourceLibraryBuilder enclosingLibraryBuilder, required DeclarationBuilder? declarationBuilder, required List unboundNominalParameters, @@ -2928,15 +2811,32 @@ _AddBuilder _createConstructorBuilderFromDeclarations( required ContainerType containerType, required IndexedContainer? indexedContainer, required ContainerName? containerName, - required ConstructorReferences constructorReferences, required String? nativeMethodName, required bool isConst, required bool isExternal, required bool inPatch}) { + NameScheme nameScheme = new NameScheme( + isInstanceMember: false, + containerName: containerName, + containerType: containerType, + libraryName: indexedLibrary != null + ? new LibraryName(indexedLibrary.library.reference) + : enclosingLibraryBuilder.libraryName); + + ConstructorEncodingStrategy encodingStrategy = + new ConstructorEncodingStrategy(declarationBuilder!); + + ConstructorReferences constructorReferences = new ConstructorReferences( + name: name, + nameScheme: nameScheme, + indexedContainer: indexedContainer, + loader: loader, + declarationBuilder: declarationBuilder); + SourceConstructorBuilder constructorBuilder = new SourceConstructorBuilder( name: name, libraryBuilder: enclosingLibraryBuilder, - declarationBuilder: declarationBuilder!, + declarationBuilder: declarationBuilder, fileUri: uriOffset.fileUri, fileOffset: uriOffset.fileOffset, constructorReferences: constructorReferences, @@ -2948,9 +2848,21 @@ _AddBuilder _createConstructorBuilderFromDeclarations( isExternal: isExternal); constructorReferences.registerReference(loader, constructorBuilder); - constructorDeclaration.createEncoding(constructorBuilder); + constructorDeclaration.createEncoding( + problemReporting: problemReporting, + loader: loader, + declarationBuilder: declarationBuilder, + constructorBuilder: constructorBuilder, + unboundNominalParameters: unboundNominalParameters, + encodingStrategy: encodingStrategy); for (ConstructorDeclaration augmentation in augmentationDeclarations) { - augmentation.createEncoding(constructorBuilder); + augmentation.createEncoding( + problemReporting: problemReporting, + loader: loader, + declarationBuilder: declarationBuilder, + constructorBuilder: constructorBuilder, + unboundNominalParameters: unboundNominalParameters, + encodingStrategy: encodingStrategy); } return new _AddBuilder(name, constructorBuilder, uriOffset, inPatch: inPatch); } @@ -2968,57 +2880,15 @@ _AddBuilder _createPrimaryConstructorBuilder( required ContainerName? containerName}) { String name = fragment.name; - NameScheme nameScheme = new NameScheme( - isInstanceMember: false, - containerName: containerName, - containerType: containerType, - libraryName: indexedLibrary != null - ? new LibraryName(indexedLibrary.library.reference) - : enclosingLibraryBuilder.libraryName); + ConstructorDeclaration constructorDeclaration = + new PrimaryConstructorDeclaration(fragment); - ConstructorReferences constructorReferences = new ConstructorReferences( - name: name, - nameScheme: nameScheme, - indexedContainer: indexedContainer, - loader: loader, - declarationBuilder: declarationBuilder!); - - ConstructorDeclaration constructorDeclaration; - switch (declarationBuilder) { - case ExtensionTypeDeclarationBuilder(): - NominalParameterCopy? nominalVariableCopy = - NominalParameterCopy.copyTypeParameters( - unboundNominalParameters: unboundNominalParameters, - oldParameterBuilders: declarationBuilder.typeParameters, - oldParameterFragments: - fragment.enclosingDeclaration.typeParameters, - kind: TypeParameterKind.extensionSynthesized, - instanceTypeParameterAccess: - InstanceTypeParameterAccessState.Allowed); - - List? typeParameters = - nominalVariableCopy?.newParameterBuilders; - fragment.typeParameterNameSpace.addTypeParameters( - problemReporting, typeParameters, - ownerName: fragment.name, allowNameConflict: true); - constructorDeclaration = new ExtensionTypePrimaryConstructorDeclaration( - fragment, - typeParameters: typeParameters); - // Coverage-ignore(suite): Not run. - case ClassBuilder(): - constructorDeclaration = new PrimaryConstructorDeclaration(fragment); - // Coverage-ignore(suite): Not run. - case ExtensionBuilder(): - throw new UnsupportedError( - 'Unexpected extension primary constructor $fragment'); - } return _createConstructorBuilderFromDeclarations( constructorDeclaration, const [], problemReporting: problemReporting, loader: loader, name: name, uriOffset: fragment.uriOffset, - nameScheme: nameScheme, enclosingLibraryBuilder: enclosingLibraryBuilder, declarationBuilder: declarationBuilder, unboundNominalParameters: unboundNominalParameters, @@ -3026,7 +2896,6 @@ _AddBuilder _createPrimaryConstructorBuilder( containerType: containerType, indexedContainer: indexedContainer, containerName: containerName, - constructorReferences: constructorReferences, nativeMethodName: null, isConst: fragment.modifiers.isConst, isExternal: fragment.modifiers.isExternal, diff --git a/pkg/front_end/test/coverage_suite_expected.dart b/pkg/front_end/test/coverage_suite_expected.dart index 75cb31bd955..47cf26dac10 100644 --- a/pkg/front_end/test/coverage_suite_expected.dart +++ b/pkg/front_end/test/coverage_suite_expected.dart @@ -505,12 +505,12 @@ const Map _expect = { ), // 100.0%. "package:front_end/src/fragment/constructor/declaration.dart": ( - hitCount: 735, + hitCount: 622, missCount: 0, ), // 100.0%. "package:front_end/src/fragment/constructor/encoding.dart": ( - hitCount: 421, + hitCount: 489, missCount: 0, ), // 100.0%. @@ -955,12 +955,12 @@ const Map _expect = { ), // 100.0%. "package:front_end/src/source/source_constructor_builder.dart": ( - hitCount: 360, + hitCount: 356, missCount: 0, ), // 100.0%. "package:front_end/src/source/source_enum_builder.dart": ( - hitCount: 423, + hitCount: 428, missCount: 0, ), // 100.0%. @@ -1026,7 +1026,7 @@ const Map _expect = { ), // 100.0%. "package:front_end/src/source/type_parameter_scope_builder.dart": ( - hitCount: 1519, + hitCount: 1458, missCount: 0, ), // 100.0%.