blob: 2a758a81434e6c016ff8306d0c2d8a06d270ddb4 [file] [log] [blame]
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:_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/method/encoding.dart';
import 'package:front_end/src/source/source_method_builder.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/reference_from_index.dart' show IndexedClass;
import 'package:kernel/src/bounds_checks.dart';
import 'package:kernel/transformations/flags.dart';
import 'package:kernel/type_environment.dart';
import '../base/modifiers.dart' show Modifiers;
import '../base/scope.dart';
import '../base/uri_offset.dart';
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/library_builder.dart';
import '../builder/member_builder.dart';
import '../builder/metadata_builder.dart';
import '../builder/method_builder.dart';
import '../builder/named_type_builder.dart';
import '../builder/nullability_builder.dart';
import '../builder/type_builder.dart';
import '../fragment/constructor/declaration.dart';
import '../fragment/field/declaration.dart';
import '../fragment/fragment.dart';
import '../fragment/getter/declaration.dart';
import '../fragment/method/declaration.dart';
import '../kernel/body_builder_context.dart';
import '../kernel/constructor_tearoff_lowering.dart';
import '../kernel/hierarchy/class_member.dart';
import '../kernel/hierarchy/members_builder.dart';
import '../kernel/kernel_helper.dart';
import '../kernel/member_covariance.dart';
import '../kernel/type_algorithms.dart';
import '../kernel/utils.dart';
import 'name_scheme.dart';
import 'source_class_builder.dart' show SourceClassBuilder;
import 'source_constructor_builder.dart';
import 'source_library_builder.dart' show SourceLibraryBuilder;
import 'source_member_builder.dart';
import 'source_property_builder.dart';
import 'source_type_parameter_builder.dart';
import 'type_parameter_scope_builder.dart';
class SourceEnumBuilder extends SourceClassBuilder {
final int startOffset;
final int endOffset;
final ClassDeclaration _introductory;
final List<EnumElementFragment> _enumElements;
final TypeBuilder _underscoreEnumTypeBuilder;
late final NamedTypeBuilder objectType;
late final NamedTypeBuilder listType;
late final NamedTypeBuilder selfType;
SourceConstructorBuilderImpl? _synthesizedDefaultConstructorBuilder;
late final _EnumValuesFieldDeclaration _enumValuesFieldDeclaration;
SourceEnumBuilder.internal(
{required String name,
required List<SourceNominalParameterBuilder>? typeParameters,
required TypeBuilder underscoreEnumTypeBuilder,
required LookupScope typeParameterScope,
required DeclarationNameSpaceBuilder nameSpaceBuilder,
required List<EnumElementFragment> enumElements,
required SourceLibraryBuilder libraryBuilder,
required Uri fileUri,
required this.startOffset,
required int nameOffset,
required this.endOffset,
required IndexedClass? indexedClass,
required ClassDeclaration classDeclaration})
: _underscoreEnumTypeBuilder = underscoreEnumTypeBuilder,
_introductory = classDeclaration,
_enumElements = enumElements,
super(
modifiers: Modifiers.empty,
name: name,
typeParameters: typeParameters,
typeParameterScope: typeParameterScope,
nameSpaceBuilder: nameSpaceBuilder,
libraryBuilder: libraryBuilder,
fileUri: fileUri,
nameOffset: nameOffset,
indexedClass: indexedClass,
introductory: classDeclaration);
factory SourceEnumBuilder(
{required String name,
required List<SourceNominalParameterBuilder>? typeParameters,
required TypeBuilder underscoreEnumTypeBuilder,
required List<TypeBuilder>? interfaceBuilders,
required List<EnumElementFragment> enumElements,
required SourceLibraryBuilder libraryBuilder,
required Uri fileUri,
required int startOffset,
required int nameOffset,
required int endOffset,
required IndexedClass? indexedClass,
required LookupScope typeParameterScope,
required DeclarationNameSpaceBuilder nameSpaceBuilder,
required ClassDeclaration classDeclaration}) {
SourceEnumBuilder enumBuilder = new SourceEnumBuilder.internal(
name: name,
typeParameters: typeParameters,
underscoreEnumTypeBuilder: underscoreEnumTypeBuilder,
typeParameterScope: typeParameterScope,
nameSpaceBuilder: nameSpaceBuilder,
enumElements: enumElements,
libraryBuilder: libraryBuilder,
fileUri: fileUri,
startOffset: startOffset,
nameOffset: nameOffset,
endOffset: endOffset,
indexedClass: indexedClass,
classDeclaration: classDeclaration);
return enumBuilder;
}
@override
void buildScopes(LibraryBuilder coreLibrary) {
super.buildScopes(coreLibrary);
_createSynthesizedMembers(coreLibrary);
Iterator<ConstructorBuilder> constructorIterator =
filteredConstructorsIterator(includeDuplicates: false);
while (constructorIterator.moveNext()) {
ConstructorBuilder constructorBuilder = constructorIterator.current;
if (!constructorBuilder.isConst) {
libraryBuilder.addProblem(messageEnumNonConstConstructor,
constructorBuilder.fileOffset, noLength, fileUri);
}
}
}
void _createSynthesizedMembers(LibraryBuilder coreLibrary) {
// TODO(ahe): These types shouldn't be looked up in scope, they come
// directly from dart:core.
objectType = new NamedTypeBuilderImpl(
const PredefinedTypeName("Object"), const NullabilityBuilder.omitted(),
instanceTypeParameterAccess:
InstanceTypeParameterAccessState.Unexpected);
selfType = new NamedTypeBuilderImpl(new SyntheticTypeName(name, fileOffset),
const NullabilityBuilder.omitted(),
instanceTypeParameterAccess:
InstanceTypeParameterAccessState.Unexpected,
fileUri: fileUri,
charOffset: fileOffset);
listType = new NamedTypeBuilderImpl(
const PredefinedTypeName("List"), const NullabilityBuilder.omitted(),
arguments: <TypeBuilder>[selfType],
instanceTypeParameterAccess:
InstanceTypeParameterAccessState.Unexpected);
// metadata class E extends _Enum {
// const E(int index, String name) : super(index, name);
// static const E id0 = const E(0, 'id0');
// ...
// static const E id${n-1} = const E(n - 1, 'idn-1');
// static const List<E> values = const <E>[id0, ..., id${n-1}];
// String _enumToString() {
// return "E.${_Enum::_name}";
// }
// }
LibraryName libraryName = indexedClass != null
? new LibraryName(indexedClass!.library.reference)
: libraryBuilder.libraryName;
NameScheme staticFieldNameScheme = new NameScheme(
isInstanceMember: false,
containerName: new ClassName(name),
containerType: ContainerType.Class,
libraryName: libraryName);
Reference? constructorReference;
Reference? tearOffReference;
Reference? toStringReference;
if (indexedClass != null) {
constructorReference =
indexedClass!.lookupConstructorReference(new Name(""));
tearOffReference = indexedClass!.lookupGetterReference(
new Name(constructorTearOffName(""), indexedClass!.library));
toStringReference = indexedClass!.lookupGetterReference(
new Name("_enumToString", coreLibrary.library));
}
PropertyReferences valuesReferences = new PropertyReferences(
"values", staticFieldNameScheme, indexedClass,
fieldIsLateWithLowering: false);
NamedBuilder? customValuesDeclaration =
nameSpace.lookupLocalMember("values")?.getable;
if (customValuesDeclaration != null) {
// Retrieve the earliest declaration for error reporting.
while (customValuesDeclaration?.next != null) {
customValuesDeclaration = customValuesDeclaration?.next;
}
libraryBuilder.addProblem(
messageEnumContainsValuesDeclaration,
customValuesDeclaration!.fileOffset,
customValuesDeclaration.fullNameForErrors.length,
fileUri);
}
for (String restrictedInstanceMemberName in const [
"index",
"hashCode",
"=="
]) {
NamedBuilder? customIndexDeclaration =
nameSpace.lookupLocalMember(restrictedInstanceMemberName)?.getable;
NamedBuilder? invalidDeclaration;
if (customIndexDeclaration is PropertyBuilder &&
!customIndexDeclaration.hasAbstractGetter &&
!customIndexDeclaration.isEnumElement) {
invalidDeclaration = customIndexDeclaration;
} else if (customIndexDeclaration is MethodBuilder &&
!customIndexDeclaration.isAbstract) {
invalidDeclaration = customIndexDeclaration;
}
if (invalidDeclaration != null) {
// Retrieve the earliest declaration for error reporting.
while (customIndexDeclaration?.next != null) {
// Coverage-ignore-block(suite): Not run.
customIndexDeclaration = customIndexDeclaration?.next;
}
libraryBuilder.addProblem(
templateEnumContainsRestrictedInstanceDeclaration
.withArguments(restrictedInstanceMemberName),
customIndexDeclaration!.fileOffset,
customIndexDeclaration.fullNameForErrors.length,
fileUri);
}
}
_enumValuesFieldDeclaration =
new _EnumValuesFieldDeclaration(this, listType);
SourcePropertyBuilder valuesBuilder = new SourcePropertyBuilder(
fileUri: fileUri,
fileOffset: fileOffset,
name: "values",
libraryBuilder: libraryBuilder,
declarationBuilder: this,
nameScheme: staticFieldNameScheme,
fieldDeclaration: _enumValuesFieldDeclaration,
getterDeclaration: _enumValuesFieldDeclaration,
getterAugmentations: const [],
setterDeclaration: null,
setterAugmentations: const [],
references: valuesReferences,
isStatic: true);
_enumValuesFieldDeclaration.builder = valuesBuilder;
if (customValuesDeclaration != null) {
customValuesDeclaration.next = valuesBuilder;
nameSpaceBuilder.checkTypeParameterConflict(libraryBuilder,
valuesBuilder.name, valuesBuilder, valuesBuilder.fileUri);
addMemberInternal(valuesBuilder, addToNameSpace: false);
} else {
addMemberInternal(valuesBuilder, addToNameSpace: true);
nameSpaceBuilder.checkTypeParameterConflict(libraryBuilder,
valuesBuilder.name, valuesBuilder, valuesBuilder.fileUri);
}
// The default constructor is added if no generative or unnamed factory
// constructors are declared.
bool needsSynthesizedDefaultConstructor = true;
Iterator<MemberBuilder> iterator = unfilteredConstructorsIterator;
while (iterator.moveNext()) {
MemberBuilder constructorBuilder = iterator.current;
if (constructorBuilder is! FactoryBuilder ||
constructorBuilder.name == "") {
needsSynthesizedDefaultConstructor = false;
break;
}
}
if (needsSynthesizedDefaultConstructor) {
FormalParameterBuilder nameFormalParameterBuilder =
new FormalParameterBuilder(
FormalParameterKind.requiredPositional,
Modifiers.empty,
libraryBuilder.loader.target.stringType,
"#name",
fileOffset,
fileUri: fileUri,
hasImmediatelyDeclaredInitializer: false);
FormalParameterBuilder indexFormalParameterBuilder =
new FormalParameterBuilder(
FormalParameterKind.requiredPositional,
Modifiers.empty,
libraryBuilder.loader.target.intType,
"#index",
fileOffset,
fileUri: fileUri,
hasImmediatelyDeclaredInitializer: false);
ConstructorDeclaration constructorDeclaration =
new DefaultEnumConstructorDeclaration(
returnType:
libraryBuilder.loader.inferableTypes.addInferableType(),
formals: [
indexFormalParameterBuilder,
nameFormalParameterBuilder
],
fileUri: fileUri,
fileOffset: fileOffset,
lookupScope: _introductory.compilationUnitScope);
SourceConstructorBuilderImpl constructorBuilder =
_synthesizedDefaultConstructorBuilder =
new SourceConstructorBuilderImpl(
modifiers: Modifiers.Const,
name: "",
libraryBuilder: libraryBuilder,
declarationBuilder: this,
fileUri: fileUri,
fileOffset: fileOffset,
constructorReference: constructorReference,
tearOffReference: tearOffReference,
nameScheme: new NameScheme(
isInstanceMember: false,
containerName: new ClassName(name),
containerType: ContainerType.Class,
libraryName: libraryName),
introductory: constructorDeclaration);
constructorBuilder.registerInitializedField(valuesBuilder);
addConstructorInternal(constructorBuilder, addToNameSpace: true);
nameSpaceBuilder.checkTypeParameterConflict(
libraryBuilder,
_synthesizedDefaultConstructorBuilder!.name,
_synthesizedDefaultConstructorBuilder!,
_synthesizedDefaultConstructorBuilder!.fileUri);
}
SourceMethodBuilder toStringBuilder = new SourceMethodBuilder(
name: "_enumToString",
fileUri: fileUri,
fileOffset: fileOffset,
libraryBuilder: libraryBuilder,
declarationBuilder: this,
nameScheme: new NameScheme(
isInstanceMember: true,
containerName: new ClassName(name),
containerType: ContainerType.Class,
libraryName: new LibraryName(coreLibrary.library.reference)),
introductory: new _EnumToStringMethodDeclaration(this,
libraryBuilder.loader.target.stringType, _underscoreEnumTypeBuilder,
fileUri: fileUri, fileOffset: fileOffset),
augmentations: const [],
isStatic: false,
modifiers: Modifiers.empty,
reference: toStringReference,
tearOffReference: null);
addMemberInternal(toStringBuilder, addToNameSpace: true);
nameSpaceBuilder.checkTypeParameterConflict(libraryBuilder,
toStringBuilder.name, toStringBuilder, toStringBuilder.fileUri);
selfType.bind(libraryBuilder, this);
if (name == "values") {
libraryBuilder.addProblem(
messageEnumWithNameValues, this.fileOffset, name.length, fileUri);
}
}
@override
bool get isEnum => true;
@override
TypeBuilder? get mixedInTypeBuilder => null;
@override
Class build(LibraryBuilder coreLibrary) {
int elementIndex = 0;
for (EnumElementFragment enumElement in _enumElements) {
if (!enumElement.builder.isDuplicate) {
enumElement.declaration.elementIndex = elementIndex++;
} else {
enumElement.declaration.elementIndex = -1;
}
}
bindCoreType(coreLibrary, objectType);
bindCoreType(coreLibrary, listType);
Class cls = super.build(coreLibrary);
cls.isEnum = true;
// The super initializer for the synthesized default constructor is
// inserted here if the enum's supertype is _Enum to preserve the legacy
// behavior or having the old-style enum constants built in the outlines.
// Other constructors are handled in [BodyBuilder.finishConstructor] as
// they are processed via the pipeline for constructor parsing and
// building.
if (identical(this.supertypeBuilder, _underscoreEnumTypeBuilder)) {
if (_synthesizedDefaultConstructorBuilder != null) {
Constructor constructor =
_synthesizedDefaultConstructorBuilder!.invokeTarget as Constructor;
ClassBuilder objectClass = objectType.declaration as ClassBuilder;
ClassBuilder enumClass =
_underscoreEnumTypeBuilder.declaration as ClassBuilder;
MemberBuilder? superConstructor = enumClass.findConstructorOrFactory(
"", fileOffset, fileUri, libraryBuilder);
if (superConstructor == null ||
superConstructor is! ConstructorBuilder) {
// Coverage-ignore-block(suite): Not run.
// TODO(ahe): Ideally, we would also want to check that [Object]'s
// unnamed constructor requires no arguments. But that information
// isn't always available at this point, and it's not really a
// situation that can happen unless you start modifying the SDK
// sources. (We should add a correct message. We no longer depend on
// Object here.)
libraryBuilder.addProblem(
messageNoUnnamedConstructorInObject,
objectClass.fileOffset,
objectClass.name.length,
objectClass.fileUri);
} else {
constructor.initializers.add(new SuperInitializer(
superConstructor.invokeTarget as Constructor,
new Arguments.forwarded(
constructor.function, libraryBuilder.library))
..parent = constructor);
}
_synthesizedDefaultConstructorBuilder = null;
}
}
return cls;
}
@override
BodyBuilderContext createBodyBuilderContext() {
return new EnumBodyBuilderContext(this);
}
@override
void buildOutlineExpressions(ClassHierarchy classHierarchy,
List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
for (EnumElementFragment enumElement in _enumElements) {
enumElement.declaration.inferType(classHierarchy);
}
_enumValuesFieldDeclaration.inferType(classHierarchy);
super.buildOutlineExpressions(classHierarchy, delayedDefaultValueCloners);
}
}
class _EnumToStringMethodDeclaration implements MethodDeclaration {
static const String _enumToStringName = "_enumToString";
final SourceEnumBuilder _enumBuilder;
final TypeBuilder _stringTypeBuilder;
final TypeBuilder _underscoreEnumTypeBuilder;
final Uri _fileUri;
final int _fileOffset;
late final Procedure _procedure;
_EnumToStringMethodDeclaration(this._enumBuilder, this._stringTypeBuilder,
this._underscoreEnumTypeBuilder,
{required Uri fileUri, required int fileOffset})
: _fileUri = fileUri,
_fileOffset = fileOffset;
@override
UriOffsetLength get uriOffset => new UriOffset(_fileUri, _fileOffset);
@override
void buildOutlineExpressions(
{required ClassHierarchy classHierarchy,
required SourceLibraryBuilder libraryBuilder,
required DeclarationBuilder? declarationBuilder,
required SourceMethodBuilder methodBuilder,
required Annotatable annotatable,
required Uri annotatableFileUri,
required bool isClassInstanceMember}) {
Name toStringName =
new Name(_enumToStringName, classHierarchy.coreTypes.coreLibrary);
Member? superToString = _enumBuilder.cls.superclass != null
? classHierarchy.getDispatchTarget(
_enumBuilder.cls.superclass!, toStringName)
: null;
Procedure? toStringSuperTarget = superToString is Procedure &&
// Coverage-ignore(suite): Not run.
superToString.enclosingClass != classHierarchy.coreTypes.objectClass
? superToString
: null;
if (toStringSuperTarget != null) {
// Coverage-ignore-block(suite): Not run.
_procedure.transformerFlags |= TransformerFlag.superCalls;
_procedure.function.body = new ReturnStatement(new SuperMethodInvocation(
toStringName, new Arguments([]), toStringSuperTarget))
..parent = _procedure.function;
} else {
ClassBuilder enumClass =
_underscoreEnumTypeBuilder.declaration as ClassBuilder;
MemberBuilder? nameFieldBuilder =
enumClass.lookupLocalMember("_name") as MemberBuilder?;
assert(nameFieldBuilder != null);
Field nameField = nameFieldBuilder!.readTarget as Field;
_procedure.function.body = new ReturnStatement(new StringConcatenation([
new StringLiteral("${_enumBuilder.cls.demangledName}."),
new InstanceGet.byReference(
InstanceAccessKind.Instance, new ThisExpression(), nameField.name,
interfaceTargetReference: nameField.getterReference,
resultType: nameField.getterType),
]))
..parent = _procedure.function;
}
}
@override
void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
NameScheme nameScheme, BuildNodesCallback f,
{required Reference reference,
required Reference? tearOffReference,
required List<TypeParameter>? classTypeParameters}) {
FunctionNode function = new FunctionNode(
new EmptyStatement()..fileOffset = _fileOffset,
returnType:
_stringTypeBuilder.build(libraryBuilder, TypeUse.returnType))
..fileOffset = _fileOffset
..fileEndOffset = _fileOffset;
_procedure = new Procedure(
nameScheme.getDeclaredName(_enumToStringName).name,
ProcedureKind.Method,
function,
fileUri: fileUri,
reference: reference)
..fileOffset = _fileOffset
..fileEndOffset = _fileOffset
..transformerFlags |= TransformerFlag.superCalls;
f(kind: BuiltMemberKind.Method, member: _procedure);
}
@override
void checkTypes(
SourceLibraryBuilder libraryBuilder, TypeEnvironment typeEnvironment) {}
@override
void checkVariance(
SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {}
@override
int computeDefaultTypes(ComputeDefaultTypeContext context) {
return 0;
}
@override
void createEncoding(
ProblemReporting problemReporting,
SourceMethodBuilder builder,
MethodEncodingStrategy encodingStrategy,
List<NominalParameterBuilder> unboundNominalParameters) {
throw new UnsupportedError("$runtimeType.createEncoding");
}
@override
void ensureTypes(
ClassMembersBuilder membersBuilder,
SourceClassBuilder enclosingClassBuilder,
Set<ClassMember>? overrideDependencies) {}
@override
Uri get fileUri => _fileUri;
@override
Procedure get invokeTarget => _procedure;
@override
bool get isOperator => false;
@override
// Coverage-ignore(suite): Not run.
List<MetadataBuilder>? get metadata => null;
@override
Procedure? get readTarget => null;
}
class _EnumValuesFieldDeclaration
implements FieldDeclaration, GetterDeclaration {
static const String name = "values";
final SourceEnumBuilder _sourceEnumBuilder;
SourcePropertyBuilder? _builder;
DartType _type = const DynamicType();
Field? _field;
final TypeBuilder _typeBuilder;
_EnumValuesFieldDeclaration(this._sourceEnumBuilder, this._typeBuilder);
@override
UriOffsetLength get uriOffset =>
new UriOffset(_sourceEnumBuilder.fileUri, _sourceEnumBuilder.fileOffset);
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;
}
@override
// Coverage-ignore(suite): Not run.
void createFieldEncoding(SourcePropertyBuilder builder) {}
@override
Initializer buildErroneousInitializer(Expression effect, Expression value,
{required int fileOffset}) {
throw new UnsupportedError('${runtimeType}.buildErroneousInitializer');
}
@override
void buildImplicitDefaultValue() {
throw new UnsupportedError('${runtimeType}.buildImplicitDefaultValue');
}
@override
Initializer buildImplicitInitializer() {
throw new UnsupportedError('${runtimeType}.buildImplicitInitializer');
}
@override
List<Initializer> buildInitializer(int fileOffset, Expression value,
{required bool isSynthetic}) {
throw new UnsupportedError('${runtimeType}.buildInitializer');
}
@override
void buildFieldOutlineExpressions(
{required ClassHierarchy classHierarchy,
required SourceLibraryBuilder libraryBuilder,
required DeclarationBuilder? declarationBuilder,
required List<Annotatable> annotatables,
required Uri annotatablesFileUri,
required bool isClassInstanceMember}) {
List<Expression> values = <Expression>[];
for (EnumElementFragment enumElement in _sourceEnumBuilder._enumElements) {
enumElement.declaration.inferType(classHierarchy);
if (!enumElement.builder.isDuplicate) {
values.add(new StaticGet(enumElement.declaration.readTarget));
}
}
_field!.initializer = new ListLiteral(values,
typeArgument: instantiateToBounds(
_sourceEnumBuilder.rawType(Nullability.nonNullable),
classHierarchy.coreTypes.objectClass),
isConst: true)
..parent = _field;
}
@override
void buildFieldOutlineNode(
SourceLibraryBuilder libraryBuilder,
NameScheme nameScheme,
BuildNodesCallback f,
PropertyReferences references,
{required List<TypeParameter>? classTypeParameters}) {
fieldType = _typeBuilder.build(libraryBuilder, TypeUse.fieldType);
_field = new Field.immutable(dummyName,
type: _type,
isFinal: false,
isConst: true,
isStatic: true,
fileUri: builder.fileUri,
fieldReference: references.fieldReference,
getterReference: references.getterReference,
isEnumElement: false)
..fileOffset = builder.fileOffset
..fileEndOffset = builder.fileOffset;
nameScheme
.getFieldMemberName(FieldNameType.Field, name, isSynthesized: false)
.attachMember(_field!);
f(member: _field!, kind: BuiltMemberKind.Field);
}
@override
void checkFieldTypes(SourceLibraryBuilder libraryBuilder,
TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder) {}
@override
// Coverage-ignore(suite): Not run.
void checkFieldVariance(
SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {}
@override
int computeFieldDefaultTypes(ComputeDefaultTypeContext context) {
return 0;
}
@override
// Coverage-ignore(suite): Not run.
void ensureTypes(
ClassMembersBuilder membersBuilder,
Set<ClassMember>? getterOverrideDependencies,
Set<ClassMember>? setterOverrideDependencies) {
inferType(membersBuilder.hierarchyBuilder);
}
@override
bool get hasInitializer => true;
@override
// Coverage-ignore(suite): Not run.
bool get hasSetter => false;
@override
// Coverage-ignore(suite): Not run.
shared.Expression? get initializerExpression => null;
@override
// Coverage-ignore(suite): Not run.
bool get isEnumElement => false;
@override
// Coverage-ignore(suite): Not run.
bool get isExtensionTypeDeclaredInstanceField => false;
@override
// Coverage-ignore(suite): Not run.
bool get isFinal => false;
@override
// Coverage-ignore(suite): Not run.
bool get isLate => false;
@override
// Coverage-ignore(suite): Not run.
bool get isConst => true;
@override
List<ClassMember> get localMembers =>
[new _EnumValuesClassMember(builder, uriOffset)];
@override
// Coverage-ignore(suite): Not run.
List<MetadataBuilder>? get metadata => null;
@override
Member get readTarget => _field!;
@override
// Coverage-ignore(suite): Not run.
DartType get fieldType => _type;
@override
void set fieldType(DartType value) {
_type = value;
_field
// Coverage-ignore(suite): Not run.
?.type = value;
}
@override
DartType inferType(ClassHierarchyBase hierarchy) {
return _type;
}
@override
FieldQuality get fieldQuality => FieldQuality.Concrete;
@override
GetterQuality get getterQuality => GetterQuality.Implicit;
@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
// Coverage-ignore(suite): Not run.
void checkGetterVariance(
SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {}
@override
int computeGetterDefaultTypes(ComputeDefaultTypeContext context) {
return 0;
}
@override
// Coverage-ignore(suite): Not run.
void createGetterEncoding(
ProblemReporting problemReporting,
SourcePropertyBuilder builder,
PropertyEncodingStrategy encodingStrategy,
List<NominalParameterBuilder> unboundNominalParameters) {}
@override
// Coverage-ignore(suite): Not run.
void ensureGetterTypes(
{required SourceLibraryBuilder libraryBuilder,
required DeclarationBuilder? declarationBuilder,
required ClassMembersBuilder membersBuilder,
required Set<ClassMember>? getterOverrideDependencies}) {}
@override
// Coverage-ignore(suite): Not run.
Uri get fileUri => _sourceEnumBuilder.fileUri;
@override
// Coverage-ignore(suite): Not run.
Iterable<Reference> getExportedGetterReferences(
PropertyReferences references) {
return [references.getterReference!];
}
}
class _EnumValuesClassMember implements ClassMember {
final SourcePropertyBuilder _builder;
@override
final UriOffsetLength uriOffset;
Covariance? _covariance;
_EnumValuesClassMember(this._builder, this.uriOffset);
@override
bool get forSetter => false;
@override
DeclarationBuilder get declarationBuilder => _builder.declarationBuilder!;
@override
// Coverage-ignore(suite): Not run.
List<ClassMember> get declarations =>
throw new UnsupportedError('$runtimeType.declarations');
@override
// Coverage-ignore(suite): Not run.
String get fullName {
String className = declarationBuilder.fullNameForErrors;
return "${className}.${fullNameForErrors}";
}
@override
// Coverage-ignore(suite): Not run.
String get fullNameForErrors => _builder.fullNameForErrors;
@override
// Coverage-ignore(suite): Not run.
Covariance getCovariance(ClassMembersBuilder membersBuilder) {
return _covariance ??= forSetter
? new Covariance.fromMember(getMember(membersBuilder),
forSetter: forSetter)
: const Covariance.empty();
}
@override
Member getMember(ClassMembersBuilder membersBuilder) {
inferType(membersBuilder);
return forSetter
?
// Coverage-ignore(suite): Not run.
_builder.writeTarget!
: _builder.readTarget!;
}
@override
// Coverage-ignore(suite): Not run.
MemberResult getMemberResult(ClassMembersBuilder membersBuilder) {
return new StaticMemberResult(getMember(membersBuilder), memberKind,
isDeclaredAsField: true,
fullName: '${declarationBuilder.name}.${_builder.memberName.text}');
}
@override
// Coverage-ignore(suite): Not run.
Member? getTearOff(ClassMembersBuilder membersBuilder) => null;
@override
bool get hasDeclarations => false;
@override
void inferType(ClassMembersBuilder membersBuilder) {
_builder.inferFieldType(membersBuilder.hierarchyBuilder);
}
@override
ClassMember get interfaceMember => this;
@override
bool get isAbstract => false;
@override
bool get isDuplicate => _builder.isDuplicate;
@override
// Coverage-ignore(suite): Not run.
bool get isExtensionTypeMember => _builder.isExtensionTypeMember;
@override
// Coverage-ignore(suite): Not run.
bool get isNoSuchMethodForwarder => false;
@override
// Coverage-ignore(suite): Not run.
bool isObjectMember(ClassBuilder objectClass) {
return declarationBuilder == objectClass;
}
@override
bool get isProperty => true;
@override
bool isSameDeclaration(ClassMember other) {
return other is _EnumValuesClassMember &&
// Coverage-ignore(suite): Not run.
_builder == other._builder;
}
@override
// Coverage-ignore(suite): Not run.
bool get isSetter => false;
@override
// Coverage-ignore(suite): Not run.
bool get isSourceDeclaration => true;
@override
bool get isStatic => true;
@override
bool get isSynthesized => true;
@override
// Coverage-ignore(suite): Not run.
ClassMemberKind get memberKind => ClassMemberKind.Getter;
@override
Name get name => _builder.memberName;
@override
// Coverage-ignore(suite): Not run.
void registerOverrideDependency(
ClassMembersBuilder membersBuilder, Set<ClassMember> overriddenMembers) {
_builder.registerGetterOverrideDependency(
membersBuilder, overriddenMembers);
}
@override
String toString() => '$runtimeType($fullName)';
}