[cfe] Add PrimaryConstructoFieldFragment
This creates a PrimaryConstructorFieldFragment instead of a FieldFragment for primary constructor fields (currently only occurring in extension types). Change-Id: Iec58112a0a0ef64dba248f1ce93625e297b10705 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426460 Reviewed-by: Chloe Stefantsova <cstefantsova@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
committed by
Commit Queue
parent
df9e0f9729
commit
918899974a
@@ -18,7 +18,7 @@ class ExtensionTypeFragment extends DeclarationFragmentImpl
|
||||
late final int startOffset;
|
||||
late final int endOffset;
|
||||
|
||||
final List<FieldFragment> primaryConstructorFields = [];
|
||||
final List<PrimaryConstructorFieldFragment> primaryConstructorFields = [];
|
||||
|
||||
SourceExtensionTypeDeclarationBuilder? _builder;
|
||||
|
||||
@@ -54,7 +54,7 @@ class ExtensionTypeFragment extends DeclarationFragmentImpl
|
||||
modifiers.isAugment;
|
||||
|
||||
@override
|
||||
void addPrimaryConstructorField(FieldFragment fragment) {
|
||||
void addPrimaryConstructorField(PrimaryConstructorFieldFragment fragment) {
|
||||
primaryConstructorFields.add(fragment);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,6 @@ class FieldFragment implements Fragment {
|
||||
|
||||
final bool isTopLevel;
|
||||
final Modifiers modifiers;
|
||||
// TODO(johnniwinther): Create separate fragment for primary constructor
|
||||
// fields.
|
||||
final bool isPrimaryConstructorField;
|
||||
|
||||
final LookupScope enclosingScope;
|
||||
|
||||
@@ -46,7 +43,6 @@ class FieldFragment implements Fragment {
|
||||
required this.type,
|
||||
required this.isTopLevel,
|
||||
required this.modifiers,
|
||||
required this.isPrimaryConstructorField,
|
||||
required this.enclosingScope,
|
||||
required this.enclosingDeclaration,
|
||||
required this.enclosingCompilationUnit,
|
||||
|
||||
@@ -5,17 +5,36 @@
|
||||
part of '../fragment.dart';
|
||||
|
||||
class FieldFragmentBodyBuilderContext extends BodyBuilderContext {
|
||||
final SourcePropertyBuilder _builder;
|
||||
final FieldFragmentDeclaration _declaration;
|
||||
final FieldFragment _fragment;
|
||||
|
||||
FieldFragmentBodyBuilderContext(
|
||||
this._declaration,
|
||||
this._fragment,
|
||||
SourceLibraryBuilder libraryBuilder,
|
||||
DeclarationBuilder? declarationBuilder,
|
||||
{required bool isDeclarationInstanceMember})
|
||||
: super(libraryBuilder, declarationBuilder,
|
||||
isDeclarationInstanceMember: isDeclarationInstanceMember);
|
||||
@override
|
||||
final bool isLateField;
|
||||
|
||||
@override
|
||||
final bool isAbstractField;
|
||||
|
||||
@override
|
||||
final bool isExternalField;
|
||||
|
||||
final int _nameOffset;
|
||||
|
||||
final int _nameLength;
|
||||
|
||||
final bool _isConst;
|
||||
|
||||
FieldFragmentBodyBuilderContext(this._builder, this._declaration,
|
||||
{required this.isLateField,
|
||||
required this.isAbstractField,
|
||||
required this.isExternalField,
|
||||
required int nameOffset,
|
||||
required int nameLength,
|
||||
required bool isConst})
|
||||
: this._nameOffset = nameOffset,
|
||||
this._nameLength = nameLength,
|
||||
this._isConst = isConst,
|
||||
super(_builder.libraryBuilder, _builder.declarationBuilder,
|
||||
isDeclarationInstanceMember: _builder.isDeclarationInstanceMember);
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
@@ -26,25 +45,16 @@ class FieldFragmentBodyBuilderContext extends BodyBuilderContext {
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isLateField => _fragment.modifiers.isLate;
|
||||
|
||||
@override
|
||||
bool get isAbstractField => _fragment.modifiers.isAbstract;
|
||||
|
||||
@override
|
||||
bool get isExternalField => _fragment.modifiers.isExternal;
|
||||
// Coverage-ignore(suite): Not run.
|
||||
int get memberNameOffset => _nameOffset;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
int get memberNameOffset => _fragment.nameOffset;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
int get memberNameLength => _fragment.name.length;
|
||||
int get memberNameLength => _nameLength;
|
||||
|
||||
@override
|
||||
InstanceTypeParameterAccessState get instanceTypeParameterAccessState {
|
||||
if (_fragment.builder.isExtensionMember && !isExternalField) {
|
||||
if (_builder.isExtensionMember && !isExternalField) {
|
||||
return InstanceTypeParameterAccessState.Invalid;
|
||||
} else {
|
||||
return super.instanceTypeParameterAccessState;
|
||||
@@ -59,15 +69,15 @@ class FieldFragmentBodyBuilderContext extends BodyBuilderContext {
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
AugmentSuperTarget? get augmentSuperTarget {
|
||||
if (_fragment.builder.isAugmentation) {
|
||||
return _fragment.builder.augmentSuperTarget;
|
||||
if (_builder.isAugmentation) {
|
||||
return _builder.augmentSuperTarget;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
ConstantContext get constantContext {
|
||||
return _fragment.modifiers.isConst
|
||||
return _isConst
|
||||
? ConstantContext.inferred
|
||||
: !_declaration.isStatic && declarationDeclaresConstConstructor
|
||||
? ConstantContext.required
|
||||
|
||||
@@ -128,7 +128,7 @@ abstract class FieldDeclaration {
|
||||
shared.Expression? get initializerExpression;
|
||||
}
|
||||
|
||||
class FieldDeclarationImpl
|
||||
class RegularFieldDeclaration
|
||||
with FieldDeclarationMixin
|
||||
implements
|
||||
FieldDeclaration,
|
||||
@@ -149,7 +149,7 @@ class FieldDeclarationImpl
|
||||
/// building them twice as part of the non-outline build.
|
||||
bool hasBodyBeenBuilt = false;
|
||||
|
||||
FieldDeclarationImpl(this._fragment) {
|
||||
RegularFieldDeclaration(this._fragment) {
|
||||
_fragment.declaration = this;
|
||||
}
|
||||
|
||||
@@ -194,8 +194,7 @@ class FieldDeclarationImpl
|
||||
|
||||
@override
|
||||
bool get isExtensionTypeDeclaredInstanceField =>
|
||||
builder.isExtensionTypeInstanceMember &&
|
||||
!_fragment.isPrimaryConstructorField;
|
||||
builder.isExtensionTypeInstanceMember;
|
||||
|
||||
@override
|
||||
bool get isFinal => _fragment.modifiers.isFinal;
|
||||
@@ -404,9 +403,13 @@ class FieldDeclarationImpl
|
||||
|
||||
@override
|
||||
BodyBuilderContext createBodyBuilderContext() {
|
||||
return new FieldFragmentBodyBuilderContext(
|
||||
this, _fragment, builder.libraryBuilder, builder.declarationBuilder,
|
||||
isDeclarationInstanceMember: builder.isDeclarationInstanceMember);
|
||||
return new FieldFragmentBodyBuilderContext(builder, this,
|
||||
isLateField: _fragment.modifiers.isLate,
|
||||
isAbstractField: _fragment.modifiers.isAbstract,
|
||||
isExternalField: _fragment.modifiers.isExternal,
|
||||
nameOffset: _fragment.nameOffset,
|
||||
nameLength: _fragment.name.length,
|
||||
isConst: _fragment.modifiers.isConst);
|
||||
}
|
||||
|
||||
void createEncoding(SourcePropertyBuilder builder) {
|
||||
@@ -430,20 +433,16 @@ class FieldDeclarationImpl
|
||||
isAbstract: isAbstract,
|
||||
isExternal: isExternal);
|
||||
} else if (isExtensionTypeMember && isInstanceMember) {
|
||||
if (_fragment.isPrimaryConstructorField) {
|
||||
_encoding = new RepresentationFieldEncoding(_fragment);
|
||||
} else {
|
||||
// Field on a extension type. Encode as abstract.
|
||||
// TODO(johnniwinther): Should we have an erroneous flag on such
|
||||
// members?
|
||||
_encoding = new AbstractOrExternalFieldEncoding(_fragment,
|
||||
isExtensionInstanceMember: isExtensionMember && isInstanceMember,
|
||||
isExtensionTypeInstanceMember:
|
||||
isExtensionTypeMember && isInstanceMember,
|
||||
isAbstract: true,
|
||||
isExternal: false,
|
||||
isForcedExtension: true);
|
||||
}
|
||||
// Field on a extension type. Encode as abstract.
|
||||
// TODO(johnniwinther): Should we have an erroneous flag on such
|
||||
// members?
|
||||
_encoding = new AbstractOrExternalFieldEncoding(_fragment,
|
||||
isExtensionInstanceMember: isExtensionMember && isInstanceMember,
|
||||
isExtensionTypeInstanceMember:
|
||||
isExtensionTypeMember && isInstanceMember,
|
||||
isAbstract: true,
|
||||
isExternal: false,
|
||||
isForcedExtension: true);
|
||||
} else if (isLate &&
|
||||
libraryBuilder.loader.target.backendTarget.isLateFieldLoweringEnabled(
|
||||
hasInitializer: hasInitializer,
|
||||
|
||||
@@ -1167,7 +1167,7 @@ class AbstractOrExternalFieldEncoding implements FieldEncoding {
|
||||
|
||||
/// The encoding of an extension type declaration representation field.
|
||||
class RepresentationFieldEncoding implements FieldEncoding {
|
||||
final FieldFragment _fragment;
|
||||
final PrimaryConstructorFieldFragment _fragment;
|
||||
|
||||
late Procedure _getter;
|
||||
DartType? _type;
|
||||
@@ -1219,12 +1219,12 @@ class RepresentationFieldEncoding implements FieldEncoding {
|
||||
fileUri: _fragment.fileUri, reference: references.fieldGetterReference)
|
||||
..stubKind = ProcedureStubKind.RepresentationField
|
||||
..fileOffset = _fragment.nameOffset
|
||||
..fileEndOffset = _fragment.endOffset;
|
||||
..fileEndOffset = _fragment.nameOffset;
|
||||
nameScheme
|
||||
.getFieldMemberName(FieldNameType.RepresentationField, _fragment.name,
|
||||
isSynthesized: true)
|
||||
.attachMember(_getter);
|
||||
_getter..isConst = _fragment.modifiers.isConst;
|
||||
_getter..isConst = false;
|
||||
_getter
|
||||
..isStatic = false
|
||||
..isExtensionMember = false
|
||||
|
||||
@@ -56,8 +56,10 @@ import '../source/source_property_builder.dart';
|
||||
import '../source/source_type_alias_builder.dart';
|
||||
import '../source/source_type_parameter_builder.dart';
|
||||
import '../source/type_parameter_scope_builder.dart';
|
||||
import '../type_inference/inference_helper.dart';
|
||||
import '../type_inference/inference_results.dart';
|
||||
import '../type_inference/type_inference_engine.dart';
|
||||
import '../type_inference/type_inferrer.dart';
|
||||
import '../type_inference/type_schema.dart';
|
||||
import 'constructor/declaration.dart';
|
||||
import 'factory/declaration.dart';
|
||||
@@ -86,6 +88,7 @@ part 'method.dart';
|
||||
part 'mixin.dart';
|
||||
part 'named_mixin_application.dart';
|
||||
part 'primary_constructor.dart';
|
||||
part 'primary_constructor_field.dart';
|
||||
part 'setter.dart';
|
||||
part 'type_parameter.dart';
|
||||
part 'typedef.dart';
|
||||
|
||||
@@ -0,0 +1,428 @@
|
||||
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
part of 'fragment.dart';
|
||||
|
||||
class PrimaryConstructorFieldFragment implements Fragment {
|
||||
@override
|
||||
final String name;
|
||||
|
||||
final Uri fileUri;
|
||||
|
||||
final int nameOffset;
|
||||
|
||||
final List<MetadataBuilder>? metadata;
|
||||
|
||||
final TypeBuilder type;
|
||||
|
||||
final LookupScope enclosingScope;
|
||||
|
||||
final DeclarationFragment enclosingDeclaration;
|
||||
final LibraryFragment enclosingCompilationUnit;
|
||||
|
||||
SourcePropertyBuilder? _builder;
|
||||
PrimaryConstructorFieldDeclaration? _declaration;
|
||||
|
||||
PrimaryConstructorFieldFragment({
|
||||
required this.name,
|
||||
required this.fileUri,
|
||||
required this.nameOffset,
|
||||
required this.metadata,
|
||||
required this.type,
|
||||
required this.enclosingScope,
|
||||
required this.enclosingDeclaration,
|
||||
required this.enclosingCompilationUnit,
|
||||
});
|
||||
|
||||
@override
|
||||
SourcePropertyBuilder get builder {
|
||||
assert(_builder != null, "Builder has not been computed for $this.");
|
||||
return _builder!;
|
||||
}
|
||||
|
||||
void set builder(SourcePropertyBuilder value) {
|
||||
assert(_builder == null, "Builder has already been computed for $this.");
|
||||
_builder = value;
|
||||
}
|
||||
|
||||
PrimaryConstructorFieldDeclaration get declaration {
|
||||
assert(
|
||||
_declaration != null, "Declaration has not been computed for $this.");
|
||||
return _declaration!;
|
||||
}
|
||||
|
||||
void set declaration(PrimaryConstructorFieldDeclaration value) {
|
||||
assert(_declaration == null,
|
||||
"Declaration has already been computed for $this.");
|
||||
_declaration = value;
|
||||
}
|
||||
}
|
||||
|
||||
class PrimaryConstructorFieldDeclaration
|
||||
with FieldDeclarationMixin
|
||||
implements
|
||||
FieldDeclaration,
|
||||
FieldFragmentDeclaration,
|
||||
GetterDeclaration,
|
||||
Inferable,
|
||||
InferredTypeListener {
|
||||
final PrimaryConstructorFieldFragment _fragment;
|
||||
|
||||
late final FieldEncoding _encoding;
|
||||
|
||||
/// Whether the body of this field has been built.
|
||||
///
|
||||
/// Constant fields have their initializer built in the outline so we avoid
|
||||
/// building them twice as part of the non-outline build.
|
||||
bool hasBodyBeenBuilt = false;
|
||||
|
||||
PrimaryConstructorFieldDeclaration(this._fragment) {
|
||||
_fragment.declaration = this;
|
||||
}
|
||||
|
||||
@override
|
||||
SourcePropertyBuilder get builder => _fragment.builder;
|
||||
|
||||
@override
|
||||
FieldQuality get fieldQuality => FieldQuality.Concrete;
|
||||
|
||||
@override
|
||||
DartType get fieldType => _encoding.type;
|
||||
|
||||
@override
|
||||
Uri get fileUri => _fragment.fileUri;
|
||||
|
||||
@override
|
||||
GetterQuality get getterQuality => GetterQuality.Implicit;
|
||||
|
||||
@override
|
||||
bool get hasInitializer => false;
|
||||
|
||||
@override
|
||||
bool get hasSetter => false;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
shared.Expression? get initializerExpression => null;
|
||||
|
||||
@override
|
||||
bool get isConst => false;
|
||||
|
||||
@override
|
||||
bool get isEnumElement => false;
|
||||
|
||||
@override
|
||||
bool get isExtensionTypeDeclaredInstanceField => false;
|
||||
|
||||
@override
|
||||
bool get isFinal => true;
|
||||
|
||||
@override
|
||||
bool get isLate => false;
|
||||
|
||||
@override
|
||||
bool get isStatic => false;
|
||||
|
||||
@override
|
||||
List<ClassMember> get localMembers => _encoding.localMembers;
|
||||
|
||||
@override
|
||||
List<MetadataBuilder>? get metadata => _fragment.metadata;
|
||||
|
||||
@override
|
||||
int get nameOffset => _fragment.nameOffset;
|
||||
|
||||
@override
|
||||
Member get readTarget => _encoding.readTarget;
|
||||
|
||||
@override
|
||||
TypeBuilder get type => _fragment.type;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
DartType get fieldTypeInternal => _encoding.type;
|
||||
|
||||
@override
|
||||
void set fieldTypeInternal(DartType value) {
|
||||
_encoding.type = value;
|
||||
}
|
||||
|
||||
/// Builds the body of this field using [initializer] as the initializer
|
||||
/// expression.
|
||||
void buildBody(CoreTypes coreTypes, Expression? initializer) {
|
||||
assert(!hasBodyBeenBuilt, "Body has already been built for $this.");
|
||||
hasBodyBeenBuilt = true;
|
||||
_encoding.createBodies(coreTypes, initializer);
|
||||
}
|
||||
|
||||
@override
|
||||
Initializer buildErroneousInitializer(Expression effect, Expression value,
|
||||
{required int fileOffset}) {
|
||||
return _encoding.buildErroneousInitializer(effect, value,
|
||||
fileOffset: fileOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
void buildFieldInitializer(InferenceHelper helper, TypeInferrer typeInferrer,
|
||||
CoreTypes coreTypes, Expression? initializer) {
|
||||
if (initializer != null) {
|
||||
if (!hasBodyBeenBuilt) {
|
||||
initializer = typeInferrer
|
||||
.inferFieldInitializer(helper, fieldType, initializer)
|
||||
.expression;
|
||||
buildBody(coreTypes, initializer);
|
||||
}
|
||||
} else if (!hasBodyBeenBuilt) {
|
||||
buildBody(coreTypes, null);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void buildImplicitDefaultValue() {
|
||||
_encoding.buildImplicitDefaultValue();
|
||||
}
|
||||
|
||||
@override
|
||||
Initializer buildImplicitInitializer() {
|
||||
return _encoding.buildImplicitInitializer();
|
||||
}
|
||||
|
||||
@override
|
||||
List<Initializer> buildInitializer(int fileOffset, Expression value,
|
||||
{required bool isSynthetic}) {
|
||||
return _encoding.createInitializer(fileOffset, value,
|
||||
isSynthetic: isSynthetic);
|
||||
}
|
||||
|
||||
@override
|
||||
void buildFieldOutlineExpressions(
|
||||
{required ClassHierarchy classHierarchy,
|
||||
required SourceLibraryBuilder libraryBuilder,
|
||||
required DeclarationBuilder? declarationBuilder,
|
||||
required List<Annotatable> annotatables,
|
||||
required Uri annotatablesFileUri,
|
||||
required bool isClassInstanceMember}) {
|
||||
BodyBuilderContext bodyBuilderContext = createBodyBuilderContext();
|
||||
for (Annotatable annotatable in annotatables) {
|
||||
buildMetadataForOutlineExpressions(
|
||||
libraryBuilder: libraryBuilder,
|
||||
scope: _fragment.enclosingScope,
|
||||
bodyBuilderContext: bodyBuilderContext,
|
||||
annotatable: annotatable,
|
||||
annotatableFileUri: annotatablesFileUri,
|
||||
metadata: metadata);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void buildFieldOutlineNode(SourceLibraryBuilder libraryBuilder,
|
||||
NameScheme nameScheme, BuildNodesCallback f, FieldReference references,
|
||||
{required List<TypeParameter>? classTypeParameters}) {
|
||||
_encoding.buildOutlineNode(libraryBuilder, nameScheme, references,
|
||||
isAbstractOrExternal: false, classTypeParameters: classTypeParameters);
|
||||
if (type is! InferableTypeBuilder) {
|
||||
fieldType = type.build(libraryBuilder, TypeUse.fieldType);
|
||||
}
|
||||
_encoding.registerMembers(f);
|
||||
}
|
||||
|
||||
@override
|
||||
void checkFieldTypes(SourceLibraryBuilder libraryBuilder,
|
||||
TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder) {
|
||||
libraryBuilder.checkTypesInField(typeEnvironment,
|
||||
isInstanceMember: builder.isDeclarationInstanceMember,
|
||||
isLate: isLate,
|
||||
isExternal: false,
|
||||
hasInitializer: hasInitializer,
|
||||
fieldType: fieldType,
|
||||
name: _fragment.name,
|
||||
nameLength: _fragment.name.length,
|
||||
nameOffset: nameOffset,
|
||||
fileUri: fileUri);
|
||||
}
|
||||
|
||||
@override
|
||||
void checkFieldVariance(
|
||||
SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
|
||||
sourceClassBuilder.checkVarianceInField(typeEnvironment,
|
||||
fieldType: fieldType,
|
||||
isInstanceMember: !isStatic,
|
||||
hasSetter: hasSetter,
|
||||
isCovariantByDeclaration: false,
|
||||
fileUri: fileUri,
|
||||
fileOffset: nameOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
int computeFieldDefaultTypes(ComputeDefaultTypeContext context) {
|
||||
if (type is! OmittedTypeBuilder) {
|
||||
context.reportInboundReferenceIssuesForType(type);
|
||||
context.recursivelyReportGenericFunctionTypesAsBoundsForType(type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@override
|
||||
BodyBuilderContext createBodyBuilderContext() {
|
||||
return new FieldFragmentBodyBuilderContext(builder, this,
|
||||
isLateField: false,
|
||||
isAbstractField: false,
|
||||
isExternalField: false,
|
||||
nameOffset: _fragment.nameOffset,
|
||||
nameLength: _fragment.name.length,
|
||||
isConst: false);
|
||||
}
|
||||
|
||||
void createEncoding(SourcePropertyBuilder builder) {
|
||||
SourceLibraryBuilder libraryBuilder = builder.libraryBuilder;
|
||||
|
||||
bool isInstanceMember = builder.isDeclarationInstanceMember;
|
||||
bool isExtensionTypeMember = builder.isExtensionTypeMember;
|
||||
|
||||
// TODO(johnniwinther): Add support for regular fields for the primary
|
||||
// constructors feature.
|
||||
assert(isExtensionTypeMember && isInstanceMember);
|
||||
_encoding = new RepresentationFieldEncoding(_fragment);
|
||||
|
||||
type.registerInferredTypeListener(this);
|
||||
if (type is InferableTypeBuilder) {
|
||||
// A field with no type and initializer or an instance field without
|
||||
// type and initializer need to have the type inferred.
|
||||
_encoding.type = new InferredType(
|
||||
libraryBuilder: libraryBuilder,
|
||||
typeBuilder: type,
|
||||
inferType: inferType,
|
||||
computeType: _computeInferredType,
|
||||
fileUri: fileUri,
|
||||
name: _fragment.name,
|
||||
nameOffset: nameOffset,
|
||||
nameLength: _fragment.name.length,
|
||||
token: null);
|
||||
type.registerInferable(this);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void ensureTypes(
|
||||
ClassMembersBuilder membersBuilder,
|
||||
Set<ClassMember>? getterOverrideDependencies,
|
||||
Set<ClassMember>? setterOverrideDependencies) {
|
||||
if (getterOverrideDependencies != null ||
|
||||
setterOverrideDependencies != null) {
|
||||
membersBuilder.inferFieldType(
|
||||
builder.declarationBuilder as SourceClassBuilder,
|
||||
type,
|
||||
[...?getterOverrideDependencies, ...?setterOverrideDependencies],
|
||||
name: _fragment.name,
|
||||
fileUri: fileUri,
|
||||
nameOffset: nameOffset,
|
||||
nameLength: _fragment.name.length,
|
||||
isAssignable: hasSetter);
|
||||
} else {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
type.build(builder.libraryBuilder, TypeUse.fieldType,
|
||||
hierarchy: membersBuilder.hierarchyBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void registerSuperCall() {
|
||||
_encoding.registerSuperCall();
|
||||
}
|
||||
|
||||
DartType _computeInferredType(
|
||||
ClassHierarchyBase classHierarchy, Token? token) {
|
||||
DartType? inferredType;
|
||||
SourceLibraryBuilder libraryBuilder = builder.libraryBuilder;
|
||||
DeclarationBuilder? declarationBuilder = builder.declarationBuilder;
|
||||
if (token != null) {
|
||||
InterfaceType? enclosingClassThisType = declarationBuilder
|
||||
is SourceClassBuilder
|
||||
? libraryBuilder.loader.typeInferenceEngine.coreTypes
|
||||
.thisInterfaceType(
|
||||
declarationBuilder.cls, libraryBuilder.library.nonNullable)
|
||||
: null;
|
||||
LookupScope scope = _fragment.enclosingScope;
|
||||
TypeInferrer typeInferrer =
|
||||
libraryBuilder.loader.typeInferenceEngine.createTopLevelTypeInferrer(
|
||||
fileUri,
|
||||
enclosingClassThisType,
|
||||
libraryBuilder,
|
||||
scope,
|
||||
builder
|
||||
.dataForTesting
|
||||
// Coverage-ignore(suite): Not run.
|
||||
?.inferenceData);
|
||||
BodyBuilderContext bodyBuilderContext = createBodyBuilderContext();
|
||||
BodyBuilder bodyBuilder = libraryBuilder.loader.createBodyBuilderForField(
|
||||
libraryBuilder, bodyBuilderContext, scope, typeInferrer, fileUri);
|
||||
bodyBuilder.constantContext = ConstantContext.none;
|
||||
bodyBuilder.inFieldInitializer = true;
|
||||
bodyBuilder.inLateFieldInitializer = false;
|
||||
Expression initializer = bodyBuilder.parseFieldInitializer(token);
|
||||
|
||||
inferredType =
|
||||
typeInferrer.inferImplicitFieldType(bodyBuilder, initializer);
|
||||
} else {
|
||||
inferredType = const DynamicType();
|
||||
}
|
||||
return inferredType;
|
||||
}
|
||||
|
||||
@override
|
||||
void setCovariantByClassInternal() {
|
||||
_encoding.setCovariantByClass();
|
||||
}
|
||||
|
||||
@override
|
||||
void buildGetterOutlineExpressions(
|
||||
{required ClassHierarchy classHierarchy,
|
||||
required SourceLibraryBuilder libraryBuilder,
|
||||
required DeclarationBuilder? declarationBuilder,
|
||||
required SourcePropertyBuilder propertyBuilder,
|
||||
required Annotatable annotatable,
|
||||
required Uri annotatableFileUri,
|
||||
required bool isClassInstanceMember}) {}
|
||||
|
||||
@override
|
||||
void buildGetterOutlineNode(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
required NameScheme nameScheme,
|
||||
required BuildNodesCallback f,
|
||||
required PropertyReferences? references,
|
||||
required List<TypeParameter>? classTypeParameters}) {}
|
||||
|
||||
@override
|
||||
void checkGetterTypes(SourceLibraryBuilder libraryBuilder,
|
||||
TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder) {}
|
||||
|
||||
@override
|
||||
void checkGetterVariance(
|
||||
SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {}
|
||||
|
||||
@override
|
||||
int computeGetterDefaultTypes(ComputeDefaultTypeContext context) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@override
|
||||
void createGetterEncoding(
|
||||
ProblemReporting problemReporting,
|
||||
SourcePropertyBuilder builder,
|
||||
PropertyEncodingStrategy encodingStrategy,
|
||||
List<NominalParameterBuilder> unboundNominalParameters) {}
|
||||
|
||||
@override
|
||||
void ensureGetterTypes(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
required DeclarationBuilder? declarationBuilder,
|
||||
required ClassMembersBuilder membersBuilder,
|
||||
required Set<ClassMember>? getterOverrideDependencies}) {}
|
||||
|
||||
@override
|
||||
Iterable<Reference> getExportedGetterReferences(
|
||||
PropertyReferences references) {
|
||||
return [references.getterReference!];
|
||||
}
|
||||
}
|
||||
@@ -1347,17 +1347,12 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult {
|
||||
required TypeBuilder type,
|
||||
required String name,
|
||||
required int nameOffset}) {
|
||||
_declarationFragments.current.addPrimaryConstructorField(_addField(
|
||||
metadata: metadata,
|
||||
modifiers: Modifiers.Final,
|
||||
isTopLevel: false,
|
||||
type: type,
|
||||
name: name,
|
||||
nameOffset: nameOffset,
|
||||
endOffset: nameOffset,
|
||||
initializerToken: null,
|
||||
hasInitializer: false,
|
||||
isPrimaryConstructorField: true));
|
||||
_declarationFragments.current.addPrimaryConstructorField(
|
||||
_addPrimaryConstructorField(
|
||||
metadata: metadata,
|
||||
type: type,
|
||||
name: name,
|
||||
nameOffset: nameOffset));
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -1819,8 +1814,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult {
|
||||
initializerToken: startToken,
|
||||
hasInitializer: hasInitializer,
|
||||
constInitializerToken:
|
||||
potentiallyNeedInitializerInOutline ? startToken : null,
|
||||
isPrimaryConstructorField: false));
|
||||
potentiallyNeedInitializerInOutline ? startToken : null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1834,8 +1828,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult {
|
||||
required int endOffset,
|
||||
required Token? initializerToken,
|
||||
required bool hasInitializer,
|
||||
Token? constInitializerToken,
|
||||
required bool isPrimaryConstructorField}) {
|
||||
Token? constInitializerToken}) {
|
||||
DeclarationFragmentImpl? enclosingDeclaration =
|
||||
_declarationFragments.currentOrNull;
|
||||
if (hasInitializer) {
|
||||
@@ -1852,7 +1845,6 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult {
|
||||
type: type,
|
||||
isTopLevel: isTopLevel,
|
||||
modifiers: modifiers,
|
||||
isPrimaryConstructorField: isPrimaryConstructorField,
|
||||
enclosingScope:
|
||||
enclosingDeclaration?.bodyScope ?? _compilationUnitScope,
|
||||
enclosingDeclaration: enclosingDeclaration,
|
||||
@@ -1861,6 +1853,27 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult {
|
||||
return fragment;
|
||||
}
|
||||
|
||||
PrimaryConstructorFieldFragment _addPrimaryConstructorField(
|
||||
{required List<MetadataBuilder>? metadata,
|
||||
required TypeBuilder type,
|
||||
required String name,
|
||||
required int nameOffset}) {
|
||||
DeclarationFragmentImpl enclosingDeclaration =
|
||||
_declarationFragments.current;
|
||||
PrimaryConstructorFieldFragment fragment =
|
||||
new PrimaryConstructorFieldFragment(
|
||||
name: name,
|
||||
fileUri: _compilationUnit.fileUri,
|
||||
nameOffset: nameOffset,
|
||||
metadata: metadata,
|
||||
type: type,
|
||||
enclosingScope: enclosingDeclaration.bodyScope,
|
||||
enclosingDeclaration: enclosingDeclaration,
|
||||
enclosingCompilationUnit: _compilationUnit);
|
||||
_addFragment(fragment);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@override
|
||||
FormalParameterBuilder addFormalParameter(
|
||||
List<MetadataBuilder>? metadata,
|
||||
|
||||
@@ -76,7 +76,7 @@ class SourceExtensionTypeDeclarationBuilder
|
||||
|
||||
final ExtensionTypeFragment _introductory;
|
||||
|
||||
FieldFragment? _representationFieldFragment;
|
||||
PrimaryConstructorFieldFragment? _representationFieldFragment;
|
||||
|
||||
final IndexedContainer? indexedContainer;
|
||||
|
||||
@@ -92,7 +92,7 @@ class SourceExtensionTypeDeclarationBuilder
|
||||
required int endOffset,
|
||||
required ExtensionTypeFragment fragment,
|
||||
required this.indexedContainer,
|
||||
required FieldFragment? representationFieldFragment})
|
||||
required PrimaryConstructorFieldFragment? representationFieldFragment})
|
||||
: parent = enclosingLibraryBuilder,
|
||||
fileOffset = nameOffset,
|
||||
_modifiers = fragment.modifiers,
|
||||
|
||||
@@ -1045,6 +1045,7 @@ void _checkAugmentation(
|
||||
case MethodFragment():
|
||||
case PrimaryConstructorFragment():
|
||||
case SetterFragment():
|
||||
case PrimaryConstructorFieldFragment():
|
||||
if (fragmentName.inLibrary) {
|
||||
message = fragmentName.inPatch
|
||||
? templateUnmatchedPatchLibraryMember
|
||||
@@ -1102,6 +1103,7 @@ _PreBuilder _createPreBuilder(_FragmentName fragmentName) {
|
||||
case PrimaryConstructorFragment():
|
||||
return new _ConstructorPreBuilder(fragmentName);
|
||||
case FieldFragment():
|
||||
case PrimaryConstructorFieldFragment():
|
||||
return new _PropertyPreBuilder.forField(fragmentName);
|
||||
case GetterFragment():
|
||||
return new _PropertyPreBuilder.forGetter(fragmentName);
|
||||
@@ -1328,6 +1330,21 @@ void _computeBuildersFromFragments(String name, List<Fragment> fragments,
|
||||
inLibrary: declarationBuilder == null,
|
||||
);
|
||||
addFragment(fragmentName);
|
||||
case PrimaryConstructorFieldFragment():
|
||||
_FragmentName fragmentName = new _FragmentName(
|
||||
_FragmentKind.Property,
|
||||
fragment,
|
||||
fileUri: fragment.fileUri,
|
||||
name: fragment.name,
|
||||
nameOffset: fragment.nameOffset,
|
||||
nameLength: fragment.name.length,
|
||||
isAugment: false,
|
||||
propertyKind: _PropertyKind.FinalField,
|
||||
isStatic: false,
|
||||
inPatch: fragment.enclosingDeclaration.isPatch,
|
||||
inLibrary: false,
|
||||
);
|
||||
addFragment(fragmentName);
|
||||
case GetterFragment():
|
||||
_FragmentName fragmentName = new _FragmentName(
|
||||
_FragmentKind.Property,
|
||||
@@ -1442,6 +1459,17 @@ void _computeBuildersFromFragments(String name, List<Fragment> fragments,
|
||||
containerType: containerType,
|
||||
indexedContainer: indexedContainer,
|
||||
containerName: containerName));
|
||||
case PrimaryConstructorFieldFragment():
|
||||
builders.add(_createPrimaryConstructorFieldBuilder(fragment,
|
||||
problemReporting: problemReporting,
|
||||
loader: loader,
|
||||
enclosingLibraryBuilder: enclosingLibraryBuilder,
|
||||
declarationBuilder: declarationBuilder!,
|
||||
unboundNominalParameters: unboundNominalParameters,
|
||||
indexedLibrary: indexedLibrary,
|
||||
containerType: containerType,
|
||||
indexedContainer: indexedContainer,
|
||||
containerName: containerName));
|
||||
case GetterFragment():
|
||||
builders.add(_createGetterBuilder(fragment, augmentations,
|
||||
problemReporting: problemReporting,
|
||||
@@ -1768,7 +1796,7 @@ abstract class DeclarationFragmentImpl implements DeclarationFragment {
|
||||
|
||||
DeclarationBuilder get builder;
|
||||
|
||||
void addPrimaryConstructorField(FieldFragment fragment) {
|
||||
void addPrimaryConstructorField(PrimaryConstructorFieldFragment fragment) {
|
||||
throw new UnsupportedError(
|
||||
"Unexpected primary constructor field in $this.");
|
||||
}
|
||||
@@ -2398,9 +2426,9 @@ _AddBuilder _createExtensionTypeBuilder(ExtensionTypeFragment fragment,
|
||||
required IndexedLibrary? indexedLibrary}) {
|
||||
IndexedContainer? indexedContainer =
|
||||
indexedLibrary?.lookupIndexedExtensionTypeDeclaration(fragment.name);
|
||||
List<FieldFragment> primaryConstructorFields =
|
||||
List<PrimaryConstructorFieldFragment> primaryConstructorFields =
|
||||
fragment.primaryConstructorFields;
|
||||
FieldFragment? representationFieldFragment;
|
||||
PrimaryConstructorFieldFragment? representationFieldFragment;
|
||||
if (primaryConstructorFields.isNotEmpty) {
|
||||
representationFieldFragment = primaryConstructorFields.first;
|
||||
}
|
||||
@@ -2468,7 +2496,7 @@ _AddBuilder _createFieldBuilder(FieldFragment fragment,
|
||||
fieldIsLateWithLowering: fieldIsLateWithLowering,
|
||||
isExternal: fragment.modifiers.isExternal);
|
||||
|
||||
FieldDeclarationImpl declaration = new FieldDeclarationImpl(fragment);
|
||||
RegularFieldDeclaration declaration = new RegularFieldDeclaration(fragment);
|
||||
SourcePropertyBuilder propertyBuilder = new SourcePropertyBuilder.forField(
|
||||
fileUri: fragment.fileUri,
|
||||
fileOffset: fragment.nameOffset,
|
||||
@@ -2496,6 +2524,62 @@ _AddBuilder _createFieldBuilder(FieldFragment fragment,
|
||||
fragment.enclosingCompilationUnit.isPatch);
|
||||
}
|
||||
|
||||
_AddBuilder _createPrimaryConstructorFieldBuilder(
|
||||
PrimaryConstructorFieldFragment fragment,
|
||||
{required ProblemReporting problemReporting,
|
||||
required SourceLoader loader,
|
||||
required SourceLibraryBuilder enclosingLibraryBuilder,
|
||||
required DeclarationBuilder declarationBuilder,
|
||||
required List<NominalParameterBuilder> unboundNominalParameters,
|
||||
required IndexedLibrary? indexedLibrary,
|
||||
required ContainerType containerType,
|
||||
required IndexedContainer? indexedContainer,
|
||||
required ContainerName? containerName}) {
|
||||
String name = fragment.name;
|
||||
|
||||
final bool isInstanceMember = true;
|
||||
|
||||
PropertyEncodingStrategy propertyEncodingStrategy =
|
||||
new PropertyEncodingStrategy(declarationBuilder,
|
||||
isInstanceMember: isInstanceMember);
|
||||
|
||||
NameScheme nameScheme = new NameScheme(
|
||||
isInstanceMember: isInstanceMember,
|
||||
containerName: containerName,
|
||||
containerType: containerType,
|
||||
libraryName: indexedLibrary != null
|
||||
? new LibraryName(indexedLibrary.reference)
|
||||
: enclosingLibraryBuilder.libraryName);
|
||||
indexedContainer ??= indexedLibrary;
|
||||
|
||||
FieldReference references = new FieldReference(
|
||||
name, nameScheme, indexedContainer,
|
||||
fieldIsLateWithLowering: false, isExternal: false);
|
||||
|
||||
PrimaryConstructorFieldDeclaration declaration =
|
||||
new PrimaryConstructorFieldDeclaration(fragment);
|
||||
SourcePropertyBuilder propertyBuilder = new SourcePropertyBuilder.forField(
|
||||
fileUri: fragment.fileUri,
|
||||
fileOffset: fragment.nameOffset,
|
||||
name: name,
|
||||
libraryBuilder: enclosingLibraryBuilder,
|
||||
declarationBuilder: declarationBuilder,
|
||||
nameScheme: nameScheme,
|
||||
fieldDeclaration: declaration,
|
||||
getterDeclaration: declaration,
|
||||
setterDeclaration: null,
|
||||
modifiers: Modifiers.Final,
|
||||
references: references);
|
||||
fragment.builder = propertyBuilder;
|
||||
declaration.createEncoding(propertyBuilder);
|
||||
declaration.createGetterEncoding(problemReporting, propertyBuilder,
|
||||
propertyEncodingStrategy, unboundNominalParameters);
|
||||
references.registerReference(loader, propertyBuilder);
|
||||
return new _AddBuilder(
|
||||
fragment.name, propertyBuilder, fragment.fileUri, fragment.nameOffset,
|
||||
inPatch: fragment.enclosingDeclaration.isPatch);
|
||||
}
|
||||
|
||||
_AddBuilder _createGetterBuilder(
|
||||
GetterFragment fragment, List<Fragment>? augmentations,
|
||||
{required ProblemReporting problemReporting,
|
||||
|
||||
Reference in New Issue
Block a user