[cfe] Create *FragmentDeclaration
This adds *FragmentDeclaration interfaces for member declaration in order to separate the interface used by the enclosing builder (which is shared between both syntactical and synthetic declarations) and by the body builder context (which is only needed for syntactical declarations). This also prepares for implementing the getter/setter aspect of a field fragment through the GetterDeclaration/SetterDeclaration interfaces. Change-Id: I314dfe084b2c9d48782d2f6a0c1ae20ff5f7d8c6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/424821 Reviewed-by: Chloe Stefantsova <cstefantsova@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
committed by
Commit Queue
parent
95e8d5b33b
commit
b23efe44e8
@@ -845,7 +845,6 @@ String createJoinedIntermediateName(String variableName, int index) {
|
||||
return '$variableName$joinedIntermediateInfix$index';
|
||||
}
|
||||
|
||||
// Coverage-ignore(suite): Not run.
|
||||
/// This turns Foo|bar into Foo.bar.
|
||||
///
|
||||
/// This only works for normal methods and operators, but for getters and
|
||||
|
||||
@@ -33,7 +33,7 @@ class ConstructorFragment implements Fragment, FunctionFragment {
|
||||
|
||||
SourceConstructorBuilderImpl? _builder;
|
||||
|
||||
ConstructorDeclaration? _declaration;
|
||||
ConstructorFragmentDeclaration? _declaration;
|
||||
|
||||
ConstructorFragment({
|
||||
required this.constructorName,
|
||||
@@ -79,13 +79,13 @@ class ConstructorFragment implements Fragment, FunctionFragment {
|
||||
_builder = value;
|
||||
}
|
||||
|
||||
ConstructorDeclaration get declaration {
|
||||
ConstructorFragmentDeclaration get declaration {
|
||||
assert(
|
||||
_declaration != null, "Declaration has not been computed for $this.");
|
||||
return _declaration!;
|
||||
}
|
||||
|
||||
void set declaration(ConstructorDeclaration value) {
|
||||
void set declaration(ConstructorFragmentDeclaration value) {
|
||||
assert(_declaration == null,
|
||||
"Declaration has already been computed for $this.");
|
||||
_declaration = value;
|
||||
|
||||
@@ -22,7 +22,7 @@ import 'declaration.dart';
|
||||
class ConstructorBodyBuilderContext extends BodyBuilderContext {
|
||||
final SourceConstructorBuilderImpl _builder;
|
||||
|
||||
final ConstructorDeclaration _declaration;
|
||||
final ConstructorFragmentDeclaration _declaration;
|
||||
|
||||
final Member _member;
|
||||
|
||||
|
||||
@@ -38,19 +38,20 @@ import '../../source/source_type_parameter_builder.dart';
|
||||
import '../fragment.dart';
|
||||
import 'encoding.dart';
|
||||
|
||||
/// Interface for the constructor declaration aspect of a
|
||||
/// [SourceConstructorBuilder].
|
||||
///
|
||||
/// If a constructor is augmented, it will have multiple
|
||||
/// [ConstructorDeclaration]s on a single [SourceConstructorBuilder].
|
||||
abstract class ConstructorDeclaration {
|
||||
int get fileOffset;
|
||||
|
||||
Uri get fileUri;
|
||||
|
||||
List<MetadataBuilder>? get metadata;
|
||||
|
||||
OmittedTypeBuilder get returnType;
|
||||
|
||||
List<FormalParameterBuilder>? get formals;
|
||||
|
||||
FunctionNode get function;
|
||||
|
||||
bool get hasParameters;
|
||||
|
||||
Member get readTarget;
|
||||
|
||||
Reference get readTargetReference;
|
||||
@@ -59,14 +60,6 @@ abstract class ConstructorDeclaration {
|
||||
|
||||
Reference get invokeTargetReference;
|
||||
|
||||
void registerFunctionBody(Statement value);
|
||||
|
||||
void registerNoBodyConstructor();
|
||||
|
||||
VariableDeclaration? get thisVariable;
|
||||
|
||||
List<TypeParameter>? get thisTypeParameters;
|
||||
|
||||
List<Initializer> get initializers;
|
||||
|
||||
void createNode({
|
||||
@@ -107,32 +100,11 @@ abstract class ConstructorDeclaration {
|
||||
|
||||
void prependInitializer(Initializer initializer);
|
||||
|
||||
void becomeNative();
|
||||
|
||||
/// Returns the [VariableDeclaration] for the [index]th formal parameter
|
||||
/// declared in the constructor.
|
||||
///
|
||||
/// The synthetic parameters of enum constructor are *not* included, so index
|
||||
/// 0 zero of an enum constructor is the first user defined parameter.
|
||||
VariableDeclaration getFormalParameter(int index);
|
||||
|
||||
/// Returns the [VariableDeclaration] for the tear off, if any, of the
|
||||
/// [index]th formal parameter declared in the constructor.
|
||||
VariableDeclaration? getTearOffParameter(int index);
|
||||
|
||||
FormalParameterBuilder? getFormal(Identifier identifier);
|
||||
|
||||
LocalScope computeFormalParameterScope(LookupScope parent);
|
||||
|
||||
LocalScope computeFormalParameterInitializerScope(LocalScope parent);
|
||||
|
||||
Substitution computeFieldTypeSubstitution(
|
||||
DeclarationBuilder declarationBuilder);
|
||||
|
||||
void buildBody();
|
||||
|
||||
bool get isConst;
|
||||
|
||||
bool get isExternal;
|
||||
|
||||
bool get isRedirecting;
|
||||
@@ -148,12 +120,10 @@ abstract class ConstructorDeclaration {
|
||||
SourceConstructorBuilderImpl constructorBuilder,
|
||||
ClassHierarchyBase hierarchy,
|
||||
List<DelayedDefaultValueCloner> delayedDefaultValueCloners);
|
||||
|
||||
BodyBuilderContext createBodyBuilderContext(
|
||||
SourceConstructorBuilderImpl constructorBuilder);
|
||||
}
|
||||
|
||||
mixin ConstructorDeclarationMixin implements ConstructorDeclaration {
|
||||
mixin ConstructorDeclarationMixin
|
||||
implements ConstructorDeclaration, ConstructorFragmentDeclaration {
|
||||
bool get _hasSuperInitializingFormals;
|
||||
|
||||
LookupScope get _typeParameterScope;
|
||||
@@ -162,6 +132,9 @@ mixin ConstructorDeclarationMixin implements ConstructorDeclaration {
|
||||
|
||||
List<SourceNominalParameterBuilder>? get _typeParameters;
|
||||
|
||||
@override
|
||||
bool get hasParameters => formals != null;
|
||||
|
||||
@override
|
||||
FormalParameterBuilder? getFormal(Identifier identifier) {
|
||||
if (formals != null) {
|
||||
@@ -672,11 +645,6 @@ mixin RegularConstructorDeclarationMixin
|
||||
_encoding.prependInitializer(initializer);
|
||||
}
|
||||
|
||||
@override
|
||||
void becomeNative() {
|
||||
_encoding.becomeNative();
|
||||
}
|
||||
|
||||
@override
|
||||
VariableDeclaration getFormalParameter(int index) {
|
||||
return _encoding.getFormalParameter(index);
|
||||
@@ -779,7 +747,7 @@ mixin RegularConstructorDeclarationMixin
|
||||
|
||||
class RegularConstructorDeclaration
|
||||
with ConstructorDeclarationMixin, RegularConstructorDeclarationMixin
|
||||
implements ConstructorDeclaration {
|
||||
implements ConstructorDeclaration, ConstructorFragmentDeclaration {
|
||||
final ConstructorFragment _fragment;
|
||||
final List<FormalParameterBuilder>? _syntheticFormals;
|
||||
|
||||
@@ -807,6 +775,11 @@ class RegularConstructorDeclaration
|
||||
_fragment.declaration = this;
|
||||
}
|
||||
|
||||
@override
|
||||
void becomeNative(SourceLoader loader) {
|
||||
_encoding.becomeNative(loader, _fragment.nativeMethodName!);
|
||||
}
|
||||
|
||||
@override
|
||||
LookupScope get _typeParameterScope => _fragment.typeParameterScope;
|
||||
|
||||
@@ -914,7 +887,7 @@ class RegularConstructorDeclaration
|
||||
// Coverage-ignore(suite): Not run.
|
||||
class PrimaryConstructorDeclaration
|
||||
with ConstructorDeclarationMixin, RegularConstructorDeclarationMixin
|
||||
implements ConstructorDeclaration {
|
||||
implements ConstructorDeclaration, ConstructorFragmentDeclaration {
|
||||
final PrimaryConstructorFragment _fragment;
|
||||
|
||||
@override
|
||||
@@ -931,6 +904,11 @@ class PrimaryConstructorDeclaration
|
||||
_fragment.declaration = this;
|
||||
}
|
||||
|
||||
@override
|
||||
void becomeNative(SourceLoader loader) {
|
||||
throw new UnsupportedError("$runtimeType.becomeNative()");
|
||||
}
|
||||
|
||||
@override
|
||||
LookupScope get _typeParameterScope => _fragment.typeParameterScope;
|
||||
|
||||
@@ -1066,6 +1044,11 @@ class DefaultEnumConstructorDeclaration
|
||||
// ensure building constructors creation during the outline phase.
|
||||
_beginInitializers = new Token.eof(-1);
|
||||
|
||||
@override
|
||||
void becomeNative(SourceLoader loader) {
|
||||
throw new UnsupportedError("$runtimeType.becomeNative()");
|
||||
}
|
||||
|
||||
@override
|
||||
LookupScope get _typeParameterScope => _lookupScope;
|
||||
|
||||
@@ -1199,7 +1182,7 @@ mixin ExtensionTypeConstructorDeclarationMixin
|
||||
}
|
||||
|
||||
@override
|
||||
void becomeNative() {
|
||||
void becomeNative(SourceLoader loader) {
|
||||
throw new UnsupportedError("$runtimeType.becomeNative()");
|
||||
}
|
||||
|
||||
@@ -1314,7 +1297,7 @@ mixin ExtensionTypeConstructorDeclarationMixin
|
||||
|
||||
class ExtensionTypeConstructorDeclaration
|
||||
with ConstructorDeclarationMixin, ExtensionTypeConstructorDeclarationMixin
|
||||
implements ConstructorDeclaration {
|
||||
implements ConstructorDeclaration, ConstructorFragmentDeclaration {
|
||||
final ConstructorFragment _fragment;
|
||||
|
||||
@override
|
||||
@@ -1438,7 +1421,7 @@ class ExtensionTypeConstructorDeclaration
|
||||
|
||||
class ExtensionTypePrimaryConstructorDeclaration
|
||||
with ConstructorDeclarationMixin, ExtensionTypeConstructorDeclarationMixin
|
||||
implements ConstructorDeclaration {
|
||||
implements ConstructorDeclaration, ConstructorFragmentDeclaration {
|
||||
final PrimaryConstructorFragment _fragment;
|
||||
|
||||
@override
|
||||
@@ -1551,3 +1534,49 @@ class ExtensionTypePrimaryConstructorDeclaration
|
||||
@override
|
||||
Uri get fileUri => _fragment.fileUri;
|
||||
}
|
||||
|
||||
/// Interface for using a [ConstructorFragment] or [PrimaryConstructorFragment]
|
||||
/// to create a [BodyBuilderContext].
|
||||
abstract class ConstructorFragmentDeclaration {
|
||||
int get fileOffset;
|
||||
|
||||
OmittedTypeBuilder get returnType;
|
||||
|
||||
List<FormalParameterBuilder>? get formals;
|
||||
|
||||
BodyBuilderContext createBodyBuilderContext(
|
||||
SourceConstructorBuilderImpl constructorBuilder);
|
||||
|
||||
FunctionNode get function;
|
||||
|
||||
void registerFunctionBody(Statement value);
|
||||
|
||||
void registerNoBodyConstructor();
|
||||
|
||||
VariableDeclaration? get thisVariable;
|
||||
|
||||
List<TypeParameter>? get thisTypeParameters;
|
||||
|
||||
void becomeNative(SourceLoader loader);
|
||||
|
||||
/// Returns the [VariableDeclaration] for the [index]th formal parameter
|
||||
/// declared in the constructor.
|
||||
///
|
||||
/// The synthetic parameters of enum constructor are *not* included, so index
|
||||
/// 0 zero of an enum constructor is the first user defined parameter.
|
||||
VariableDeclaration getFormalParameter(int index);
|
||||
|
||||
/// Returns the [VariableDeclaration] for the tear off, if any, of the
|
||||
/// [index]th formal parameter declared in the constructor.
|
||||
VariableDeclaration? getTearOffParameter(int index);
|
||||
|
||||
FormalParameterBuilder? getFormal(Identifier identifier);
|
||||
|
||||
LocalScope computeFormalParameterScope(LookupScope parent);
|
||||
|
||||
LocalScope computeFormalParameterInitializerScope(LocalScope parent);
|
||||
|
||||
bool get isConst;
|
||||
|
||||
bool get isExternal;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import '../../source/source_constructor_builder.dart';
|
||||
import '../../source/source_extension_type_declaration_builder.dart';
|
||||
import '../../source/source_function_builder.dart';
|
||||
import '../../source/source_library_builder.dart';
|
||||
import '../../source/source_loader.dart';
|
||||
import '../../source/source_member_builder.dart';
|
||||
import '../../source/source_type_parameter_builder.dart';
|
||||
import '../../type_inference/type_schema.dart';
|
||||
@@ -226,8 +227,10 @@ class RegularConstructorEncoding {
|
||||
_constructor.initializers.insert(0, initializer);
|
||||
}
|
||||
|
||||
void becomeNative() {
|
||||
void becomeNative(SourceLoader loader, String nativeMethodName) {
|
||||
_constructor.isExternal = true;
|
||||
|
||||
loader.addNativeAnnotation(_constructor, nativeMethodName);
|
||||
}
|
||||
|
||||
VariableDeclaration getFormalParameter(int index) {
|
||||
@@ -291,7 +294,7 @@ class RegularConstructorEncoding {
|
||||
|
||||
BodyBuilderContext createBodyBuilderContext(
|
||||
SourceConstructorBuilderImpl constructorBuilder,
|
||||
ConstructorDeclaration constructorDeclaration) {
|
||||
ConstructorFragmentDeclaration constructorDeclaration) {
|
||||
return new ConstructorBodyBuilderContext(
|
||||
constructorBuilder, constructorDeclaration, _constructor);
|
||||
}
|
||||
@@ -590,7 +593,7 @@ class ExtensionTypeConstructorEncoding {
|
||||
|
||||
BodyBuilderContext createBodyBuilderContext(
|
||||
SourceConstructorBuilderImpl constructorBuilder,
|
||||
ConstructorDeclaration constructorDeclaration) {
|
||||
ConstructorFragmentDeclaration constructorDeclaration) {
|
||||
return new ConstructorBodyBuilderContext(
|
||||
constructorBuilder, constructorDeclaration, _constructor);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ class FactoryFragment implements Fragment, FunctionFragment {
|
||||
|
||||
SourceFactoryBuilder? _builder;
|
||||
|
||||
FactoryDeclaration? _declaration;
|
||||
FactoryFragmentDeclaration? _declaration;
|
||||
|
||||
FactoryFragment({
|
||||
required this.constructorName,
|
||||
@@ -67,13 +67,13 @@ class FactoryFragment implements Fragment, FunctionFragment {
|
||||
_builder = value;
|
||||
}
|
||||
|
||||
FactoryDeclaration get declaration {
|
||||
FactoryFragmentDeclaration get declaration {
|
||||
assert(
|
||||
_declaration != null, "Declaration has not been computed for $this.");
|
||||
return _declaration!;
|
||||
}
|
||||
|
||||
void set declaration(FactoryDeclaration value) {
|
||||
void set declaration(FactoryFragmentDeclaration value) {
|
||||
assert(_declaration == null,
|
||||
"Declaration has already been computed for $this.");
|
||||
_declaration = value;
|
||||
|
||||
@@ -16,7 +16,7 @@ import 'declaration.dart';
|
||||
class FactoryBodyBuilderContext extends BodyBuilderContext {
|
||||
final SourceFactoryBuilder _builder;
|
||||
|
||||
final FactoryDeclaration _declaration;
|
||||
final FactoryFragmentDeclaration _declaration;
|
||||
|
||||
final Member _member;
|
||||
|
||||
|
||||
@@ -26,14 +26,47 @@ import '../../source/source_type_parameter_builder.dart';
|
||||
import 'body_builder_context.dart';
|
||||
import 'encoding.dart';
|
||||
|
||||
/// Interface for the factory declaration aspect of a [SourceFactoryBuilder].
|
||||
///
|
||||
/// If a factory is augmented, it will have multiple
|
||||
/// [FactoryDeclaration]s on a single [SourceFactoryBuilder].
|
||||
abstract class FactoryDeclaration {
|
||||
Procedure get procedure;
|
||||
|
||||
Procedure? get tearOff;
|
||||
Uri get fileUri;
|
||||
|
||||
FunctionNode get function;
|
||||
|
||||
TypeBuilder get returnType;
|
||||
Iterable<MetadataBuilder>? get metadata;
|
||||
|
||||
Procedure get procedure;
|
||||
|
||||
ConstructorReferenceBuilder? get redirectionTarget;
|
||||
|
||||
Procedure? get tearOff;
|
||||
|
||||
void buildOutlineExpressions(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
required SourceFactoryBuilder factoryBuilder,
|
||||
required ClassHierarchy classHierarchy,
|
||||
required List<DelayedDefaultValueCloner> delayedDefaultValueCloners,
|
||||
required bool createFileUriExpression});
|
||||
|
||||
void buildOutlineNodes(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
required SourceFactoryBuilder factoryBuilder,
|
||||
required BuildNodesCallback f,
|
||||
required bool isConst});
|
||||
|
||||
/// Checks this factory builder if it is for a redirecting factory.
|
||||
void checkRedirectingFactory(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
required SourceFactoryBuilder factoryBuilder,
|
||||
required TypeEnvironment typeEnvironment});
|
||||
|
||||
void checkTypes(SourceLibraryBuilder library, NameSpace nameSpace,
|
||||
TypeEnvironment typeEnvironment);
|
||||
|
||||
int computeDefaultTypes(ComputeDefaultTypeContext context,
|
||||
{required bool inErrorRecovery});
|
||||
|
||||
void createNode({
|
||||
required String name,
|
||||
@@ -43,80 +76,18 @@ abstract class FactoryDeclaration {
|
||||
required Reference? tearOffReference,
|
||||
});
|
||||
|
||||
void buildOutlineNodes(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
required SourceFactoryBuilder factoryBuilder,
|
||||
required BuildNodesCallback f,
|
||||
required bool isConst});
|
||||
|
||||
void buildOutlineExpressions(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
required SourceFactoryBuilder factoryBuilder,
|
||||
required ClassHierarchy classHierarchy,
|
||||
required List<DelayedDefaultValueCloner> delayedDefaultValueCloners,
|
||||
required bool createFileUriExpression});
|
||||
|
||||
void inferRedirectionTarget(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
required SourceFactoryBuilder factoryBuilder,
|
||||
required ClassHierarchy classHierarchy,
|
||||
required List<DelayedDefaultValueCloner> delayedDefaultValueCloners});
|
||||
|
||||
/// Checks this factory builder if it is for a redirecting factory.
|
||||
void checkRedirectingFactory(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
required SourceFactoryBuilder factoryBuilder,
|
||||
required TypeEnvironment typeEnvironment});
|
||||
|
||||
int computeDefaultTypes(ComputeDefaultTypeContext context,
|
||||
{required bool inErrorRecovery});
|
||||
|
||||
void checkTypes(SourceLibraryBuilder library, NameSpace nameSpace,
|
||||
TypeEnvironment typeEnvironment);
|
||||
|
||||
void setBody(Statement value);
|
||||
|
||||
void setAsyncModifier(AsyncMarker newModifier);
|
||||
|
||||
FormalParameterBuilder? getFormal(Identifier identifier);
|
||||
|
||||
VariableDeclaration? getTearOffParameter(int index);
|
||||
|
||||
abstract List<DartType>? redirectionTypeArguments;
|
||||
|
||||
bool get isNative;
|
||||
|
||||
bool get isExternal;
|
||||
|
||||
Uri get fileUri;
|
||||
|
||||
int get fileOffset;
|
||||
|
||||
void becomeNative(
|
||||
{required SourceLoader loader,
|
||||
required Iterable<Annotatable> annotatables});
|
||||
|
||||
void resolveRedirectingFactory(
|
||||
{required SourceLibraryBuilder libraryBuilder});
|
||||
|
||||
List<FormalParameterBuilder>? get formals;
|
||||
|
||||
/// Returns the [index]th parameter of this function.
|
||||
///
|
||||
/// The index is the syntactical index, including both positional and named
|
||||
/// parameter in the order they are declared, and excluding the synthesized
|
||||
/// this parameter on extension instance members.
|
||||
VariableDeclaration getFormalParameter(int index);
|
||||
|
||||
Iterable<MetadataBuilder>? get metadata;
|
||||
|
||||
ConstructorReferenceBuilder? get redirectionTarget;
|
||||
|
||||
BodyBuilderContext createBodyBuilderContext(
|
||||
SourceFactoryBuilder factoryBuilder);
|
||||
}
|
||||
|
||||
class FactoryDeclarationImpl implements FactoryDeclaration {
|
||||
class FactoryDeclarationImpl
|
||||
implements FactoryDeclaration, FactoryFragmentDeclaration {
|
||||
final FactoryFragment _fragment;
|
||||
final List<SourceNominalParameterBuilder>? typeParameters;
|
||||
@override
|
||||
@@ -133,73 +104,46 @@ class FactoryDeclarationImpl implements FactoryDeclaration {
|
||||
}
|
||||
|
||||
@override
|
||||
Procedure get procedure => _encoding.procedure;
|
||||
int get fileOffset => _fragment.fullNameOffset;
|
||||
|
||||
@override
|
||||
Procedure? get tearOff => _encoding.tearOff;
|
||||
Uri get fileUri => _fragment.fileUri;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<FormalParameterBuilder>? get formals => _fragment.formals;
|
||||
|
||||
@override
|
||||
FunctionNode get function => _encoding.function;
|
||||
|
||||
@override
|
||||
bool get isExternal => _fragment.modifiers.isExternal;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isNative => _encoding.isNative;
|
||||
|
||||
@override
|
||||
bool get isExternal => _fragment.modifiers.isExternal;
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Iterable<MetadataBuilder>? get metadata => _fragment.metadata;
|
||||
|
||||
@override
|
||||
Uri get fileUri => _fragment.fileUri;
|
||||
Procedure get procedure => _encoding.procedure;
|
||||
|
||||
@override
|
||||
int get fileOffset => _fragment.fullNameOffset;
|
||||
ConstructorReferenceBuilder? get redirectionTarget {
|
||||
return _fragment.redirectionTarget;
|
||||
}
|
||||
|
||||
@override
|
||||
void becomeNative(
|
||||
{required SourceLoader loader,
|
||||
required Iterable<Annotatable> annotatables}) {
|
||||
for (Annotatable annotatable in annotatables) {
|
||||
loader.addNativeAnnotation(annotatable, _fragment.nativeMethodName!);
|
||||
}
|
||||
Procedure? get tearOff => _encoding.tearOff;
|
||||
|
||||
@override
|
||||
void becomeNative(SourceLoader loader) {
|
||||
loader.addNativeAnnotation(procedure, _fragment.nativeMethodName!);
|
||||
_encoding.becomeNative(loader);
|
||||
}
|
||||
|
||||
@override
|
||||
void createNode({
|
||||
required String name,
|
||||
required SourceLibraryBuilder libraryBuilder,
|
||||
required NameScheme nameScheme,
|
||||
required Reference? procedureReference,
|
||||
required Reference? tearOffReference,
|
||||
}) {
|
||||
_encoding.createNode(
|
||||
name: name,
|
||||
libraryBuilder: libraryBuilder,
|
||||
nameScheme: nameScheme,
|
||||
procedureReference: procedureReference,
|
||||
tearOffReference: tearOffReference);
|
||||
}
|
||||
|
||||
@override
|
||||
void buildOutlineNodes(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
required SourceFactoryBuilder factoryBuilder,
|
||||
required BuildNodesCallback f,
|
||||
required bool isConst}) {
|
||||
_encoding.buildOutlineNodes(
|
||||
libraryBuilder: libraryBuilder,
|
||||
factoryBuilder: factoryBuilder,
|
||||
f: f,
|
||||
isConst: isConst);
|
||||
}
|
||||
|
||||
@override
|
||||
BodyBuilderContext createBodyBuilderContext(
|
||||
SourceFactoryBuilder factoryBuilder) {
|
||||
return new FactoryBodyBuilderContext(
|
||||
factoryBuilder, this, _encoding.procedure);
|
||||
}
|
||||
|
||||
@override
|
||||
void buildOutlineExpressions(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
@@ -248,19 +192,16 @@ class FactoryDeclarationImpl implements FactoryDeclaration {
|
||||
}
|
||||
|
||||
@override
|
||||
void inferRedirectionTarget(
|
||||
void buildOutlineNodes(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
required SourceFactoryBuilder factoryBuilder,
|
||||
required ClassHierarchy classHierarchy,
|
||||
required List<DelayedDefaultValueCloner> delayedDefaultValueCloners}) {
|
||||
BodyBuilderContext bodyBuilderContext =
|
||||
createBodyBuilderContext(factoryBuilder);
|
||||
_encoding.inferRedirectionTarget(
|
||||
required BuildNodesCallback f,
|
||||
required bool isConst}) {
|
||||
_encoding.buildOutlineNodes(
|
||||
libraryBuilder: libraryBuilder,
|
||||
declarationBuilder: factoryBuilder.declarationBuilder,
|
||||
bodyBuilderContext: bodyBuilderContext,
|
||||
classHierarchy: classHierarchy,
|
||||
delayedDefaultValueCloners: delayedDefaultValueCloners);
|
||||
factoryBuilder: factoryBuilder,
|
||||
f: f,
|
||||
isConst: isConst);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -274,17 +215,6 @@ class FactoryDeclarationImpl implements FactoryDeclaration {
|
||||
typeEnvironment: typeEnvironment);
|
||||
}
|
||||
|
||||
@override
|
||||
int computeDefaultTypes(ComputeDefaultTypeContext context,
|
||||
{required bool inErrorRecovery}) {
|
||||
int count = context.computeDefaultTypesForVariables(typeParameters,
|
||||
// Type parameters are inherited from the enclosing declaration, so if
|
||||
// it has issues, so do the constructors.
|
||||
inErrorRecovery: inErrorRecovery);
|
||||
context.reportGenericFunctionTypesForFormals(_fragment.formals);
|
||||
return count;
|
||||
}
|
||||
|
||||
@override
|
||||
void checkTypes(SourceLibraryBuilder library, NameSpace nameSpace,
|
||||
TypeEnvironment typeEnvironment) {
|
||||
@@ -299,13 +229,37 @@ class FactoryDeclarationImpl implements FactoryDeclaration {
|
||||
}
|
||||
|
||||
@override
|
||||
void setBody(Statement value) {
|
||||
_encoding.setBody(value);
|
||||
int computeDefaultTypes(ComputeDefaultTypeContext context,
|
||||
{required bool inErrorRecovery}) {
|
||||
int count = context.computeDefaultTypesForVariables(typeParameters,
|
||||
// Type parameters are inherited from the enclosing declaration, so if
|
||||
// it has issues, so do the constructors.
|
||||
inErrorRecovery: inErrorRecovery);
|
||||
context.reportGenericFunctionTypesForFormals(_fragment.formals);
|
||||
return count;
|
||||
}
|
||||
|
||||
@override
|
||||
void setAsyncModifier(AsyncMarker newModifier) {
|
||||
_encoding.asyncModifier = newModifier;
|
||||
BodyBuilderContext createBodyBuilderContext(
|
||||
SourceFactoryBuilder factoryBuilder) {
|
||||
return new FactoryBodyBuilderContext(
|
||||
factoryBuilder, this, _encoding.procedure);
|
||||
}
|
||||
|
||||
@override
|
||||
void createNode({
|
||||
required String name,
|
||||
required SourceLibraryBuilder libraryBuilder,
|
||||
required NameScheme nameScheme,
|
||||
required Reference? procedureReference,
|
||||
required Reference? tearOffReference,
|
||||
}) {
|
||||
_encoding.createNode(
|
||||
name: name,
|
||||
libraryBuilder: libraryBuilder,
|
||||
nameScheme: nameScheme,
|
||||
procedureReference: procedureReference,
|
||||
tearOffReference: tearOffReference);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -313,20 +267,29 @@ class FactoryDeclarationImpl implements FactoryDeclaration {
|
||||
return _encoding.getFormal(identifier);
|
||||
}
|
||||
|
||||
@override
|
||||
VariableDeclaration getFormalParameter(int index) =>
|
||||
_fragment.formals![index].variable!;
|
||||
|
||||
@override
|
||||
VariableDeclaration? getTearOffParameter(int index) {
|
||||
return _encoding.getTearOffParameter(index);
|
||||
}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<DartType>? get redirectionTypeArguments =>
|
||||
_encoding.redirectionTypeArguments;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void set redirectionTypeArguments(List<DartType>? value) {
|
||||
_encoding.redirectionTypeArguments = value;
|
||||
void inferRedirectionTarget(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
required SourceFactoryBuilder factoryBuilder,
|
||||
required ClassHierarchy classHierarchy,
|
||||
required List<DelayedDefaultValueCloner> delayedDefaultValueCloners}) {
|
||||
BodyBuilderContext bodyBuilderContext =
|
||||
createBodyBuilderContext(factoryBuilder);
|
||||
_encoding.inferRedirectionTarget(
|
||||
libraryBuilder: libraryBuilder,
|
||||
declarationBuilder: factoryBuilder.declarationBuilder,
|
||||
bodyBuilderContext: bodyBuilderContext,
|
||||
classHierarchy: classHierarchy,
|
||||
delayedDefaultValueCloners: delayedDefaultValueCloners);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -336,19 +299,55 @@ class FactoryDeclarationImpl implements FactoryDeclaration {
|
||||
}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<FormalParameterBuilder>? get formals => _fragment.formals;
|
||||
void setAsyncModifier(AsyncMarker newModifier) {
|
||||
_encoding.asyncModifier = newModifier;
|
||||
}
|
||||
|
||||
@override
|
||||
VariableDeclaration getFormalParameter(int index) =>
|
||||
_fragment.formals![index].variable!;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Iterable<MetadataBuilder>? get metadata => _fragment.metadata;
|
||||
|
||||
@override
|
||||
ConstructorReferenceBuilder? get redirectionTarget {
|
||||
return _fragment.redirectionTarget;
|
||||
void setBody(Statement value) {
|
||||
_encoding.setBody(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// Interface for using a [FactoryFragment] to create a [BodyBuilderContext].
|
||||
abstract class FactoryFragmentDeclaration {
|
||||
int get fileOffset;
|
||||
|
||||
List<FormalParameterBuilder>? get formals;
|
||||
|
||||
FunctionNode get function;
|
||||
|
||||
bool get isExternal;
|
||||
|
||||
bool get isNative;
|
||||
|
||||
ConstructorReferenceBuilder? get redirectionTarget;
|
||||
|
||||
TypeBuilder get returnType;
|
||||
|
||||
void becomeNative(SourceLoader loader);
|
||||
|
||||
BodyBuilderContext createBodyBuilderContext(
|
||||
SourceFactoryBuilder factoryBuilder);
|
||||
|
||||
FormalParameterBuilder? getFormal(Identifier identifier);
|
||||
|
||||
/// Returns the [index]th parameter of this function.
|
||||
///
|
||||
/// The index is the syntactical index, including both positional and named
|
||||
/// parameter in the order they are declared, and excluding the synthesized
|
||||
/// this parameter on extension instance members.
|
||||
VariableDeclaration getFormalParameter(int index);
|
||||
|
||||
/// If this is an extension instance method or constructor with lowering
|
||||
/// enabled, the tear off parameter corresponding to the [index]th parameter
|
||||
/// on the instance method or constructor is returned.
|
||||
///
|
||||
/// This is used to update the default value for the closure parameter when
|
||||
/// it has been computed for the original parameter.
|
||||
VariableDeclaration? getTearOffParameter(int index);
|
||||
|
||||
void setAsyncModifier(AsyncMarker newModifier);
|
||||
|
||||
void setBody(Statement value);
|
||||
}
|
||||
|
||||
@@ -4,131 +4,281 @@
|
||||
|
||||
part of 'fragment.dart';
|
||||
|
||||
class FieldFragment implements Fragment {
|
||||
@override
|
||||
final String name;
|
||||
|
||||
final Uri fileUri;
|
||||
|
||||
final int nameOffset;
|
||||
|
||||
final int endOffset;
|
||||
|
||||
Token? _initializerToken;
|
||||
Token? _constInitializerToken;
|
||||
|
||||
final List<MetadataBuilder>? metadata;
|
||||
|
||||
final TypeBuilder type;
|
||||
|
||||
final bool isTopLevel;
|
||||
final Modifiers modifiers;
|
||||
// TODO(johnniwinther): Create separate fragment for primary constructor
|
||||
// fields.
|
||||
final bool isPrimaryConstructorField;
|
||||
|
||||
final LookupScope enclosingScope;
|
||||
|
||||
final DeclarationFragment? enclosingDeclaration;
|
||||
final LibraryFragment enclosingCompilationUnit;
|
||||
|
||||
SourcePropertyBuilder? _builder;
|
||||
FieldFragmentDeclaration? _declaration;
|
||||
|
||||
FieldFragment({
|
||||
required this.name,
|
||||
required this.fileUri,
|
||||
required this.nameOffset,
|
||||
required this.endOffset,
|
||||
required Token? initializerToken,
|
||||
required Token? constInitializerToken,
|
||||
required this.metadata,
|
||||
required this.type,
|
||||
required this.isTopLevel,
|
||||
required this.modifiers,
|
||||
required this.isPrimaryConstructorField,
|
||||
required this.enclosingScope,
|
||||
required this.enclosingDeclaration,
|
||||
required this.enclosingCompilationUnit,
|
||||
}) : _initializerToken = initializerToken,
|
||||
_constInitializerToken = constInitializerToken;
|
||||
|
||||
bool get hasSetter {
|
||||
if (modifiers.isConst) {
|
||||
return false;
|
||||
} else if (modifiers.isFinal) {
|
||||
if (modifiers.isLate) {
|
||||
return !modifiers.hasInitializer;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the token for the initializer of this field, if any.
|
||||
///
|
||||
/// This can only be called once and will hand over the responsibility of
|
||||
/// the token to the caller.
|
||||
Token? get initializerToken {
|
||||
Token? result = _initializerToken;
|
||||
// Ensure that we don't hold onto the token.
|
||||
_initializerToken = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Returns the token for the initializer of this field, if any. This is the
|
||||
/// same as [initializerToken] but is used to signal that the initializer
|
||||
/// needs to be computed for outline expressions.
|
||||
///
|
||||
/// This can only be called once and will hand over the responsibility of
|
||||
/// the token to the caller.
|
||||
Token? get constInitializerToken {
|
||||
Token? result = _constInitializerToken;
|
||||
// Ensure that we don't hold onto the token.
|
||||
_constInitializerToken = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
FieldFragmentDeclaration get declaration {
|
||||
assert(
|
||||
_declaration != null, "Declaration has not been computed for $this.");
|
||||
return _declaration!;
|
||||
}
|
||||
|
||||
void set declaration(FieldFragmentDeclaration value) {
|
||||
assert(_declaration == null,
|
||||
"Declaration has already been computed for $this.");
|
||||
_declaration = value;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => '$runtimeType($name,$fileUri,$nameOffset)';
|
||||
}
|
||||
|
||||
class FieldFragmentDeclaration
|
||||
class FieldDeclarationImpl
|
||||
with FieldDeclarationMixin
|
||||
implements FieldDeclaration, Inferable, InferredTypeListener {
|
||||
implements
|
||||
FieldDeclaration,
|
||||
FieldFragmentDeclaration,
|
||||
Inferable,
|
||||
InferredTypeListener {
|
||||
final FieldFragment _fragment;
|
||||
|
||||
late final _FieldEncoding _encoding;
|
||||
|
||||
FieldFragmentDeclaration(this._fragment) {
|
||||
shared.Expression? _initializerExpression;
|
||||
|
||||
/// 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;
|
||||
|
||||
FieldDeclarationImpl(this._fragment) {
|
||||
_fragment.declaration = this;
|
||||
}
|
||||
|
||||
@override
|
||||
SourcePropertyBuilder get builder => _fragment.builder;
|
||||
|
||||
@override
|
||||
FieldQuality get fieldQuality => _fragment.modifiers.isAbstract
|
||||
? FieldQuality.Abstract
|
||||
: _fragment.modifiers.isExternal
|
||||
? FieldQuality.External
|
||||
: FieldQuality.Concrete;
|
||||
|
||||
@override
|
||||
DartType get fieldType => _encoding.type;
|
||||
|
||||
@override
|
||||
Uri get fileUri => _fragment.fileUri;
|
||||
|
||||
@override
|
||||
GetterQuality get getterQuality => _fragment.modifiers.isAbstract
|
||||
? GetterQuality.ImplicitAbstract
|
||||
: _fragment.modifiers.isExternal
|
||||
? GetterQuality.ImplicitExternal
|
||||
: GetterQuality.Implicit;
|
||||
|
||||
@override
|
||||
bool get hasInitializer => _fragment.modifiers.hasInitializer;
|
||||
|
||||
@override
|
||||
bool get hasSetter => _fragment.hasSetter;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
shared.Expression? get initializerExpression => _initializerExpression;
|
||||
|
||||
@override
|
||||
bool get isConst => _fragment.modifiers.isConst;
|
||||
|
||||
@override
|
||||
bool get isEnumElement => false;
|
||||
|
||||
@override
|
||||
bool get isExtensionTypeDeclaredInstanceField =>
|
||||
builder.isExtensionTypeInstanceMember &&
|
||||
!_fragment.isPrimaryConstructorField;
|
||||
|
||||
@override
|
||||
bool get isFinal => _fragment.modifiers.isFinal;
|
||||
|
||||
@override
|
||||
bool get isLate => _fragment.modifiers.isLate;
|
||||
|
||||
@override
|
||||
bool get isStatic =>
|
||||
_fragment.modifiers.isStatic || builder.declarationBuilder == null;
|
||||
|
||||
@override
|
||||
List<ClassMember> get localMembers => _encoding.localMembers;
|
||||
|
||||
@override
|
||||
List<ClassMember> get localSetters => _encoding.localSetters;
|
||||
|
||||
@override
|
||||
List<MetadataBuilder>? get metadata => _fragment.metadata;
|
||||
|
||||
@override
|
||||
int get nameOffset => _fragment.nameOffset;
|
||||
|
||||
@override
|
||||
Member get readTarget => _encoding.readTarget;
|
||||
|
||||
@override
|
||||
SetterQuality get setterQuality => !hasSetter
|
||||
? SetterQuality.Absent
|
||||
: _fragment.modifiers.isAbstract
|
||||
? SetterQuality.ImplicitAbstract
|
||||
: _fragment.modifiers.isExternal
|
||||
? SetterQuality.ImplicitExternal
|
||||
: SetterQuality.Implicit;
|
||||
|
||||
@override
|
||||
TypeBuilder get type => _fragment.type;
|
||||
|
||||
@override
|
||||
Member? get writeTarget => _encoding.writeTarget;
|
||||
|
||||
@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;
|
||||
if (!_fragment.modifiers.hasInitializer &&
|
||||
initializer != null &&
|
||||
initializer is! NullLiteral &&
|
||||
// Coverage-ignore(suite): Not run.
|
||||
!_fragment.modifiers.isConst &&
|
||||
// Coverage-ignore(suite): Not run.
|
||||
!_fragment.modifiers.isFinal) {
|
||||
internalProblem(
|
||||
messageInternalProblemAlreadyInitialized, nameOffset, fileUri);
|
||||
}
|
||||
_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 buildOutlineExpressions(
|
||||
ClassHierarchy classHierarchy,
|
||||
SourceLibraryBuilder libraryBuilder,
|
||||
DeclarationBuilder? declarationBuilder,
|
||||
List<Annotatable> annotatables,
|
||||
{required bool isClassInstanceMember,
|
||||
required bool createFileUriExpression}) {
|
||||
BodyBuilderContext bodyBuilderContext = createBodyBuilderContext();
|
||||
for (Annotatable annotatable in annotatables) {
|
||||
buildMetadataForOutlineExpressions(libraryBuilder,
|
||||
_fragment.enclosingScope, bodyBuilderContext, annotatable, metadata,
|
||||
fileUri: fileUri, createFileUriExpression: createFileUriExpression);
|
||||
}
|
||||
// For modular compilation we need to include initializers of all const
|
||||
// fields and all non-static final fields in classes with const constructors
|
||||
// into the outline.
|
||||
Token? token = _fragment.constInitializerToken;
|
||||
if ((_fragment.modifiers.isConst ||
|
||||
(isFinal &&
|
||||
isClassInstanceMember &&
|
||||
(declarationBuilder as SourceClassBuilder)
|
||||
.declaresConstConstructor)) &&
|
||||
token != null) {
|
||||
LookupScope scope = _fragment.enclosingScope;
|
||||
BodyBuilder bodyBuilder = libraryBuilder.loader
|
||||
.createBodyBuilderForOutlineExpression(
|
||||
libraryBuilder, createBodyBuilderContext(), scope, fileUri);
|
||||
bodyBuilder.constantContext = _fragment.modifiers.isConst
|
||||
? ConstantContext.inferred
|
||||
: ConstantContext.required;
|
||||
Expression initializer = bodyBuilder.typeInferrer
|
||||
.inferFieldInitializer(
|
||||
bodyBuilder, fieldType, bodyBuilder.parseFieldInitializer(token))
|
||||
.expression;
|
||||
buildBody(classHierarchy.coreTypes, initializer);
|
||||
bodyBuilder.performBacklogComputations();
|
||||
if (computeSharedExpressionForTesting) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
_initializerExpression = parseFieldInitializer(libraryBuilder.loader,
|
||||
token, libraryBuilder.importUri, fileUri, scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
|
||||
NameScheme nameScheme, BuildNodesCallback f, FieldReference references,
|
||||
{required List<TypeParameter>? classTypeParameters}) {
|
||||
_encoding.buildOutlineNode(libraryBuilder, nameScheme, references,
|
||||
isAbstractOrExternal:
|
||||
_fragment.modifiers.isAbstract || _fragment.modifiers.isExternal,
|
||||
classTypeParameters: classTypeParameters);
|
||||
if (type is! InferableTypeBuilder) {
|
||||
fieldType = type.build(libraryBuilder, TypeUse.fieldType);
|
||||
}
|
||||
_encoding.registerMembers(f);
|
||||
}
|
||||
|
||||
@override
|
||||
void checkTypes(SourceLibraryBuilder libraryBuilder,
|
||||
TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder) {
|
||||
libraryBuilder.checkTypesInField(typeEnvironment,
|
||||
isInstanceMember: builder.isDeclarationInstanceMember,
|
||||
isLate: isLate,
|
||||
isExternal: _fragment.modifiers.isExternal,
|
||||
hasInitializer: hasInitializer,
|
||||
fieldType: fieldType,
|
||||
name: _fragment.name,
|
||||
nameLength: _fragment.name.length,
|
||||
nameOffset: nameOffset,
|
||||
fileUri: fileUri);
|
||||
}
|
||||
|
||||
@override
|
||||
void checkVariance(
|
||||
SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
|
||||
sourceClassBuilder.checkVarianceInField(typeEnvironment,
|
||||
fieldType: fieldType,
|
||||
isInstanceMember: !isStatic,
|
||||
hasSetter: hasSetter,
|
||||
isCovariantByDeclaration: _fragment.modifiers.isCovariant,
|
||||
fileUri: fileUri,
|
||||
fileOffset: nameOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
int computeDefaultTypes(ComputeDefaultTypeContext context) {
|
||||
if (type is! OmittedTypeBuilder) {
|
||||
context.reportInboundReferenceIssuesForType(type);
|
||||
context.recursivelyReportGenericFunctionTypesAsBoundsForType(type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@override
|
||||
BodyBuilderContext createBodyBuilderContext() {
|
||||
return new _FieldFragmentBodyBuilderContext(
|
||||
this, _fragment, builder.libraryBuilder, builder.declarationBuilder,
|
||||
isDeclarationInstanceMember: builder.isDeclarationInstanceMember);
|
||||
}
|
||||
|
||||
void createEncoding(SourcePropertyBuilder builder) {
|
||||
SourceLibraryBuilder libraryBuilder = builder.libraryBuilder;
|
||||
|
||||
@@ -227,6 +377,42 @@ class FieldFragmentDeclaration
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
Iterable<Reference> getExportedMemberReferences(FieldReference references) {
|
||||
return [
|
||||
references.getterReference!,
|
||||
if (hasSetter) references.setterReference!
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
void registerSuperCall() {
|
||||
_encoding.registerSuperCall();
|
||||
}
|
||||
|
||||
DartType _computeInferredType(
|
||||
ClassHierarchyBase classHierarchy, Token? token) {
|
||||
DartType? inferredType;
|
||||
@@ -268,302 +454,135 @@ class FieldFragmentDeclaration
|
||||
return inferredType;
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isEnumElement => false;
|
||||
|
||||
BodyBuilderContext createBodyBuilderContext() {
|
||||
return new _FieldFragmentBodyBuilderContext(
|
||||
this, _fragment, builder.libraryBuilder, builder.declarationBuilder,
|
||||
isDeclarationInstanceMember: builder.isDeclarationInstanceMember);
|
||||
}
|
||||
|
||||
/// Registers that a `super` call has occurred in the initializer of this
|
||||
/// field.
|
||||
void registerSuperCall() {
|
||||
_encoding.registerSuperCall();
|
||||
}
|
||||
|
||||
@override
|
||||
void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
|
||||
NameScheme nameScheme, BuildNodesCallback f, FieldReference references,
|
||||
{required List<TypeParameter>? classTypeParameters}) {
|
||||
_encoding.buildOutlineNode(libraryBuilder, nameScheme, references,
|
||||
isAbstractOrExternal:
|
||||
_fragment.modifiers.isAbstract || _fragment.modifiers.isExternal,
|
||||
classTypeParameters: classTypeParameters);
|
||||
if (type is! InferableTypeBuilder) {
|
||||
fieldType = type.build(libraryBuilder, TypeUse.fieldType);
|
||||
}
|
||||
_encoding.registerMembers(f);
|
||||
}
|
||||
|
||||
@override
|
||||
Iterable<Reference> getExportedMemberReferences(FieldReference references) {
|
||||
return [
|
||||
references.getterReference!,
|
||||
if (hasSetter) references.setterReference!
|
||||
];
|
||||
}
|
||||
|
||||
shared.Expression? _initializerExpression;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
shared.Expression? get initializerExpression => _initializerExpression;
|
||||
|
||||
@override
|
||||
void buildOutlineExpressions(
|
||||
ClassHierarchy classHierarchy,
|
||||
SourceLibraryBuilder libraryBuilder,
|
||||
DeclarationBuilder? declarationBuilder,
|
||||
List<Annotatable> annotatables,
|
||||
{required bool isClassInstanceMember,
|
||||
required bool createFileUriExpression}) {
|
||||
BodyBuilderContext bodyBuilderContext = createBodyBuilderContext();
|
||||
for (Annotatable annotatable in annotatables) {
|
||||
buildMetadataForOutlineExpressions(libraryBuilder,
|
||||
_fragment.enclosingScope, bodyBuilderContext, annotatable, metadata,
|
||||
fileUri: fileUri, createFileUriExpression: createFileUriExpression);
|
||||
}
|
||||
// For modular compilation we need to include initializers of all const
|
||||
// fields and all non-static final fields in classes with const constructors
|
||||
// into the outline.
|
||||
Token? token = _fragment.constInitializerToken;
|
||||
if ((_fragment.modifiers.isConst ||
|
||||
(isFinal &&
|
||||
isClassInstanceMember &&
|
||||
(declarationBuilder as SourceClassBuilder)
|
||||
.declaresConstConstructor)) &&
|
||||
token != null) {
|
||||
LookupScope scope = _fragment.enclosingScope;
|
||||
BodyBuilder bodyBuilder = libraryBuilder.loader
|
||||
.createBodyBuilderForOutlineExpression(
|
||||
libraryBuilder, createBodyBuilderContext(), scope, fileUri);
|
||||
bodyBuilder.constantContext = _fragment.modifiers.isConst
|
||||
? ConstantContext.inferred
|
||||
: ConstantContext.required;
|
||||
Expression initializer = bodyBuilder.typeInferrer
|
||||
.inferFieldInitializer(
|
||||
bodyBuilder, fieldType, bodyBuilder.parseFieldInitializer(token))
|
||||
.expression;
|
||||
buildBody(classHierarchy.coreTypes, initializer);
|
||||
bodyBuilder.performBacklogComputations();
|
||||
if (computeSharedExpressionForTesting) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
_initializerExpression = parseFieldInitializer(libraryBuilder.loader,
|
||||
token, libraryBuilder.importUri, fileUri, scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void checkTypes(SourceLibraryBuilder libraryBuilder,
|
||||
TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder) {
|
||||
libraryBuilder.checkTypesInField(typeEnvironment,
|
||||
isInstanceMember: builder.isDeclarationInstanceMember,
|
||||
isLate: isLate,
|
||||
isExternal: _fragment.modifiers.isExternal,
|
||||
hasInitializer: hasInitializer,
|
||||
fieldType: fieldType,
|
||||
name: _fragment.name,
|
||||
nameLength: _fragment.name.length,
|
||||
nameOffset: nameOffset,
|
||||
fileUri: fileUri);
|
||||
}
|
||||
|
||||
@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 checkVariance(
|
||||
SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
|
||||
sourceClassBuilder.checkVarianceInField(typeEnvironment,
|
||||
fieldType: fieldType,
|
||||
isInstanceMember: !isStatic,
|
||||
hasSetter: hasSetter,
|
||||
isCovariantByDeclaration: _fragment.modifiers.isCovariant,
|
||||
fileUri: fileUri,
|
||||
fileOffset: nameOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
int computeDefaultTypes(ComputeDefaultTypeContext context) {
|
||||
if (type is! OmittedTypeBuilder) {
|
||||
context.reportInboundReferenceIssuesForType(type);
|
||||
context.recursivelyReportGenericFunctionTypesAsBoundsForType(type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@override
|
||||
Member get readTarget => _encoding.readTarget;
|
||||
|
||||
@override
|
||||
Member? get writeTarget => _encoding.writeTarget;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// 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;
|
||||
|
||||
/// 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;
|
||||
if (!_fragment.modifiers.hasInitializer &&
|
||||
initializer != null &&
|
||||
initializer is! NullLiteral &&
|
||||
// Coverage-ignore(suite): Not run.
|
||||
!_fragment.modifiers.isConst &&
|
||||
// Coverage-ignore(suite): Not run.
|
||||
!_fragment.modifiers.isFinal) {
|
||||
internalProblem(
|
||||
messageInternalProblemAlreadyInitialized, nameOffset, fileUri);
|
||||
}
|
||||
_encoding.createBodies(coreTypes, initializer);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType get fieldType => _encoding.type;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
DartType get _fieldTypeInternal => _encoding.type;
|
||||
|
||||
@override
|
||||
void set _fieldTypeInternal(DartType value) {
|
||||
_encoding.type = value;
|
||||
}
|
||||
|
||||
@override
|
||||
void _setCovariantByClassInternal() {
|
||||
_encoding.setCovariantByClass();
|
||||
}
|
||||
|
||||
@override
|
||||
Initializer buildErroneousInitializer(Expression effect, Expression value,
|
||||
{required int fileOffset}) {
|
||||
return _encoding.buildErroneousInitializer(effect, value,
|
||||
fileOffset: fileOffset);
|
||||
}
|
||||
|
||||
@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
|
||||
bool get hasInitializer => _fragment.modifiers.hasInitializer;
|
||||
|
||||
@override
|
||||
bool get isExtensionTypeDeclaredInstanceField =>
|
||||
builder.isExtensionTypeInstanceMember &&
|
||||
!_fragment.isPrimaryConstructorField;
|
||||
|
||||
@override
|
||||
bool get isFinal => _fragment.modifiers.isFinal;
|
||||
|
||||
@override
|
||||
bool get isConst => _fragment.modifiers.isConst;
|
||||
|
||||
@override
|
||||
bool get isLate => _fragment.modifiers.isLate;
|
||||
|
||||
bool get isStatic =>
|
||||
_fragment.modifiers.isStatic || builder.declarationBuilder == null;
|
||||
|
||||
@override
|
||||
List<ClassMember> get localMembers => _encoding.localMembers;
|
||||
|
||||
@override
|
||||
List<ClassMember> get localSetters => _encoding.localSetters;
|
||||
|
||||
@override
|
||||
SourcePropertyBuilder get builder => _fragment.builder;
|
||||
|
||||
@override
|
||||
Uri get fileUri => _fragment.fileUri;
|
||||
|
||||
@override
|
||||
bool get hasSetter => _fragment.hasSetter;
|
||||
|
||||
@override
|
||||
List<MetadataBuilder>? get metadata => _fragment.metadata;
|
||||
|
||||
@override
|
||||
int get nameOffset => _fragment.nameOffset;
|
||||
|
||||
@override
|
||||
TypeBuilder get type => _fragment.type;
|
||||
|
||||
@override
|
||||
FieldQuality get fieldQuality => _fragment.modifiers.isAbstract
|
||||
? FieldQuality.Abstract
|
||||
: _fragment.modifiers.isExternal
|
||||
? FieldQuality.External
|
||||
: FieldQuality.Concrete;
|
||||
|
||||
@override
|
||||
GetterQuality get getterQuality => _fragment.modifiers.isAbstract
|
||||
? GetterQuality.ImplicitAbstract
|
||||
: _fragment.modifiers.isExternal
|
||||
? GetterQuality.ImplicitExternal
|
||||
: GetterQuality.Implicit;
|
||||
|
||||
@override
|
||||
SetterQuality get setterQuality => !hasSetter
|
||||
? SetterQuality.Absent
|
||||
: _fragment.modifiers.isAbstract
|
||||
? SetterQuality.ImplicitAbstract
|
||||
: _fragment.modifiers.isExternal
|
||||
? SetterQuality.ImplicitExternal
|
||||
: SetterQuality.Implicit;
|
||||
}
|
||||
|
||||
class FieldFragment implements Fragment {
|
||||
@override
|
||||
final String name;
|
||||
|
||||
final Uri fileUri;
|
||||
|
||||
final int nameOffset;
|
||||
|
||||
final int endOffset;
|
||||
|
||||
Token? _initializerToken;
|
||||
Token? _constInitializerToken;
|
||||
|
||||
final List<MetadataBuilder>? metadata;
|
||||
|
||||
final TypeBuilder type;
|
||||
|
||||
final bool isTopLevel;
|
||||
final Modifiers modifiers;
|
||||
// TODO(johnniwinther): Create separate fragment for primary constructor
|
||||
// fields.
|
||||
final bool isPrimaryConstructorField;
|
||||
|
||||
final LookupScope enclosingScope;
|
||||
|
||||
final DeclarationFragment? enclosingDeclaration;
|
||||
final LibraryFragment enclosingCompilationUnit;
|
||||
|
||||
SourcePropertyBuilder? _builder;
|
||||
FieldFragmentDeclaration? _declaration;
|
||||
|
||||
FieldFragment({
|
||||
required this.name,
|
||||
required this.fileUri,
|
||||
required this.nameOffset,
|
||||
required this.endOffset,
|
||||
required Token? initializerToken,
|
||||
required Token? constInitializerToken,
|
||||
required this.metadata,
|
||||
required this.type,
|
||||
required this.isTopLevel,
|
||||
required this.modifiers,
|
||||
required this.isPrimaryConstructorField,
|
||||
required this.enclosingScope,
|
||||
required this.enclosingDeclaration,
|
||||
required this.enclosingCompilationUnit,
|
||||
}) : _initializerToken = initializerToken,
|
||||
_constInitializerToken = constInitializerToken;
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
/// Returns the token for the initializer of this field, if any. This is the
|
||||
/// same as [initializerToken] but is used to signal that the initializer
|
||||
/// needs to be computed for outline expressions.
|
||||
///
|
||||
/// This can only be called once and will hand over the responsibility of
|
||||
/// the token to the caller.
|
||||
Token? get constInitializerToken {
|
||||
Token? result = _constInitializerToken;
|
||||
// Ensure that we don't hold onto the token.
|
||||
_constInitializerToken = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
FieldFragmentDeclaration get declaration {
|
||||
assert(
|
||||
_declaration != null, "Declaration has not been computed for $this.");
|
||||
return _declaration!;
|
||||
}
|
||||
|
||||
void set declaration(FieldFragmentDeclaration value) {
|
||||
assert(_declaration == null,
|
||||
"Declaration has already been computed for $this.");
|
||||
_declaration = value;
|
||||
}
|
||||
|
||||
bool get hasSetter {
|
||||
if (modifiers.isConst) {
|
||||
return false;
|
||||
} else if (modifiers.isFinal) {
|
||||
if (modifiers.isLate) {
|
||||
return !modifiers.hasInitializer;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the token for the initializer of this field, if any.
|
||||
///
|
||||
/// This can only be called once and will hand over the responsibility of
|
||||
/// the token to the caller.
|
||||
Token? get initializerToken {
|
||||
Token? result = _initializerToken;
|
||||
// Ensure that we don't hold onto the token.
|
||||
_initializerToken = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => '$runtimeType($name,$fileUri,$nameOffset)';
|
||||
}
|
||||
|
||||
abstract class FieldFragmentDeclaration {
|
||||
bool get isStatic;
|
||||
|
||||
void buildFieldInitializer(InferenceHelper helper, TypeInferrer typeInferrer,
|
||||
CoreTypes coreTypes, Expression? initializer);
|
||||
|
||||
BodyBuilderContext createBodyBuilderContext();
|
||||
|
||||
/// Registers that a `super` call has occurred in the initializer of this
|
||||
/// field.
|
||||
void registerSuperCall();
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ class GetterFragment implements Fragment, FunctionFragment {
|
||||
|
||||
SourcePropertyBuilder? _builder;
|
||||
|
||||
GetterDeclaration? _declaration;
|
||||
GetterFragmentDeclaration? _declaration;
|
||||
|
||||
GetterFragment({
|
||||
required this.name,
|
||||
@@ -96,12 +96,12 @@ class GetterFragment implements Fragment, FunctionFragment {
|
||||
_builder = value;
|
||||
}
|
||||
|
||||
GetterDeclaration get declaration {
|
||||
GetterFragmentDeclaration get declaration {
|
||||
assert(_declaration != null, "Builder has not been computed for $this.");
|
||||
return _declaration!;
|
||||
}
|
||||
|
||||
void set declaration(GetterDeclaration value) {
|
||||
void set declaration(GetterFragmentDeclaration value) {
|
||||
assert(_declaration == null,
|
||||
"Declaration has already been computed for $this.");
|
||||
_declaration = value;
|
||||
|
||||
@@ -18,7 +18,7 @@ import 'declaration.dart';
|
||||
|
||||
class GetterFragmentBodyBuilderContext extends BodyBuilderContext {
|
||||
final SourcePropertyBuilder _builder;
|
||||
final GetterDeclaration _declaration;
|
||||
final GetterFragmentDeclaration _declaration;
|
||||
|
||||
GetterFragmentBodyBuilderContext(
|
||||
this._builder,
|
||||
|
||||
@@ -28,37 +28,16 @@ import '../fragment.dart';
|
||||
import 'body_builder_context.dart';
|
||||
import 'encoding.dart';
|
||||
|
||||
/// Interface for a getter declaration aspect of a [SourcePropertyBuilder].
|
||||
abstract class GetterDeclaration {
|
||||
GetterQuality get getterQuality;
|
||||
|
||||
AsyncMarker get asyncModifier;
|
||||
|
||||
Uri get fileUri;
|
||||
|
||||
List<FormalParameterBuilder>? get formals;
|
||||
|
||||
FunctionNode get function;
|
||||
|
||||
bool get isAbstract;
|
||||
|
||||
bool get isExternal;
|
||||
GetterQuality get getterQuality;
|
||||
|
||||
List<MetadataBuilder>? get metadata;
|
||||
|
||||
String get name;
|
||||
|
||||
int get nameOffset;
|
||||
|
||||
Procedure get readTarget;
|
||||
|
||||
TypeBuilder get returnType;
|
||||
|
||||
List<TypeParameter>? get thisTypeParameters;
|
||||
|
||||
VariableDeclaration? get thisVariable;
|
||||
|
||||
void becomeNative(SourceLoader loader);
|
||||
|
||||
void buildOutlineExpressions(
|
||||
{required ClassHierarchy classHierarchy,
|
||||
required SourceLibraryBuilder libraryBuilder,
|
||||
@@ -83,17 +62,12 @@ abstract class GetterDeclaration {
|
||||
|
||||
int computeDefaultTypes(ComputeDefaultTypeContext context);
|
||||
|
||||
BodyBuilderContext createBodyBuilderContext(
|
||||
SourcePropertyBuilder propertyBuilder);
|
||||
|
||||
void createEncoding(
|
||||
ProblemReporting problemReporting,
|
||||
SourcePropertyBuilder builder,
|
||||
PropertyEncodingStrategy encodingStrategy,
|
||||
List<NominalParameterBuilder> unboundNominalParameters);
|
||||
|
||||
LocalScope createFormalParameterScope(LookupScope typeParameterScope);
|
||||
|
||||
void ensureTypes(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
required DeclarationBuilder? declarationBuilder,
|
||||
@@ -101,11 +75,10 @@ abstract class GetterDeclaration {
|
||||
required Set<ClassMember>? getterOverrideDependencies});
|
||||
|
||||
Iterable<Reference> getExportedMemberReferences(GetterReference references);
|
||||
|
||||
VariableDeclaration getFormalParameter(int index);
|
||||
}
|
||||
|
||||
class GetterDeclarationImpl implements GetterDeclaration {
|
||||
class GetterDeclarationImpl
|
||||
implements GetterDeclaration, GetterFragmentDeclaration {
|
||||
final GetterFragment _fragment;
|
||||
late final GetterEncoding _encoding;
|
||||
|
||||
@@ -126,7 +99,11 @@ class GetterDeclarationImpl implements GetterDeclaration {
|
||||
FunctionNode get function => _encoding.function;
|
||||
|
||||
@override
|
||||
bool get isAbstract => _fragment.modifiers.isAbstract;
|
||||
GetterQuality get getterQuality => _fragment.modifiers.isAbstract
|
||||
? GetterQuality.Abstract
|
||||
: _fragment.modifiers.isExternal
|
||||
? GetterQuality.External
|
||||
: GetterQuality.Concrete;
|
||||
|
||||
@override
|
||||
bool get isExternal => _fragment.modifiers.isExternal;
|
||||
@@ -198,7 +175,8 @@ class GetterDeclarationImpl implements GetterDeclaration {
|
||||
void checkTypes(SourceLibraryBuilder libraryBuilder,
|
||||
TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder) {
|
||||
_encoding.checkTypes(libraryBuilder, typeEnvironment, setterBuilder,
|
||||
isAbstract: isAbstract, isExternal: isExternal);
|
||||
isAbstract: _fragment.modifiers.isAbstract,
|
||||
isExternal: _fragment.modifiers.isExternal);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -232,7 +210,7 @@ class GetterDeclarationImpl implements GetterDeclaration {
|
||||
_fragment.typeParameterNameSpace.addTypeParameters(
|
||||
problemReporting, _encoding.clonedAndDeclaredTypeParameters,
|
||||
ownerName: _fragment.name, allowNameConflict: true);
|
||||
returnType.registerInferredTypeListener(_encoding);
|
||||
_fragment.returnType.registerInferredTypeListener(_encoding);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -265,11 +243,34 @@ class GetterDeclarationImpl implements GetterDeclaration {
|
||||
VariableDeclaration getFormalParameter(int index) {
|
||||
return _encoding.getFormalParameter(index);
|
||||
}
|
||||
|
||||
@override
|
||||
GetterQuality get getterQuality => _fragment.modifiers.isAbstract
|
||||
? GetterQuality.Abstract
|
||||
: _fragment.modifiers.isExternal
|
||||
? GetterQuality.External
|
||||
: GetterQuality.Concrete;
|
||||
}
|
||||
|
||||
/// Interface for using a [GetterFragment] to create a [BodyBuilderContext].
|
||||
abstract class GetterFragmentDeclaration {
|
||||
AsyncMarker get asyncModifier;
|
||||
|
||||
List<FormalParameterBuilder>? get formals;
|
||||
|
||||
FunctionNode get function;
|
||||
|
||||
bool get isExternal;
|
||||
|
||||
String get name;
|
||||
|
||||
int get nameOffset;
|
||||
|
||||
TypeBuilder get returnType;
|
||||
|
||||
List<TypeParameter>? get thisTypeParameters;
|
||||
|
||||
VariableDeclaration? get thisVariable;
|
||||
|
||||
void becomeNative(SourceLoader loader);
|
||||
|
||||
BodyBuilderContext createBodyBuilderContext(
|
||||
SourcePropertyBuilder propertyBuilder);
|
||||
|
||||
LocalScope createFormalParameterScope(LookupScope typeParameterScope);
|
||||
|
||||
VariableDeclaration getFormalParameter(int index);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ class MethodFragment implements Fragment, FunctionFragment {
|
||||
|
||||
SourceMethodBuilder? _builder;
|
||||
|
||||
MethodDeclaration? _declaration;
|
||||
MethodFragmentDeclaration? _declaration;
|
||||
|
||||
MethodFragment({
|
||||
required this.name,
|
||||
@@ -93,13 +93,13 @@ class MethodFragment implements Fragment, FunctionFragment {
|
||||
_builder = value;
|
||||
}
|
||||
|
||||
MethodDeclaration get declaration {
|
||||
MethodFragmentDeclaration get declaration {
|
||||
assert(
|
||||
_declaration != null, "Declaration has not been computed for $this.");
|
||||
return _declaration!;
|
||||
}
|
||||
|
||||
void set declaration(MethodDeclaration value) {
|
||||
void set declaration(MethodFragmentDeclaration value) {
|
||||
assert(_declaration == null,
|
||||
"Declaration has already been computed for $this.");
|
||||
_declaration = value;
|
||||
|
||||
@@ -18,7 +18,7 @@ import 'declaration.dart';
|
||||
|
||||
class MethodFragmentBodyBuilderContext extends BodyBuilderContext {
|
||||
final MethodFragment _fragment;
|
||||
final MethodDeclaration _declaration;
|
||||
final MethodFragmentDeclaration _declaration;
|
||||
|
||||
MethodFragmentBodyBuilderContext(
|
||||
this._fragment,
|
||||
|
||||
@@ -27,13 +27,13 @@ import '../fragment.dart';
|
||||
import 'body_builder_context.dart';
|
||||
import 'encoding.dart';
|
||||
|
||||
/// Interface for the method declaration aspect of a [SourceMethodBuilder].
|
||||
///
|
||||
/// If a method is augmented, it will have multiple
|
||||
/// [MethodDeclaration]s on a single [SourceMethodBuilder].
|
||||
abstract class MethodDeclaration {
|
||||
Uri get fileUri;
|
||||
|
||||
List<FormalParameterBuilder>? get formals;
|
||||
|
||||
FunctionNode get function;
|
||||
|
||||
Procedure get invokeTarget;
|
||||
|
||||
bool get isOperator;
|
||||
@@ -42,14 +42,6 @@ abstract class MethodDeclaration {
|
||||
|
||||
Procedure? get readTarget;
|
||||
|
||||
TypeBuilder get returnType;
|
||||
|
||||
List<TypeParameter>? get thisTypeParameters;
|
||||
|
||||
VariableDeclaration? get thisVariable;
|
||||
|
||||
void becomeNative(SourceLoader loader);
|
||||
|
||||
void buildOutlineExpressions(
|
||||
ClassHierarchy classHierarchy,
|
||||
SourceLibraryBuilder libraryBuilder,
|
||||
@@ -73,27 +65,20 @@ abstract class MethodDeclaration {
|
||||
|
||||
int computeDefaultTypes(ComputeDefaultTypeContext context);
|
||||
|
||||
BodyBuilderContext createBodyBuilderContext(SourceMethodBuilder builder);
|
||||
|
||||
void createEncoding(
|
||||
ProblemReporting problemReporting,
|
||||
SourceMethodBuilder builder,
|
||||
MethodEncodingStrategy encodingStrategy,
|
||||
List<NominalParameterBuilder> unboundNominalParameters);
|
||||
|
||||
LocalScope createFormalParameterScope(LookupScope typeParameterScope);
|
||||
|
||||
void ensureTypes(
|
||||
ClassMembersBuilder membersBuilder,
|
||||
SourceClassBuilder enclosingClassBuilder,
|
||||
Set<ClassMember>? overrideDependencies);
|
||||
|
||||
VariableDeclaration getFormalParameter(int index);
|
||||
|
||||
VariableDeclaration? getTearOffParameter(int index);
|
||||
}
|
||||
|
||||
class MethodDeclarationImpl implements MethodDeclaration {
|
||||
class MethodDeclarationImpl
|
||||
implements MethodDeclaration, MethodFragmentDeclaration {
|
||||
final MethodFragment _fragment;
|
||||
late final MethodEncoding _encoding;
|
||||
|
||||
@@ -241,3 +226,26 @@ class MethodDeclarationImpl implements MethodDeclaration {
|
||||
return _encoding.getTearOffParameter(index);
|
||||
}
|
||||
}
|
||||
|
||||
/// Interface for using a [MethodFragment] to create a [BodyBuilderContext].
|
||||
abstract class MethodFragmentDeclaration {
|
||||
List<FormalParameterBuilder>? get formals;
|
||||
|
||||
FunctionNode get function;
|
||||
|
||||
TypeBuilder get returnType;
|
||||
|
||||
List<TypeParameter>? get thisTypeParameters;
|
||||
|
||||
VariableDeclaration? get thisVariable;
|
||||
|
||||
void becomeNative(SourceLoader loader);
|
||||
|
||||
BodyBuilderContext createBodyBuilderContext(SourceMethodBuilder builder);
|
||||
|
||||
LocalScope createFormalParameterScope(LookupScope typeParameterScope);
|
||||
|
||||
VariableDeclaration getFormalParameter(int index);
|
||||
|
||||
VariableDeclaration? getTearOffParameter(int index);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class PrimaryConstructorFragment implements Fragment, FunctionFragment {
|
||||
|
||||
SourceConstructorBuilderImpl? _builder;
|
||||
|
||||
ConstructorDeclaration? _declaration;
|
||||
ConstructorFragmentDeclaration? _declaration;
|
||||
|
||||
PrimaryConstructorFragment({
|
||||
required this.constructorName,
|
||||
@@ -63,13 +63,13 @@ class PrimaryConstructorFragment implements Fragment, FunctionFragment {
|
||||
_builder = value;
|
||||
}
|
||||
|
||||
ConstructorDeclaration get declaration {
|
||||
ConstructorFragmentDeclaration get declaration {
|
||||
assert(
|
||||
_declaration != null, "Declaration has not been computed for $this.");
|
||||
return _declaration!;
|
||||
}
|
||||
|
||||
void set declaration(ConstructorDeclaration value) {
|
||||
void set declaration(ConstructorFragmentDeclaration value) {
|
||||
assert(_declaration == null,
|
||||
"Declaration has already been computed for $this.");
|
||||
_declaration = value;
|
||||
|
||||
@@ -58,7 +58,7 @@ class SetterFragment implements Fragment, FunctionFragment {
|
||||
final LibraryFragment enclosingCompilationUnit;
|
||||
|
||||
SourcePropertyBuilder? _builder;
|
||||
SetterDeclaration? _declaration;
|
||||
SetterFragmentDeclaration? _declaration;
|
||||
|
||||
SetterFragment({
|
||||
required this.name,
|
||||
@@ -93,13 +93,13 @@ class SetterFragment implements Fragment, FunctionFragment {
|
||||
_builder = value;
|
||||
}
|
||||
|
||||
SetterDeclaration get declaration {
|
||||
SetterFragmentDeclaration get declaration {
|
||||
assert(
|
||||
_declaration != null, "Declaration has not been computed for $this.");
|
||||
return _declaration!;
|
||||
}
|
||||
|
||||
void set declaration(SetterDeclaration value) {
|
||||
void set declaration(SetterFragmentDeclaration value) {
|
||||
assert(_declaration == null,
|
||||
"Declaration has already been computed for $this.");
|
||||
_declaration = value;
|
||||
|
||||
@@ -18,7 +18,7 @@ import 'declaration.dart';
|
||||
|
||||
class SetterBodyBuilderContext extends BodyBuilderContext {
|
||||
final SourcePropertyBuilder _builder;
|
||||
final SetterDeclaration _declaration;
|
||||
final SetterFragmentDeclaration _declaration;
|
||||
|
||||
SetterBodyBuilderContext(
|
||||
this._builder,
|
||||
|
||||
@@ -28,37 +28,16 @@ import '../fragment.dart';
|
||||
import 'body_builder_context.dart';
|
||||
import 'encoding.dart';
|
||||
|
||||
/// Interface for a setter declaration aspect of a [SourcePropertyBuilder].
|
||||
abstract class SetterDeclaration {
|
||||
SetterQuality get setterQuality;
|
||||
|
||||
AsyncMarker get asyncModifier;
|
||||
|
||||
Uri get fileUri;
|
||||
|
||||
List<FormalParameterBuilder>? get formals;
|
||||
|
||||
FunctionNode get function;
|
||||
|
||||
bool get isAbstract;
|
||||
|
||||
bool get isExternal;
|
||||
|
||||
List<MetadataBuilder>? get metadata;
|
||||
|
||||
String get name;
|
||||
|
||||
int get nameOffset;
|
||||
|
||||
TypeBuilder get returnType;
|
||||
|
||||
List<TypeParameter>? get thisTypeParameters;
|
||||
|
||||
VariableDeclaration? get thisVariable;
|
||||
SetterQuality get setterQuality;
|
||||
|
||||
Procedure get writeTarget;
|
||||
|
||||
void becomeNative(SourceLoader loader);
|
||||
|
||||
void buildOutlineExpressions(
|
||||
{required ClassHierarchy classHierarchy,
|
||||
required SourceLibraryBuilder libraryBuilder,
|
||||
@@ -83,17 +62,12 @@ abstract class SetterDeclaration {
|
||||
|
||||
int computeDefaultTypes(ComputeDefaultTypeContext context);
|
||||
|
||||
BodyBuilderContext createBodyBuilderContext(
|
||||
SourcePropertyBuilder propertyBuilder);
|
||||
|
||||
void createEncoding(
|
||||
ProblemReporting problemReporting,
|
||||
SourcePropertyBuilder builder,
|
||||
PropertyEncodingStrategy encodingStrategy,
|
||||
List<NominalParameterBuilder> unboundNominalParameters);
|
||||
|
||||
LocalScope createFormalParameterScope(LookupScope typeParameterScope);
|
||||
|
||||
void ensureTypes(
|
||||
{required SourceLibraryBuilder libraryBuilder,
|
||||
required DeclarationBuilder? declarationBuilder,
|
||||
@@ -101,11 +75,10 @@ abstract class SetterDeclaration {
|
||||
required Set<ClassMember>? setterOverrideDependencies});
|
||||
|
||||
Iterable<Reference> getExportedMemberReferences(SetterReference references);
|
||||
|
||||
VariableDeclaration getFormalParameter(int index);
|
||||
}
|
||||
|
||||
class SetterDeclarationImpl implements SetterDeclaration {
|
||||
class SetterDeclarationImpl
|
||||
implements SetterDeclaration, SetterFragmentDeclaration {
|
||||
final SetterFragment _fragment;
|
||||
late final SetterEncoding _encoding;
|
||||
|
||||
@@ -145,6 +118,13 @@ class SetterDeclarationImpl implements SetterDeclaration {
|
||||
@override
|
||||
TypeBuilder get returnType => _fragment.returnType;
|
||||
|
||||
@override
|
||||
SetterQuality get setterQuality => _fragment.modifiers.isAbstract
|
||||
? SetterQuality.Abstract
|
||||
: _fragment.modifiers.isExternal
|
||||
? SetterQuality.External
|
||||
: SetterQuality.Concrete;
|
||||
|
||||
@override
|
||||
List<TypeParameter>? get thisTypeParameters => _encoding.thisTypeParameters;
|
||||
|
||||
@@ -266,11 +246,36 @@ class SetterDeclarationImpl implements SetterDeclaration {
|
||||
VariableDeclaration getFormalParameter(int index) {
|
||||
return _encoding.getFormalParameter(index);
|
||||
}
|
||||
|
||||
@override
|
||||
SetterQuality get setterQuality => _fragment.modifiers.isAbstract
|
||||
? SetterQuality.Abstract
|
||||
: _fragment.modifiers.isExternal
|
||||
? SetterQuality.External
|
||||
: SetterQuality.Concrete;
|
||||
}
|
||||
|
||||
/// Interface for using a [SetterFragment] to create a [BodyBuilderContext].
|
||||
abstract class SetterFragmentDeclaration {
|
||||
AsyncMarker get asyncModifier;
|
||||
|
||||
List<FormalParameterBuilder>? get formals;
|
||||
|
||||
FunctionNode get function;
|
||||
|
||||
bool get isAbstract;
|
||||
|
||||
bool get isExternal;
|
||||
|
||||
String get name;
|
||||
|
||||
int get nameOffset;
|
||||
|
||||
TypeBuilder get returnType;
|
||||
|
||||
List<TypeParameter>? get thisTypeParameters;
|
||||
|
||||
VariableDeclaration? get thisVariable;
|
||||
|
||||
void becomeNative(SourceLoader loader);
|
||||
|
||||
BodyBuilderContext createBodyBuilderContext(
|
||||
SourcePropertyBuilder propertyBuilder);
|
||||
|
||||
LocalScope createFormalParameterScope(LookupScope typeParameterScope);
|
||||
|
||||
VariableDeclaration getFormalParameter(int index);
|
||||
}
|
||||
|
||||
@@ -169,9 +169,6 @@ abstract class FieldDeclaration {
|
||||
/// `null` if this field declaration has no setter.
|
||||
Member? get writeTarget;
|
||||
|
||||
/// The [TypeBuilder] for the declared type of this field declaration.
|
||||
TypeBuilder get type;
|
||||
|
||||
/// The [DartType] of this field declaration.
|
||||
abstract DartType fieldType;
|
||||
|
||||
@@ -222,6 +219,9 @@ mixin FieldDeclarationMixin
|
||||
|
||||
bool get isConst;
|
||||
|
||||
/// The [TypeBuilder] for the declared type of this field declaration.
|
||||
TypeBuilder get type;
|
||||
|
||||
void _setCovariantByClassInternal();
|
||||
|
||||
abstract DartType _fieldTypeInternal;
|
||||
|
||||
@@ -2113,7 +2113,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult {
|
||||
@override
|
||||
int finishNativeMethods() {
|
||||
for (FactoryFragment fragment in _nativeFactoryFragments) {
|
||||
fragment.builder.becomeNative(loader);
|
||||
fragment.declaration.becomeNative(loader);
|
||||
}
|
||||
for (GetterFragment fragment in _nativeGetterFragments) {
|
||||
fragment.declaration.becomeNative(loader);
|
||||
@@ -2125,7 +2125,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult {
|
||||
fragment.declaration.becomeNative(loader);
|
||||
}
|
||||
for (ConstructorFragment fragment in _nativeConstructorFragments) {
|
||||
fragment.builder.becomeNative(loader);
|
||||
fragment.declaration.becomeNative(loader);
|
||||
}
|
||||
return _nativeFactoryFragments.length;
|
||||
}
|
||||
|
||||
@@ -39,26 +39,117 @@ import 'constructor_declaration.dart';
|
||||
import 'name_scheme.dart';
|
||||
import 'source_class_builder.dart';
|
||||
import 'source_library_builder.dart' show SourceLibraryBuilder;
|
||||
import 'source_loader.dart' show SourceLoader;
|
||||
import 'source_member_builder.dart';
|
||||
import 'source_property_builder.dart';
|
||||
|
||||
class ExtensionTypeInitializerToStatementConverter
|
||||
implements InitializerVisitor<void> {
|
||||
VariableDeclaration thisVariable;
|
||||
final List<Statement> statements;
|
||||
|
||||
ExtensionTypeInitializerToStatementConverter(
|
||||
this.statements, this.thisVariable);
|
||||
|
||||
@override
|
||||
void visitAssertInitializer(AssertInitializer node) {
|
||||
statements.add(node.statement);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAuxiliaryInitializer(AuxiliaryInitializer node) {
|
||||
if (node is ExtensionTypeRedirectingInitializer) {
|
||||
statements.add(new ExpressionStatement(
|
||||
new VariableSet(
|
||||
thisVariable,
|
||||
new StaticInvocation(node.target, node.arguments)
|
||||
..fileOffset = node.fileOffset)
|
||||
..fileOffset = node.fileOffset)
|
||||
..fileOffset = node.fileOffset);
|
||||
return;
|
||||
} else if (node is ExtensionTypeRepresentationFieldInitializer) {
|
||||
thisVariable
|
||||
..initializer = (node.value..parent = thisVariable)
|
||||
..fileOffset = node.fileOffset;
|
||||
return;
|
||||
}
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
throw new UnsupportedError(
|
||||
"Unexpected initializer $node (${node.runtimeType})");
|
||||
}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void visitFieldInitializer(FieldInitializer node) {
|
||||
thisVariable
|
||||
..initializer = (node.value..parent = thisVariable)
|
||||
..fileOffset = node.fileOffset;
|
||||
}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void visitInvalidInitializer(InvalidInitializer node) {
|
||||
statements.add(new ExpressionStatement(
|
||||
new InvalidExpression(null)..fileOffset = node.fileOffset)
|
||||
..fileOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitLocalInitializer(LocalInitializer node) {
|
||||
statements.add(node.variable);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitRedirectingInitializer(RedirectingInitializer node) {
|
||||
throw new UnsupportedError(
|
||||
"Unexpected initializer $node (${node.runtimeType})");
|
||||
}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void visitSuperInitializer(SuperInitializer node) {
|
||||
// TODO(johnniwinther): Report error for this case.
|
||||
}
|
||||
}
|
||||
|
||||
class InferableConstructor implements InferableMember {
|
||||
@override
|
||||
final Member member;
|
||||
|
||||
final SourceConstructorBuilder _builder;
|
||||
|
||||
InferableConstructor(this.member, this._builder);
|
||||
|
||||
@override
|
||||
void inferMemberTypes(ClassHierarchyBase classHierarchy) {
|
||||
_builder.inferFormalTypes(classHierarchy);
|
||||
}
|
||||
|
||||
@override
|
||||
void reportCyclicDependency() {
|
||||
// There is a cyclic dependency where inferring the types of the
|
||||
// initializing formals of a constructor required us to infer the
|
||||
// corresponding field type which required us to know the type of the
|
||||
// constructor.
|
||||
String name = _builder.declarationBuilder.name;
|
||||
if (_builder.name.isNotEmpty) {
|
||||
// TODO(ahe): Use `inferrer.helper.constructorNameForDiagnostics`
|
||||
// instead. However, `inferrer.helper` may be null.
|
||||
name += ".${_builder.name}";
|
||||
}
|
||||
_builder.libraryBuilder.addProblem(
|
||||
templateCantInferTypeDueToCircularity.withArguments(name),
|
||||
_builder.fileOffset,
|
||||
name.length,
|
||||
_builder.fileUri);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class SourceConstructorBuilder implements ConstructorBuilder {
|
||||
@override
|
||||
DeclarationBuilder get declarationBuilder;
|
||||
|
||||
void buildOutlineNodes(BuildNodesCallback f);
|
||||
|
||||
void buildOutlineExpressions(ClassHierarchy classHierarchy,
|
||||
List<DelayedDefaultValueCloner> delayedDefaultValueCloners);
|
||||
|
||||
int buildBodyNodes(BuildNodesCallback f);
|
||||
|
||||
/// Infers the types of any untyped initializing formals.
|
||||
void inferFormalTypes(ClassHierarchyBase hierarchy);
|
||||
|
||||
void addSuperParameterDefaultValueCloners(
|
||||
List<DelayedDefaultValueCloner> delayedDefaultValueCloners);
|
||||
@override
|
||||
Uri get fileUri;
|
||||
|
||||
/// Returns `true` if this constructor is an redirecting generative
|
||||
/// constructor.
|
||||
@@ -67,8 +158,18 @@ abstract class SourceConstructorBuilder implements ConstructorBuilder {
|
||||
/// initializer.
|
||||
bool get isRedirecting;
|
||||
|
||||
@override
|
||||
Uri get fileUri;
|
||||
void addSuperParameterDefaultValueCloners(
|
||||
List<DelayedDefaultValueCloner> delayedDefaultValueCloners);
|
||||
|
||||
int buildBodyNodes(BuildNodesCallback f);
|
||||
|
||||
void buildOutlineExpressions(ClassHierarchy classHierarchy,
|
||||
List<DelayedDefaultValueCloner> delayedDefaultValueCloners);
|
||||
|
||||
void buildOutlineNodes(BuildNodesCallback f);
|
||||
|
||||
/// Infers the types of any untyped initializing formals.
|
||||
void inferFormalTypes(ClassHierarchyBase hierarchy);
|
||||
}
|
||||
|
||||
class SourceConstructorBuilderImpl extends SourceMemberBuilderImpl
|
||||
@@ -121,6 +222,21 @@ class SourceConstructorBuilderImpl extends SourceMemberBuilderImpl
|
||||
late final Reference _readTargetReference;
|
||||
late final Member _readTarget;
|
||||
|
||||
late final Substitution _fieldTypeSubstitution =
|
||||
_introductory.computeFieldTypeSubstitution(declarationBuilder);
|
||||
|
||||
final String? nativeMethodName;
|
||||
|
||||
SuperInitializer? superInitializer;
|
||||
|
||||
RedirectingInitializer? redirectingInitializer;
|
||||
|
||||
bool _hasBuiltOutlines = false;
|
||||
|
||||
bool hasBuiltOutlineExpressions = false;
|
||||
|
||||
bool _hasFormalsInferred = false;
|
||||
|
||||
SourceConstructorBuilderImpl({
|
||||
required this.modifiers,
|
||||
required this.name,
|
||||
@@ -169,48 +285,28 @@ class SourceConstructorBuilderImpl extends SourceMemberBuilderImpl
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Builder get parent => declarationBuilder;
|
||||
|
||||
bool get hasParameters => _introductory.formals != null;
|
||||
// TODO(johnniwinther): Add annotations to tear-offs.
|
||||
Iterable<Annotatable> get annotatables => [invokeTarget];
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Iterable<MetadataBuilder>? get metadataForTesting => _introductory.metadata;
|
||||
Iterable<Reference> get exportedMemberReferences => [invokeTargetReference];
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isAugmentation => modifiers.isAugment;
|
||||
|
||||
bool get isExternal => modifiers.isExternal;
|
||||
String get fullNameForErrors {
|
||||
return "${declarationBuilder.name}"
|
||||
"${name.isEmpty ? '' : '.$name'}";
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isConst => modifiers.isConst;
|
||||
|
||||
@override
|
||||
bool get isStatic => modifiers.isStatic;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Name get memberName => _memberName.name;
|
||||
|
||||
@override
|
||||
bool get isRedirecting => _lastDeclaration.isRedirecting;
|
||||
FunctionNode get function => _lastDeclaration.function;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Builder get getable => this;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Builder? get setable => null;
|
||||
|
||||
@override
|
||||
Member get readTarget => _readTarget;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Reference get readTargetReference => _readTargetReference;
|
||||
bool get hasParameters => _introductory.hasParameters;
|
||||
|
||||
@override
|
||||
Member get invokeTarget => _invokeTarget;
|
||||
@@ -219,6 +315,98 @@ class SourceConstructorBuilderImpl extends SourceMemberBuilderImpl
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Reference get invokeTargetReference => _invokeTargetReference;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isAugmentation => modifiers.isAugment;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isClassInstanceMember => false;
|
||||
|
||||
@override
|
||||
bool get isConst => modifiers.isConst;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isDeclarationInstanceMember => false;
|
||||
|
||||
@override
|
||||
bool get isEffectivelyExternal {
|
||||
bool isExternal = this.isExternal;
|
||||
if (isExternal) {
|
||||
for (ConstructorDeclaration augmentation in _augmentations) {
|
||||
isExternal &= augmentation.isExternal;
|
||||
}
|
||||
}
|
||||
return isExternal;
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isEffectivelyRedirecting {
|
||||
bool isRedirecting = _introductory.isRedirecting;
|
||||
if (!isRedirecting) {
|
||||
for (ConstructorDeclaration augmentation in _augmentations) {
|
||||
isRedirecting |= augmentation.isRedirecting;
|
||||
}
|
||||
}
|
||||
return isRedirecting;
|
||||
}
|
||||
|
||||
bool get isExternal => modifiers.isExternal;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isFinal => false;
|
||||
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isNative => nativeMethodName != null;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isProperty => false;
|
||||
|
||||
@override
|
||||
bool get isRedirecting => _lastDeclaration.isRedirecting;
|
||||
|
||||
@override
|
||||
bool get isStatic => modifiers.isStatic;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isSynthesized => false;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<ClassMember> get localMembers =>
|
||||
throw new UnsupportedError('${runtimeType}.localMembers');
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<ClassMember> get localSetters =>
|
||||
throw new UnsupportedError('${runtimeType}.localSetters');
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Name get memberName => _memberName.name;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Iterable<MetadataBuilder>? get metadataForTesting => _introductory.metadata;
|
||||
|
||||
@override
|
||||
Builder get parent => declarationBuilder;
|
||||
|
||||
@override
|
||||
Member get readTarget => _readTarget;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Reference get readTargetReference => _readTargetReference;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Builder? get setable => null;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Member? get writeTarget => null;
|
||||
@@ -227,57 +415,8 @@ class SourceConstructorBuilderImpl extends SourceMemberBuilderImpl
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Reference? get writeTargetReference => null;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Iterable<Reference> get exportedMemberReferences => [invokeTargetReference];
|
||||
|
||||
// TODO(johnniwinther): Add annotations to tear-offs.
|
||||
Iterable<Annotatable> get annotatables => [invokeTarget];
|
||||
|
||||
@override
|
||||
FunctionNode get function => _lastDeclaration.function;
|
||||
|
||||
void becomeNative(SourceLoader loader) {
|
||||
_introductory.becomeNative();
|
||||
for (ConstructorDeclaration augmentation in _augmentations) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
augmentation.becomeNative();
|
||||
}
|
||||
for (Annotatable annotatable in annotatables) {
|
||||
loader.addNativeAnnotation(annotatable, nativeMethodName!);
|
||||
}
|
||||
}
|
||||
|
||||
late final Substitution _fieldTypeSubstitution =
|
||||
_introductory.computeFieldTypeSubstitution(declarationBuilder);
|
||||
|
||||
@override
|
||||
DartType substituteFieldType(DartType fieldType) {
|
||||
return _fieldTypeSubstitution.substituteType(fieldType);
|
||||
}
|
||||
|
||||
final String? nativeMethodName;
|
||||
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isNative => nativeMethodName != null;
|
||||
|
||||
List<Initializer> get _initializers => _lastDeclaration.initializers;
|
||||
|
||||
SuperInitializer? superInitializer;
|
||||
|
||||
RedirectingInitializer? redirectingInitializer;
|
||||
|
||||
void _injectInvalidInitializer(Message message, int charOffset, int length,
|
||||
ExpressionGeneratorHelper helper, TreeNode parent) {
|
||||
Initializer lastInitializer = _initializers.removeLast();
|
||||
assert(lastInitializer == superInitializer ||
|
||||
lastInitializer == redirectingInitializer);
|
||||
Initializer error = helper.buildInvalidInitializer(
|
||||
helper.buildProblem(message, charOffset, length));
|
||||
_initializers.add(error..parent = parent);
|
||||
_initializers.add(lastInitializer);
|
||||
}
|
||||
|
||||
@override
|
||||
void addInitializer(Initializer initializer, ExpressionGeneratorHelper helper,
|
||||
{required InitializerInferenceResult? inferenceResult,
|
||||
@@ -394,66 +533,13 @@ class SourceConstructorBuilderImpl extends SourceMemberBuilderImpl
|
||||
}
|
||||
|
||||
@override
|
||||
int computeDefaultTypes(ComputeDefaultTypeContext context,
|
||||
{required bool inErrorRecovery}) {
|
||||
int count = _introductory.computeDefaultTypes(context,
|
||||
inErrorRecovery: inErrorRecovery);
|
||||
void addSuperParameterDefaultValueCloners(
|
||||
List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
|
||||
_introductory.addSuperParameterDefaultValueCloners(
|
||||
libraryBuilder, declarationBuilder, delayedDefaultValueCloners);
|
||||
for (ConstructorDeclaration augmentation in _augmentations) {
|
||||
count += augmentation.computeDefaultTypes(context,
|
||||
inErrorRecovery: inErrorRecovery);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void checkVariance(
|
||||
SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {}
|
||||
|
||||
@override
|
||||
void checkTypes(SourceLibraryBuilder libraryBuilder, NameSpace nameSpace,
|
||||
TypeEnvironment typeEnvironment) {
|
||||
_introductory.checkTypes(libraryBuilder, nameSpace, typeEnvironment);
|
||||
for (ConstructorDeclaration augmentation in _augmentations) {
|
||||
augmentation.checkTypes(libraryBuilder, nameSpace, typeEnvironment);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<ClassMember> get localMembers =>
|
||||
throw new UnsupportedError('${runtimeType}.localMembers');
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<ClassMember> get localSetters =>
|
||||
throw new UnsupportedError('${runtimeType}.localSetters');
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isProperty => false;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isFinal => false;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isSynthesized => false;
|
||||
|
||||
@override
|
||||
void buildOutlineNodes(BuildNodesCallback f) {
|
||||
_lastDeclaration.buildOutlineNodes(f,
|
||||
constructorBuilder: this,
|
||||
libraryBuilder: libraryBuilder,
|
||||
declarationConstructor: invokeTarget,
|
||||
delayedDefaultValueCloners: _delayedDefaultValueCloners);
|
||||
for (ConstructorDeclaration declaration in _augmentedDeclarations) {
|
||||
declaration.buildOutlineNodes(noAddBuildNodesCallback,
|
||||
constructorBuilder: this,
|
||||
libraryBuilder: libraryBuilder,
|
||||
declarationConstructor: invokeTarget,
|
||||
delayedDefaultValueCloners: _delayedDefaultValueCloners);
|
||||
augmentation.addSuperParameterDefaultValueCloners(
|
||||
libraryBuilder, declarationBuilder, delayedDefaultValueCloners);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,36 +552,6 @@ class SourceConstructorBuilderImpl extends SourceMemberBuilderImpl
|
||||
return _augmentations.length;
|
||||
}
|
||||
|
||||
@override
|
||||
void registerInitializedField(SourcePropertyBuilder fieldBuilder) {
|
||||
(_initializedFields ??= {}).add(fieldBuilder);
|
||||
}
|
||||
|
||||
@override
|
||||
Set<SourcePropertyBuilder>? takeInitializedFields() {
|
||||
Set<SourcePropertyBuilder>? result = _initializedFields;
|
||||
_initializedFields = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
void prepareInitializers() {
|
||||
_introductory.prepareInitializers();
|
||||
for (ConstructorDeclaration augmentation in _augmentations) {
|
||||
augmentation.prepareInitializers();
|
||||
}
|
||||
redirectingInitializer = null;
|
||||
superInitializer = null;
|
||||
}
|
||||
|
||||
@override
|
||||
void prependInitializer(Initializer initializer) {
|
||||
_lastDeclaration.prependInitializer(initializer);
|
||||
}
|
||||
|
||||
bool _hasBuiltOutlines = false;
|
||||
bool hasBuiltOutlineExpressions = false;
|
||||
|
||||
@override
|
||||
void buildOutlineExpressions(ClassHierarchy classHierarchy,
|
||||
List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
|
||||
@@ -531,48 +587,46 @@ class SourceConstructorBuilderImpl extends SourceMemberBuilderImpl
|
||||
}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
String get fullNameForErrors {
|
||||
return "${declarationBuilder.name}"
|
||||
"${name.isEmpty ? '' : '.$name'}";
|
||||
}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isDeclarationInstanceMember => false;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isClassInstanceMember => false;
|
||||
|
||||
@override
|
||||
bool get isEffectivelyExternal {
|
||||
bool isExternal = this.isExternal;
|
||||
if (isExternal) {
|
||||
for (ConstructorDeclaration augmentation in _augmentations) {
|
||||
isExternal &= augmentation.isExternal;
|
||||
}
|
||||
void buildOutlineNodes(BuildNodesCallback f) {
|
||||
_lastDeclaration.buildOutlineNodes(f,
|
||||
constructorBuilder: this,
|
||||
libraryBuilder: libraryBuilder,
|
||||
declarationConstructor: invokeTarget,
|
||||
delayedDefaultValueCloners: _delayedDefaultValueCloners);
|
||||
for (ConstructorDeclaration declaration in _augmentedDeclarations) {
|
||||
declaration.buildOutlineNodes(noAddBuildNodesCallback,
|
||||
constructorBuilder: this,
|
||||
libraryBuilder: libraryBuilder,
|
||||
declarationConstructor: invokeTarget,
|
||||
delayedDefaultValueCloners: _delayedDefaultValueCloners);
|
||||
}
|
||||
return isExternal;
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isEffectivelyRedirecting {
|
||||
bool isRedirecting = _introductory.isRedirecting;
|
||||
if (!isRedirecting) {
|
||||
for (ConstructorDeclaration augmentation in _augmentations) {
|
||||
isRedirecting |= augmentation.isRedirecting;
|
||||
}
|
||||
void checkTypes(SourceLibraryBuilder libraryBuilder, NameSpace nameSpace,
|
||||
TypeEnvironment typeEnvironment) {
|
||||
_introductory.checkTypes(libraryBuilder, nameSpace, typeEnvironment);
|
||||
for (ConstructorDeclaration augmentation in _augmentations) {
|
||||
augmentation.checkTypes(libraryBuilder, nameSpace, typeEnvironment);
|
||||
}
|
||||
return isRedirecting;
|
||||
}
|
||||
|
||||
@override
|
||||
void inferTypes(ClassHierarchyBase hierarchy) {
|
||||
inferFormalTypes(hierarchy);
|
||||
}
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void checkVariance(
|
||||
SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {}
|
||||
|
||||
bool _hasFormalsInferred = false;
|
||||
@override
|
||||
int computeDefaultTypes(ComputeDefaultTypeContext context,
|
||||
{required bool inErrorRecovery}) {
|
||||
int count = _introductory.computeDefaultTypes(context,
|
||||
inErrorRecovery: inErrorRecovery);
|
||||
for (ConstructorDeclaration augmentation in _augmentations) {
|
||||
count += augmentation.computeDefaultTypes(context,
|
||||
inErrorRecovery: inErrorRecovery);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@override
|
||||
void inferFormalTypes(ClassHierarchyBase hierarchy) {
|
||||
@@ -587,14 +641,51 @@ class SourceConstructorBuilderImpl extends SourceMemberBuilderImpl
|
||||
}
|
||||
|
||||
@override
|
||||
void addSuperParameterDefaultValueCloners(
|
||||
List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
|
||||
_introductory.addSuperParameterDefaultValueCloners(
|
||||
libraryBuilder, declarationBuilder, delayedDefaultValueCloners);
|
||||
void inferTypes(ClassHierarchyBase hierarchy) {
|
||||
inferFormalTypes(hierarchy);
|
||||
}
|
||||
|
||||
@override
|
||||
void prepareInitializers() {
|
||||
_introductory.prepareInitializers();
|
||||
for (ConstructorDeclaration augmentation in _augmentations) {
|
||||
augmentation.addSuperParameterDefaultValueCloners(
|
||||
libraryBuilder, declarationBuilder, delayedDefaultValueCloners);
|
||||
augmentation.prepareInitializers();
|
||||
}
|
||||
redirectingInitializer = null;
|
||||
superInitializer = null;
|
||||
}
|
||||
|
||||
@override
|
||||
void prependInitializer(Initializer initializer) {
|
||||
_lastDeclaration.prependInitializer(initializer);
|
||||
}
|
||||
|
||||
@override
|
||||
void registerInitializedField(SourcePropertyBuilder fieldBuilder) {
|
||||
(_initializedFields ??= {}).add(fieldBuilder);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType substituteFieldType(DartType fieldType) {
|
||||
return _fieldTypeSubstitution.substituteType(fieldType);
|
||||
}
|
||||
|
||||
@override
|
||||
Set<SourcePropertyBuilder>? takeInitializedFields() {
|
||||
Set<SourcePropertyBuilder>? result = _initializedFields;
|
||||
_initializedFields = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
void _injectInvalidInitializer(Message message, int charOffset, int length,
|
||||
ExpressionGeneratorHelper helper, TreeNode parent) {
|
||||
Initializer lastInitializer = _initializers.removeLast();
|
||||
assert(lastInitializer == superInitializer ||
|
||||
lastInitializer == redirectingInitializer);
|
||||
Initializer error = helper.buildInvalidInitializer(
|
||||
helper.buildProblem(message, charOffset, length));
|
||||
_initializers.add(error..parent = parent);
|
||||
_initializers.add(lastInitializer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,9 +724,12 @@ class SyntheticSourceConstructorBuilder extends MemberBuilderImpl
|
||||
_constructor = constructor,
|
||||
_constructorTearOff = constructorTearOff;
|
||||
|
||||
@override
|
||||
DeclarationBuilder get declarationBuilder => classBuilder;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Iterable<MetadataBuilder>? get metadataForTesting => null;
|
||||
Iterable<Reference> get exportedMemberReferences => [_constructor.reference];
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
@@ -646,72 +740,12 @@ class SyntheticSourceConstructorBuilder extends MemberBuilderImpl
|
||||
Uri get fileUri => _constructor.fileUri;
|
||||
|
||||
@override
|
||||
Builder get parent => declarationBuilder;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Iterable<Reference> get exportedMemberReferences => [_constructor.reference];
|
||||
|
||||
@override
|
||||
String get name => _constructor.name.text;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Name get memberName => _constructor.name;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isFinal => false;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isSynthesized => true;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isSynthetic => _constructor.isSynthetic;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isProperty => false;
|
||||
FunctionNode get function => _constructor.function;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Builder get getable => this;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Builder? get setable => null;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<ClassMember> get localMembers =>
|
||||
throw new UnsupportedError('${runtimeType}.localMembers');
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<ClassMember> get localSetters =>
|
||||
throw new UnsupportedError('${runtimeType}.localSetters');
|
||||
|
||||
@override
|
||||
FunctionNode get function => _constructor.function;
|
||||
|
||||
@override
|
||||
Member get readTarget => _constructorTearOff ?? _constructor;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Reference get readTargetReference =>
|
||||
(_constructorTearOff ?? _constructor).reference;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Member? get writeTarget => null;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Reference? get writeTargetReference => null;
|
||||
|
||||
@override
|
||||
Constructor get invokeTarget => _constructor;
|
||||
|
||||
@@ -723,7 +757,12 @@ class SyntheticSourceConstructorBuilder extends MemberBuilderImpl
|
||||
bool get isConst => _constructor.isConst;
|
||||
|
||||
@override
|
||||
DeclarationBuilder get declarationBuilder => classBuilder;
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isFinal => false;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isProperty => false;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
@@ -737,33 +776,56 @@ class SyntheticSourceConstructorBuilder extends MemberBuilderImpl
|
||||
}
|
||||
|
||||
@override
|
||||
void inferFormalTypes(ClassHierarchyBase hierarchy) {
|
||||
if (_immediatelyDefiningConstructor is SourceConstructorBuilder) {
|
||||
(_immediatelyDefiningConstructor as SourceConstructorBuilder)
|
||||
.inferFormalTypes(hierarchy);
|
||||
}
|
||||
if (_typeDependency != null) {
|
||||
_typeDependency!.copyInferred();
|
||||
_typeDependency = null;
|
||||
}
|
||||
}
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isSynthesized => true;
|
||||
|
||||
@override
|
||||
void buildOutlineExpressions(ClassHierarchy classHierarchy,
|
||||
List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
|
||||
if (_immediatelyDefiningConstructor != null) {
|
||||
// Ensure that default value expressions have been created for [_origin].
|
||||
// If [_origin] is from a source library, we need to build the default
|
||||
// values and initializers first.
|
||||
MemberBuilder origin = _immediatelyDefiningConstructor!;
|
||||
if (origin is SourceConstructorBuilder) {
|
||||
origin.buildOutlineExpressions(
|
||||
classHierarchy, delayedDefaultValueCloners);
|
||||
}
|
||||
addSuperParameterDefaultValueCloners(delayedDefaultValueCloners);
|
||||
_immediatelyDefiningConstructor = null;
|
||||
}
|
||||
}
|
||||
// Coverage-ignore(suite): Not run.
|
||||
bool get isSynthetic => _constructor.isSynthetic;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<ClassMember> get localMembers =>
|
||||
throw new UnsupportedError('${runtimeType}.localMembers');
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<ClassMember> get localSetters =>
|
||||
throw new UnsupportedError('${runtimeType}.localSetters');
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Name get memberName => _constructor.name;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Iterable<MetadataBuilder>? get metadataForTesting => null;
|
||||
|
||||
@override
|
||||
String get name => _constructor.name.text;
|
||||
|
||||
@override
|
||||
Builder get parent => declarationBuilder;
|
||||
|
||||
@override
|
||||
Member get readTarget => _constructorTearOff ?? _constructor;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Reference get readTargetReference =>
|
||||
(_constructorTearOff ?? _constructor).reference;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Builder? get setable => null;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Member? get writeTarget => null;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Reference? get writeTargetReference => null;
|
||||
|
||||
@override
|
||||
void addSuperParameterDefaultValueCloners(
|
||||
@@ -785,6 +847,32 @@ class SyntheticSourceConstructorBuilder extends MemberBuilderImpl
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void buildOutlineExpressions(ClassHierarchy classHierarchy,
|
||||
List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
|
||||
if (_immediatelyDefiningConstructor != null) {
|
||||
// Ensure that default value expressions have been created for [_origin].
|
||||
// If [_origin] is from a source library, we need to build the default
|
||||
// values and initializers first.
|
||||
MemberBuilder origin = _immediatelyDefiningConstructor!;
|
||||
if (origin is SourceConstructorBuilder) {
|
||||
origin.buildOutlineExpressions(
|
||||
classHierarchy, delayedDefaultValueCloners);
|
||||
}
|
||||
addSuperParameterDefaultValueCloners(delayedDefaultValueCloners);
|
||||
_immediatelyDefiningConstructor = null;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void checkTypes(SourceLibraryBuilder library, NameSpace nameSpace,
|
||||
TypeEnvironment typeEnvironment) {}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void checkVariance(
|
||||
SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
int computeDefaultTypes(ComputeDefaultTypeContext context,
|
||||
@@ -794,113 +882,14 @@ class SyntheticSourceConstructorBuilder extends MemberBuilderImpl
|
||||
}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void checkVariance(
|
||||
SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {}
|
||||
|
||||
@override
|
||||
void checkTypes(SourceLibraryBuilder library, NameSpace nameSpace,
|
||||
TypeEnvironment typeEnvironment) {}
|
||||
}
|
||||
|
||||
class ExtensionTypeInitializerToStatementConverter
|
||||
implements InitializerVisitor<void> {
|
||||
VariableDeclaration thisVariable;
|
||||
final List<Statement> statements;
|
||||
|
||||
ExtensionTypeInitializerToStatementConverter(
|
||||
this.statements, this.thisVariable);
|
||||
|
||||
@override
|
||||
void visitAuxiliaryInitializer(AuxiliaryInitializer node) {
|
||||
if (node is ExtensionTypeRedirectingInitializer) {
|
||||
statements.add(new ExpressionStatement(
|
||||
new VariableSet(
|
||||
thisVariable,
|
||||
new StaticInvocation(node.target, node.arguments)
|
||||
..fileOffset = node.fileOffset)
|
||||
..fileOffset = node.fileOffset)
|
||||
..fileOffset = node.fileOffset);
|
||||
return;
|
||||
} else if (node is ExtensionTypeRepresentationFieldInitializer) {
|
||||
thisVariable
|
||||
..initializer = (node.value..parent = thisVariable)
|
||||
..fileOffset = node.fileOffset;
|
||||
return;
|
||||
void inferFormalTypes(ClassHierarchyBase hierarchy) {
|
||||
if (_immediatelyDefiningConstructor is SourceConstructorBuilder) {
|
||||
(_immediatelyDefiningConstructor as SourceConstructorBuilder)
|
||||
.inferFormalTypes(hierarchy);
|
||||
}
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
throw new UnsupportedError(
|
||||
"Unexpected initializer $node (${node.runtimeType})");
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAssertInitializer(AssertInitializer node) {
|
||||
statements.add(node.statement);
|
||||
}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void visitFieldInitializer(FieldInitializer node) {
|
||||
thisVariable
|
||||
..initializer = (node.value..parent = thisVariable)
|
||||
..fileOffset = node.fileOffset;
|
||||
}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void visitInvalidInitializer(InvalidInitializer node) {
|
||||
statements.add(new ExpressionStatement(
|
||||
new InvalidExpression(null)..fileOffset = node.fileOffset)
|
||||
..fileOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitLocalInitializer(LocalInitializer node) {
|
||||
statements.add(node.variable);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitRedirectingInitializer(RedirectingInitializer node) {
|
||||
throw new UnsupportedError(
|
||||
"Unexpected initializer $node (${node.runtimeType})");
|
||||
}
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void visitSuperInitializer(SuperInitializer node) {
|
||||
// TODO(johnniwinther): Report error for this case.
|
||||
}
|
||||
}
|
||||
|
||||
class InferableConstructor implements InferableMember {
|
||||
@override
|
||||
final Member member;
|
||||
|
||||
final SourceConstructorBuilder _builder;
|
||||
|
||||
InferableConstructor(this.member, this._builder);
|
||||
|
||||
@override
|
||||
void inferMemberTypes(ClassHierarchyBase classHierarchy) {
|
||||
_builder.inferFormalTypes(classHierarchy);
|
||||
}
|
||||
|
||||
@override
|
||||
void reportCyclicDependency() {
|
||||
// There is a cyclic dependency where inferring the types of the
|
||||
// initializing formals of a constructor required us to infer the
|
||||
// corresponding field type which required us to know the type of the
|
||||
// constructor.
|
||||
String name = _builder.declarationBuilder.name;
|
||||
if (_builder.name.isNotEmpty) {
|
||||
// TODO(ahe): Use `inferrer.helper.constructorNameForDiagnostics`
|
||||
// instead. However, `inferrer.helper` may be null.
|
||||
name += ".${_builder.name}";
|
||||
if (_typeDependency != null) {
|
||||
_typeDependency!.copyInferred();
|
||||
_typeDependency = null;
|
||||
}
|
||||
_builder.libraryBuilder.addProblem(
|
||||
templateCantInferTypeDueToCircularity.withArguments(name),
|
||||
_builder.fileOffset,
|
||||
name.length,
|
||||
_builder.fileUri);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,9 @@
|
||||
|
||||
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/local_scope.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_loader.dart';
|
||||
import 'package:front_end/src/source/source_method_builder.dart';
|
||||
import 'package:kernel/ast.dart';
|
||||
import 'package:kernel/class_hierarchy.dart';
|
||||
@@ -477,12 +475,6 @@ class _EnumToStringMethodDeclaration implements MethodDeclaration {
|
||||
: _fileUri = fileUri,
|
||||
_fileOffset = fileOffset;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void becomeNative(SourceLoader loader) {
|
||||
// TODO: implement becomeNative
|
||||
}
|
||||
|
||||
@override
|
||||
void buildOutlineExpressions(
|
||||
ClassHierarchy classHierarchy,
|
||||
@@ -566,11 +558,6 @@ class _EnumToStringMethodDeclaration implements MethodDeclaration {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@override
|
||||
BodyBuilderContext createBodyBuilderContext(SourceMethodBuilder builder) {
|
||||
throw new UnsupportedError("$runtimeType.createBodyBuilderContext");
|
||||
}
|
||||
|
||||
@override
|
||||
void createEncoding(
|
||||
ProblemReporting problemReporting,
|
||||
@@ -580,11 +567,6 @@ class _EnumToStringMethodDeclaration implements MethodDeclaration {
|
||||
throw new UnsupportedError("$runtimeType.createEncoding");
|
||||
}
|
||||
|
||||
@override
|
||||
LocalScope createFormalParameterScope(LookupScope typeParameterScope) {
|
||||
throw new UnsupportedError("$runtimeType.createFormalParameterScope");
|
||||
}
|
||||
|
||||
@override
|
||||
void ensureTypes(
|
||||
ClassMembersBuilder membersBuilder,
|
||||
@@ -594,24 +576,6 @@ class _EnumToStringMethodDeclaration implements MethodDeclaration {
|
||||
@override
|
||||
Uri get fileUri => _fileUri;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<FormalParameterBuilder>? get formals => null;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
FunctionNode get function => _procedure.function;
|
||||
|
||||
@override
|
||||
VariableDeclaration getFormalParameter(int index) {
|
||||
throw new UnsupportedError("$runtimeType.getFormalParameter");
|
||||
}
|
||||
|
||||
@override
|
||||
VariableDeclaration? getTearOffParameter(int index) {
|
||||
throw new UnsupportedError("$runtimeType.getTearOffParameter");
|
||||
}
|
||||
|
||||
@override
|
||||
Procedure get invokeTarget => _procedure;
|
||||
|
||||
@@ -624,19 +588,6 @@ class _EnumToStringMethodDeclaration implements MethodDeclaration {
|
||||
|
||||
@override
|
||||
Procedure? get readTarget => null;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
TypeBuilder get returnType =>
|
||||
throw new UnsupportedError("$runtimeType.returnType");
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<TypeParameter>? get thisTypeParameters => null;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
VariableDeclaration? get thisVariable => null;
|
||||
}
|
||||
|
||||
class _EnumValuesFieldDeclaration implements FieldDeclaration {
|
||||
@@ -651,11 +602,10 @@ class _EnumValuesFieldDeclaration implements FieldDeclaration {
|
||||
|
||||
Field? _field;
|
||||
|
||||
@override
|
||||
final TypeBuilder type;
|
||||
final TypeBuilder _typeBuilder;
|
||||
|
||||
_EnumValuesFieldDeclaration(
|
||||
this._sourceEnumBuilder, this.fieldReference, this.type);
|
||||
this._sourceEnumBuilder, this.fieldReference, this._typeBuilder);
|
||||
|
||||
SourcePropertyBuilder get builder {
|
||||
assert(_builder != null, "Builder has not been computed for $this.");
|
||||
@@ -717,7 +667,7 @@ class _EnumValuesFieldDeclaration implements FieldDeclaration {
|
||||
void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
|
||||
NameScheme nameScheme, BuildNodesCallback f, FieldReference references,
|
||||
{required List<TypeParameter>? classTypeParameters}) {
|
||||
fieldType = type.build(libraryBuilder, TypeUse.fieldType);
|
||||
fieldType = _typeBuilder.build(libraryBuilder, TypeUse.fieldType);
|
||||
_field = new Field.immutable(dummyName,
|
||||
type: _type,
|
||||
isFinal: false,
|
||||
|
||||
@@ -22,7 +22,6 @@ import '../type_inference/type_inference_engine.dart';
|
||||
import 'name_scheme.dart';
|
||||
import 'source_class_builder.dart';
|
||||
import 'source_library_builder.dart' show SourceLibraryBuilder;
|
||||
import 'source_loader.dart' show SourceLoader;
|
||||
import 'source_member_builder.dart';
|
||||
|
||||
class SourceFactoryBuilder extends SourceMemberBuilderImpl
|
||||
@@ -121,14 +120,6 @@ class SourceFactoryBuilder extends SourceMemberBuilderImpl
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Builder? get setable => null;
|
||||
|
||||
void becomeNative(SourceLoader loader) {
|
||||
_introductory.becomeNative(loader: loader, annotatables: annotatables);
|
||||
for (FactoryDeclaration augmentation in _augmentations) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
augmentation.becomeNative(loader: loader, annotatables: annotatables);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Builder get parent => declarationBuilder;
|
||||
|
||||
@@ -181,16 +172,6 @@ class SourceFactoryBuilder extends SourceMemberBuilderImpl
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Iterable<Reference> get exportedMemberReferences => [_procedure.reference];
|
||||
|
||||
// Coverage-ignore(suite): Not run.
|
||||
/// If this is an extension instance method or constructor with lowering
|
||||
/// enabled, the tear off parameter corresponding to the [index]th parameter
|
||||
/// on the instance method or constructor is returned.
|
||||
///
|
||||
/// This is used to update the default value for the closure parameter when
|
||||
/// it has been computed for the original parameter.
|
||||
VariableDeclaration? getTearOffParameter(int index) =>
|
||||
_introductory.getTearOffParameter(index);
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<ClassMember> get localMembers =>
|
||||
|
||||
@@ -2463,7 +2463,7 @@ _AddBuilder _createFieldBuilder(FieldFragment fragment,
|
||||
fieldIsLateWithLowering: fieldIsLateWithLowering,
|
||||
isExternal: fragment.modifiers.isExternal);
|
||||
|
||||
FieldFragmentDeclaration declaration = new FieldFragmentDeclaration(fragment);
|
||||
FieldDeclarationImpl declaration = new FieldDeclarationImpl(fragment);
|
||||
SourcePropertyBuilder propertyBuilder = new SourcePropertyBuilder.forField(
|
||||
fileUri: fragment.fileUri,
|
||||
fileOffset: fragment.nameOffset,
|
||||
|
||||
@@ -45,7 +45,7 @@ const Map<String, ({int hitCount, int missCount})> _expect = {
|
||||
),
|
||||
// 100.0%.
|
||||
"package:front_end/src/api_prototype/lowering_predicates.dart": (
|
||||
hitCount: 13,
|
||||
hitCount: 15,
|
||||
missCount: 0,
|
||||
),
|
||||
// 100.0%.
|
||||
@@ -505,12 +505,12 @@ const Map<String, ({int hitCount, int missCount})> _expect = {
|
||||
),
|
||||
// 100.0%.
|
||||
"package:front_end/src/fragment/constructor/declaration.dart": (
|
||||
hitCount: 673,
|
||||
hitCount: 677,
|
||||
missCount: 0,
|
||||
),
|
||||
// 100.0%.
|
||||
"package:front_end/src/fragment/constructor/encoding.dart": (
|
||||
hitCount: 373,
|
||||
hitCount: 375,
|
||||
missCount: 0,
|
||||
),
|
||||
// 100.0%.
|
||||
@@ -545,7 +545,7 @@ const Map<String, ({int hitCount, int missCount})> _expect = {
|
||||
),
|
||||
// 100.0%.
|
||||
"package:front_end/src/fragment/factory/declaration.dart": (
|
||||
hitCount: 126,
|
||||
hitCount: 125,
|
||||
missCount: 0,
|
||||
),
|
||||
// 100.0%.
|
||||
@@ -585,7 +585,7 @@ const Map<String, ({int hitCount, int missCount})> _expect = {
|
||||
),
|
||||
// 100.0%.
|
||||
"package:front_end/src/fragment/getter/declaration.dart": (
|
||||
hitCount: 119,
|
||||
hitCount: 120,
|
||||
missCount: 0,
|
||||
),
|
||||
// 100.0%.
|
||||
@@ -670,7 +670,7 @@ const Map<String, ({int hitCount, int missCount})> _expect = {
|
||||
),
|
||||
// 100.0%.
|
||||
"package:front_end/src/kernel/body_builder.dart": (
|
||||
hitCount: 7219,
|
||||
hitCount: 7213,
|
||||
missCount: 0,
|
||||
),
|
||||
// 100.0%.
|
||||
@@ -820,7 +820,7 @@ const Map<String, ({int hitCount, int missCount})> _expect = {
|
||||
),
|
||||
// 100.0%.
|
||||
"package:front_end/src/kernel/kernel_target.dart": (
|
||||
hitCount: 997,
|
||||
hitCount: 999,
|
||||
missCount: 0,
|
||||
),
|
||||
// 100.0%.
|
||||
@@ -945,7 +945,7 @@ const Map<String, ({int hitCount, int missCount})> _expect = {
|
||||
),
|
||||
// 100.0%.
|
||||
"package:front_end/src/source/source_constructor_builder.dart": (
|
||||
hitCount: 421,
|
||||
hitCount: 415,
|
||||
missCount: 0,
|
||||
),
|
||||
// 100.0%.
|
||||
@@ -966,7 +966,7 @@ const Map<String, ({int hitCount, int missCount})> _expect = {
|
||||
),
|
||||
// 100.0%.
|
||||
"package:front_end/src/source/source_factory_builder.dart": (
|
||||
hitCount: 137,
|
||||
hitCount: 132,
|
||||
missCount: 0,
|
||||
),
|
||||
// 100.0%.
|
||||
|
||||
Reference in New Issue
Block a user