[cfe] Add ConstructorEncodingStrategy

This adds [ConstructorEncodingStrategy] similar to
[PropertyEncodingStrategy] which allows for separating
[ConstructorDeclaration] from [ConstructorEncoding] such that we don't
need special [ConstructorDeclaration]s for extension (types).

Change-Id: I1c7f17e1759d47abae4af97d84455a37cbb70c17
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/435460
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
This commit is contained in:
Johnni Winther
2025-06-18 04:45:22 -07:00
committed by Commit Queue
parent 7e4145d141
commit 807e7d3290
6 changed files with 607 additions and 874 deletions
File diff suppressed because it is too large Load Diff
@@ -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<TypeParameter>? 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<SourceNominalParameterBuilder>? typeParameters,
required List<FormalParameterBuilder>? formals,
required List<DelayedDefaultValueCloner> delayedDefaultValueCloners,
});
void buildBody();
BodyBuilderContext createBodyBuilderContext(
SourceConstructorBuilder constructorBuilder,
ConstructorFragmentDeclaration constructorDeclaration);
void registerFunctionBody(Statement value);
void registerNoBodyConstructor();
void addSuperParameterDefaultValueCloners(
{required List<DelayedDefaultValueCloner> delayedDefaultValueCloners,
required Member superTarget,
required List<int?>? positionalSuperParameters,
required List<String>? namedSuperParameters,
required SourceLibraryBuilder libraryBuilder});
void becomeNative(SourceLoader loader, String nativeMethodName);
Substitution computeFieldTypeSubstitution(
covariant DeclarationBuilder declarationBuilder,
List<SourceNominalParameterBuilder>? 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<Initializer> 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<TypeParameter>? 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<DelayedDefaultValueCloner> 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<SourceNominalParameterBuilder>? typeParameters) {
// Nothing to substitute. Regular generative constructors don't have their
// own type parameters.
return Substitution.empty;
}
}
mixin _ExtensionTypeConstructorEncodingMixin<T extends DeclarationBuilder>
@@ -365,10 +455,12 @@ mixin _ExtensionTypeConstructorEncodingMixin<T extends DeclarationBuilder>
@override
List<Initializer> 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<T extends DeclarationBuilder>
}
}
@override
VariableDeclaration? get thisVariable {
assert(_thisVariable != null,
"ProcedureBuilder.thisVariable has not been set.");
return _thisVariable;
}
@override
List<TypeParameter>? get thisTypeParameters {
// Use [_thisVariable] as marker for whether this type parameters have
// been computed.
@@ -561,6 +655,7 @@ mixin _ExtensionTypeConstructorEncodingMixin<T extends DeclarationBuilder>
bool _hasBuiltBody = false;
@override
void buildBody() {
if (_hasBuiltBody) {
return;
@@ -583,6 +678,7 @@ mixin _ExtensionTypeConstructorEncodingMixin<T extends DeclarationBuilder>
_hasBuiltBody = true;
}
@override
BodyBuilderContext createBodyBuilderContext(
SourceConstructorBuilder constructorBuilder,
ConstructorFragmentDeclaration constructorDeclaration) {
@@ -594,6 +690,22 @@ mixin _ExtensionTypeConstructorEncodingMixin<T extends DeclarationBuilder>
void markAsErroneous() {
_constructor.isErroneous = true;
}
@override
void addSuperParameterDefaultValueCloners(
{required List<DelayedDefaultValueCloner> delayedDefaultValueCloners,
required Member superTarget,
required List<int?>? positionalSuperParameters,
required List<String>? 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<SourceNominalParameterBuilder>? typeParameters,
required List<FormalParameterBuilder>? formals,
@@ -734,6 +849,36 @@ class ExtensionTypeConstructorEncoding
@override
bool get _isExtensionTypeMember => true;
@override
Substitution computeFieldTypeSubstitution(
DeclarationBuilder declarationBuilder,
List<SourceNominalParameterBuilder>? typeParameters) {
if (typeParameters != null) {
assert(
declarationBuilder.typeParameters!.length == typeParameters.length);
return Substitution.fromPairs(
(declarationBuilder as SourceExtensionTypeDeclarationBuilder)
.extensionTypeDeclaration
.typeParameters,
new List<DartType>.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<SourceNominalParameterBuilder>? typeParameters,
required List<FormalParameterBuilder>? 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<SourceNominalParameterBuilder>? typeParameters) {
if (typeParameters != null) {
assert(
declarationBuilder.typeParameters!.length == typeParameters.length);
return Substitution.fromPairs(
declarationBuilder.extension.typeParameters,
new List<DartType>.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<FormalParameterBuilder>? createFormals({
required SourceLoader loader,
required List<FormalParameterBuilder>? formals,
required Uri fileUri,
required int fileOffset,
});
List<SourceNominalParameterBuilder>? createTypeParameters({
required DeclarationBuilder declarationBuilder,
required List<TypeParameterFragment>? declarationTypeParameterFragments,
required List<SourceNominalParameterBuilder>? typeParameters,
required List<NominalParameterBuilder> 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<FormalParameterBuilder>? createFormals(
{required SourceLoader loader,
required List<FormalParameterBuilder>? formals,
required Uri fileUri,
required int fileOffset}) {
return formals;
}
@override
List<SourceNominalParameterBuilder>? createTypeParameters(
{required DeclarationBuilder declarationBuilder,
required List<TypeParameterFragment>? declarationTypeParameterFragments,
required List<SourceNominalParameterBuilder>? typeParameters,
required List<NominalParameterBuilder> unboundNominalParameters}) {
return typeParameters;
}
}
class EnumConstructorEncodingStrategy implements ConstructorEncodingStrategy {
const EnumConstructorEncodingStrategy();
@override
ConstructorEncoding createEncoding({required bool isExternal}) {
return new RegularConstructorEncoding(
isExternal: isExternal, isEnumConstructor: true);
}
@override
List<FormalParameterBuilder>? createFormals({
required SourceLoader loader,
required List<FormalParameterBuilder>? 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<SourceNominalParameterBuilder>? createTypeParameters(
{required DeclarationBuilder declarationBuilder,
required List<TypeParameterFragment>? declarationTypeParameterFragments,
required List<SourceNominalParameterBuilder>? typeParameters,
required List<NominalParameterBuilder> unboundNominalParameters}) {
return typeParameters;
}
}
class ExtensionConstructorEncodingStrategy
implements ConstructorEncodingStrategy {
const ExtensionConstructorEncodingStrategy();
@override
ConstructorEncoding createEncoding({required bool isExternal}) {
return new ExtensionConstructorEncoding(isExternal: isExternal);
}
@override
List<FormalParameterBuilder>? createFormals(
{required SourceLoader loader,
required List<FormalParameterBuilder>? formals,
required Uri fileUri,
required int fileOffset}) {
return formals;
}
@override
List<SourceNominalParameterBuilder>? createTypeParameters(
{required DeclarationBuilder declarationBuilder,
required List<TypeParameterFragment>? declarationTypeParameterFragments,
required List<SourceNominalParameterBuilder>? typeParameters,
required List<NominalParameterBuilder> 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<FormalParameterBuilder>? createFormals(
{required SourceLoader loader,
required List<FormalParameterBuilder>? formals,
required Uri fileUri,
required int fileOffset}) {
return formals;
}
@override
List<SourceNominalParameterBuilder>? createTypeParameters({
required DeclarationBuilder declarationBuilder,
required List<TypeParameterFragment>? declarationTypeParameterFragments,
required List<SourceNominalParameterBuilder>? typeParameters,
required List<NominalParameterBuilder> 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);
}
}
@@ -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.
@@ -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(
@@ -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<SourceNominalParameterBuilder>? 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<FormalParameterBuilder>? 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<SourceNominalParameterBuilder>? 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<SourceNominalParameterBuilder>? 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<ConstructorDeclaration> 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<NominalParameterBuilder> 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<SourceNominalParameterBuilder>? 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,
@@ -505,12 +505,12 @@ const Map<String, ({int hitCount, int missCount})> _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<String, ({int hitCount, int missCount})> _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<String, ({int hitCount, int missCount})> _expect = {
),
// 100.0%.
"package:front_end/src/source/type_parameter_scope_builder.dart": (
hitCount: 1519,
hitCount: 1458,
missCount: 0,
),
// 100.0%.