From b23efe44e8e19ee6196162bf9896d2e716fa04ea Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Mon, 28 Apr 2025 01:04:33 -0700 Subject: [PATCH] [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 Commit-Queue: Johnni Winther --- .../api_prototype/lowering_predicates.dart | 1 - .../lib/src/fragment/constructor.dart | 6 +- .../constructor/body_builder_context.dart | 2 +- .../src/fragment/constructor/declaration.dart | 127 ++- .../src/fragment/constructor/encoding.dart | 9 +- pkg/front_end/lib/src/fragment/factory.dart | 6 +- .../factory/body_builder_context.dart | 2 +- .../lib/src/fragment/factory/declaration.dart | 319 ++++--- pkg/front_end/lib/src/fragment/field.dart | 841 +++++++++--------- pkg/front_end/lib/src/fragment/getter.dart | 6 +- .../fragment/getter/body_builder_context.dart | 2 +- .../lib/src/fragment/getter/declaration.dart | 83 +- pkg/front_end/lib/src/fragment/method.dart | 6 +- .../fragment/method/body_builder_context.dart | 2 +- .../lib/src/fragment/method/declaration.dart | 50 +- .../lib/src/fragment/primary_constructor.dart | 6 +- pkg/front_end/lib/src/fragment/setter.dart | 6 +- .../fragment/setter/body_builder_context.dart | 2 +- .../lib/src/fragment/setter/declaration.dart | 81 +- pkg/front_end/lib/src/fragment/util.dart | 6 +- .../src/source/source_builder_factory.dart | 4 +- .../source/source_constructor_builder.dart | 819 +++++++++-------- .../lib/src/source/source_enum_builder.dart | 56 +- .../src/source/source_factory_builder.dart | 19 - .../source/type_parameter_scope_builder.dart | 2 +- .../test/coverage_suite_expected.dart | 18 +- 26 files changed, 1232 insertions(+), 1249 deletions(-) diff --git a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart index bd1351bed22..b0719711095 100644 --- a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart +++ b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart @@ -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 diff --git a/pkg/front_end/lib/src/fragment/constructor.dart b/pkg/front_end/lib/src/fragment/constructor.dart index faaabbdd319..9c4078e6d06 100644 --- a/pkg/front_end/lib/src/fragment/constructor.dart +++ b/pkg/front_end/lib/src/fragment/constructor.dart @@ -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; diff --git a/pkg/front_end/lib/src/fragment/constructor/body_builder_context.dart b/pkg/front_end/lib/src/fragment/constructor/body_builder_context.dart index 4c5839c3958..8abfb212fdd 100644 --- a/pkg/front_end/lib/src/fragment/constructor/body_builder_context.dart +++ b/pkg/front_end/lib/src/fragment/constructor/body_builder_context.dart @@ -22,7 +22,7 @@ import 'declaration.dart'; class ConstructorBodyBuilderContext extends BodyBuilderContext { final SourceConstructorBuilderImpl _builder; - final ConstructorDeclaration _declaration; + final ConstructorFragmentDeclaration _declaration; final Member _member; diff --git a/pkg/front_end/lib/src/fragment/constructor/declaration.dart b/pkg/front_end/lib/src/fragment/constructor/declaration.dart index c8821fb4476..65d77af4ecb 100644 --- a/pkg/front_end/lib/src/fragment/constructor/declaration.dart +++ b/pkg/front_end/lib/src/fragment/constructor/declaration.dart @@ -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? get metadata; - OmittedTypeBuilder get returnType; - - List? 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? get thisTypeParameters; - List 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 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? 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? _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? get formals; + + BodyBuilderContext createBodyBuilderContext( + SourceConstructorBuilderImpl constructorBuilder); + + FunctionNode get function; + + void registerFunctionBody(Statement value); + + void registerNoBodyConstructor(); + + VariableDeclaration? get thisVariable; + + List? 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; +} diff --git a/pkg/front_end/lib/src/fragment/constructor/encoding.dart b/pkg/front_end/lib/src/fragment/constructor/encoding.dart index ed5c76ea0f6..7e68fb5dbf6 100644 --- a/pkg/front_end/lib/src/fragment/constructor/encoding.dart +++ b/pkg/front_end/lib/src/fragment/constructor/encoding.dart @@ -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); } diff --git a/pkg/front_end/lib/src/fragment/factory.dart b/pkg/front_end/lib/src/fragment/factory.dart index aeb7f336d75..2ea4698d444 100644 --- a/pkg/front_end/lib/src/fragment/factory.dart +++ b/pkg/front_end/lib/src/fragment/factory.dart @@ -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; diff --git a/pkg/front_end/lib/src/fragment/factory/body_builder_context.dart b/pkg/front_end/lib/src/fragment/factory/body_builder_context.dart index bed4d9e97f0..f2efdd4f108 100644 --- a/pkg/front_end/lib/src/fragment/factory/body_builder_context.dart +++ b/pkg/front_end/lib/src/fragment/factory/body_builder_context.dart @@ -16,7 +16,7 @@ import 'declaration.dart'; class FactoryBodyBuilderContext extends BodyBuilderContext { final SourceFactoryBuilder _builder; - final FactoryDeclaration _declaration; + final FactoryFragmentDeclaration _declaration; final Member _member; diff --git a/pkg/front_end/lib/src/fragment/factory/declaration.dart b/pkg/front_end/lib/src/fragment/factory/declaration.dart index 511ece0c052..ddcc9b57d41 100644 --- a/pkg/front_end/lib/src/fragment/factory/declaration.dart +++ b/pkg/front_end/lib/src/fragment/factory/declaration.dart @@ -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? get metadata; + + Procedure get procedure; + + ConstructorReferenceBuilder? get redirectionTarget; + + Procedure? get tearOff; + + void buildOutlineExpressions( + {required SourceLibraryBuilder libraryBuilder, + required SourceFactoryBuilder factoryBuilder, + required ClassHierarchy classHierarchy, + required List 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 delayedDefaultValueCloners, - required bool createFileUriExpression}); - void inferRedirectionTarget( {required SourceLibraryBuilder libraryBuilder, required SourceFactoryBuilder factoryBuilder, required ClassHierarchy classHierarchy, required List 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? redirectionTypeArguments; - - bool get isNative; - - bool get isExternal; - - Uri get fileUri; - - int get fileOffset; - - void becomeNative( - {required SourceLoader loader, - required Iterable annotatables}); - void resolveRedirectingFactory( {required SourceLibraryBuilder libraryBuilder}); - - List? 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? get metadata; - - ConstructorReferenceBuilder? get redirectionTarget; - - BodyBuilderContext createBodyBuilderContext( - SourceFactoryBuilder factoryBuilder); } -class FactoryDeclarationImpl implements FactoryDeclaration { +class FactoryDeclarationImpl + implements FactoryDeclaration, FactoryFragmentDeclaration { final FactoryFragment _fragment; final List? 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? 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? 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 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 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? get redirectionTypeArguments => - _encoding.redirectionTypeArguments; - - @override - // Coverage-ignore(suite): Not run. - void set redirectionTypeArguments(List? value) { - _encoding.redirectionTypeArguments = value; + void inferRedirectionTarget( + {required SourceLibraryBuilder libraryBuilder, + required SourceFactoryBuilder factoryBuilder, + required ClassHierarchy classHierarchy, + required List 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? 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? 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? 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); +} diff --git a/pkg/front_end/lib/src/fragment/field.dart b/pkg/front_end/lib/src/fragment/field.dart index 55428830839..bc8eb2b523c 100644 --- a/pkg/front_end/lib/src/fragment/field.dart +++ b/pkg/front_end/lib/src/fragment/field.dart @@ -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? 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 get localMembers => _encoding.localMembers; + + @override + List get localSetters => _encoding.localSetters; + + @override + List? 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 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 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? 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? getterOverrideDependencies, + Set? 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 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? 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 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 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? getterOverrideDependencies, - Set? 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 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 get localMembers => _encoding.localMembers; - - @override - List get localSetters => _encoding.localSetters; - - @override - SourcePropertyBuilder get builder => _fragment.builder; - - @override - Uri get fileUri => _fragment.fileUri; - - @override - bool get hasSetter => _fragment.hasSetter; - - @override - List? 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? 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(); } diff --git a/pkg/front_end/lib/src/fragment/getter.dart b/pkg/front_end/lib/src/fragment/getter.dart index ea4731f0d99..ead065aef17 100644 --- a/pkg/front_end/lib/src/fragment/getter.dart +++ b/pkg/front_end/lib/src/fragment/getter.dart @@ -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; diff --git a/pkg/front_end/lib/src/fragment/getter/body_builder_context.dart b/pkg/front_end/lib/src/fragment/getter/body_builder_context.dart index a1ed65f6df8..1f30a24f410 100644 --- a/pkg/front_end/lib/src/fragment/getter/body_builder_context.dart +++ b/pkg/front_end/lib/src/fragment/getter/body_builder_context.dart @@ -18,7 +18,7 @@ import 'declaration.dart'; class GetterFragmentBodyBuilderContext extends BodyBuilderContext { final SourcePropertyBuilder _builder; - final GetterDeclaration _declaration; + final GetterFragmentDeclaration _declaration; GetterFragmentBodyBuilderContext( this._builder, diff --git a/pkg/front_end/lib/src/fragment/getter/declaration.dart b/pkg/front_end/lib/src/fragment/getter/declaration.dart index 633c047bdf0..1b4c0297568 100644 --- a/pkg/front_end/lib/src/fragment/getter/declaration.dart +++ b/pkg/front_end/lib/src/fragment/getter/declaration.dart @@ -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? get formals; - - FunctionNode get function; - - bool get isAbstract; - - bool get isExternal; + GetterQuality get getterQuality; List? get metadata; - String get name; - - int get nameOffset; - Procedure get readTarget; - TypeBuilder get returnType; - - List? 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 unboundNominalParameters); - LocalScope createFormalParameterScope(LookupScope typeParameterScope); - void ensureTypes( {required SourceLibraryBuilder libraryBuilder, required DeclarationBuilder? declarationBuilder, @@ -101,11 +75,10 @@ abstract class GetterDeclaration { required Set? getterOverrideDependencies}); Iterable 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? get formals; + + FunctionNode get function; + + bool get isExternal; + + String get name; + + int get nameOffset; + + TypeBuilder get returnType; + + List? get thisTypeParameters; + + VariableDeclaration? get thisVariable; + + void becomeNative(SourceLoader loader); + + BodyBuilderContext createBodyBuilderContext( + SourcePropertyBuilder propertyBuilder); + + LocalScope createFormalParameterScope(LookupScope typeParameterScope); + + VariableDeclaration getFormalParameter(int index); } diff --git a/pkg/front_end/lib/src/fragment/method.dart b/pkg/front_end/lib/src/fragment/method.dart index da004452d8e..c311c421135 100644 --- a/pkg/front_end/lib/src/fragment/method.dart +++ b/pkg/front_end/lib/src/fragment/method.dart @@ -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; diff --git a/pkg/front_end/lib/src/fragment/method/body_builder_context.dart b/pkg/front_end/lib/src/fragment/method/body_builder_context.dart index 40b4b826a57..1259b2831be 100644 --- a/pkg/front_end/lib/src/fragment/method/body_builder_context.dart +++ b/pkg/front_end/lib/src/fragment/method/body_builder_context.dart @@ -18,7 +18,7 @@ import 'declaration.dart'; class MethodFragmentBodyBuilderContext extends BodyBuilderContext { final MethodFragment _fragment; - final MethodDeclaration _declaration; + final MethodFragmentDeclaration _declaration; MethodFragmentBodyBuilderContext( this._fragment, diff --git a/pkg/front_end/lib/src/fragment/method/declaration.dart b/pkg/front_end/lib/src/fragment/method/declaration.dart index 8db1fb9ef52..effc03f5800 100644 --- a/pkg/front_end/lib/src/fragment/method/declaration.dart +++ b/pkg/front_end/lib/src/fragment/method/declaration.dart @@ -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? 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? 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 unboundNominalParameters); - LocalScope createFormalParameterScope(LookupScope typeParameterScope); - void ensureTypes( ClassMembersBuilder membersBuilder, SourceClassBuilder enclosingClassBuilder, Set? 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? get formals; + + FunctionNode get function; + + TypeBuilder get returnType; + + List? 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); +} diff --git a/pkg/front_end/lib/src/fragment/primary_constructor.dart b/pkg/front_end/lib/src/fragment/primary_constructor.dart index 0737bf07c24..ba6ec4fc830 100644 --- a/pkg/front_end/lib/src/fragment/primary_constructor.dart +++ b/pkg/front_end/lib/src/fragment/primary_constructor.dart @@ -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; diff --git a/pkg/front_end/lib/src/fragment/setter.dart b/pkg/front_end/lib/src/fragment/setter.dart index d9f2aeb6bdb..ff7ed90201b 100644 --- a/pkg/front_end/lib/src/fragment/setter.dart +++ b/pkg/front_end/lib/src/fragment/setter.dart @@ -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; diff --git a/pkg/front_end/lib/src/fragment/setter/body_builder_context.dart b/pkg/front_end/lib/src/fragment/setter/body_builder_context.dart index f8953dba3fd..1c44e46e8ba 100644 --- a/pkg/front_end/lib/src/fragment/setter/body_builder_context.dart +++ b/pkg/front_end/lib/src/fragment/setter/body_builder_context.dart @@ -18,7 +18,7 @@ import 'declaration.dart'; class SetterBodyBuilderContext extends BodyBuilderContext { final SourcePropertyBuilder _builder; - final SetterDeclaration _declaration; + final SetterFragmentDeclaration _declaration; SetterBodyBuilderContext( this._builder, diff --git a/pkg/front_end/lib/src/fragment/setter/declaration.dart b/pkg/front_end/lib/src/fragment/setter/declaration.dart index 9365253e545..dd2dbaecc1a 100644 --- a/pkg/front_end/lib/src/fragment/setter/declaration.dart +++ b/pkg/front_end/lib/src/fragment/setter/declaration.dart @@ -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? get formals; - - FunctionNode get function; - - bool get isAbstract; - - bool get isExternal; - List? get metadata; - String get name; - - int get nameOffset; - - TypeBuilder get returnType; - - List? 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 unboundNominalParameters); - LocalScope createFormalParameterScope(LookupScope typeParameterScope); - void ensureTypes( {required SourceLibraryBuilder libraryBuilder, required DeclarationBuilder? declarationBuilder, @@ -101,11 +75,10 @@ abstract class SetterDeclaration { required Set? setterOverrideDependencies}); Iterable 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? 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? get formals; + + FunctionNode get function; + + bool get isAbstract; + + bool get isExternal; + + String get name; + + int get nameOffset; + + TypeBuilder get returnType; + + List? get thisTypeParameters; + + VariableDeclaration? get thisVariable; + + void becomeNative(SourceLoader loader); + + BodyBuilderContext createBodyBuilderContext( + SourcePropertyBuilder propertyBuilder); + + LocalScope createFormalParameterScope(LookupScope typeParameterScope); + + VariableDeclaration getFormalParameter(int index); } diff --git a/pkg/front_end/lib/src/fragment/util.dart b/pkg/front_end/lib/src/fragment/util.dart index 7f918a14668..f22c0a7751b 100644 --- a/pkg/front_end/lib/src/fragment/util.dart +++ b/pkg/front_end/lib/src/fragment/util.dart @@ -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; diff --git a/pkg/front_end/lib/src/source/source_builder_factory.dart b/pkg/front_end/lib/src/source/source_builder_factory.dart index 343e0c879c6..97da4a4e516 100644 --- a/pkg/front_end/lib/src/source/source_builder_factory.dart +++ b/pkg/front_end/lib/src/source/source_builder_factory.dart @@ -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; } diff --git a/pkg/front_end/lib/src/source/source_constructor_builder.dart b/pkg/front_end/lib/src/source/source_constructor_builder.dart index d051fb5ba8f..1dd6ca6871f 100644 --- a/pkg/front_end/lib/src/source/source_constructor_builder.dart +++ b/pkg/front_end/lib/src/source/source_constructor_builder.dart @@ -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 { + VariableDeclaration thisVariable; + final List 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 delayedDefaultValueCloners); - - int buildBodyNodes(BuildNodesCallback f); - - /// Infers the types of any untyped initializing formals. - void inferFormalTypes(ClassHierarchyBase hierarchy); - - void addSuperParameterDefaultValueCloners( - List 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 delayedDefaultValueCloners); + + int buildBodyNodes(BuildNodesCallback f); + + void buildOutlineExpressions(ClassHierarchy classHierarchy, + List 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 get annotatables => [invokeTarget]; @override // Coverage-ignore(suite): Not run. - Iterable? get metadataForTesting => _introductory.metadata; + Iterable 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 get localMembers => + throw new UnsupportedError('${runtimeType}.localMembers'); + + @override + // Coverage-ignore(suite): Not run. + List 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? 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 get exportedMemberReferences => [invokeTargetReference]; - - // TODO(johnniwinther): Add annotations to tear-offs. - Iterable 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 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 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 get localMembers => - throw new UnsupportedError('${runtimeType}.localMembers'); - - @override - // Coverage-ignore(suite): Not run. - List 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? takeInitializedFields() { - Set? 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 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 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? takeInitializedFields() { + Set? 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? get metadataForTesting => null; + Iterable 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 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 get localMembers => - throw new UnsupportedError('${runtimeType}.localMembers'); - - @override - // Coverage-ignore(suite): Not run. - List 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 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 get localMembers => + throw new UnsupportedError('${runtimeType}.localMembers'); + + @override + // Coverage-ignore(suite): Not run. + List 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? 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 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 { - VariableDeclaration thisVariable; - final List 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); } } diff --git a/pkg/front_end/lib/src/source/source_enum_builder.dart b/pkg/front_end/lib/src/source/source_enum_builder.dart index 284f2022efa..4423bb70d8f 100644 --- a/pkg/front_end/lib/src/source/source_enum_builder.dart +++ b/pkg/front_end/lib/src/source/source_enum_builder.dart @@ -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? 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? 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? classTypeParameters}) { - fieldType = type.build(libraryBuilder, TypeUse.fieldType); + fieldType = _typeBuilder.build(libraryBuilder, TypeUse.fieldType); _field = new Field.immutable(dummyName, type: _type, isFinal: false, diff --git a/pkg/front_end/lib/src/source/source_factory_builder.dart b/pkg/front_end/lib/src/source/source_factory_builder.dart index 663e3c16e2c..b3634f795fc 100644 --- a/pkg/front_end/lib/src/source/source_factory_builder.dart +++ b/pkg/front_end/lib/src/source/source_factory_builder.dart @@ -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 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 get localMembers => diff --git a/pkg/front_end/lib/src/source/type_parameter_scope_builder.dart b/pkg/front_end/lib/src/source/type_parameter_scope_builder.dart index 08390a0adb7..50a0d140a93 100644 --- a/pkg/front_end/lib/src/source/type_parameter_scope_builder.dart +++ b/pkg/front_end/lib/src/source/type_parameter_scope_builder.dart @@ -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, diff --git a/pkg/front_end/test/coverage_suite_expected.dart b/pkg/front_end/test/coverage_suite_expected.dart index beefb6d61e7..e3a2fc1cd06 100644 --- a/pkg/front_end/test/coverage_suite_expected.dart +++ b/pkg/front_end/test/coverage_suite_expected.dart @@ -45,7 +45,7 @@ const Map _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 _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 _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 _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 _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 _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 _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 _expect = { ), // 100.0%. "package:front_end/src/source/source_factory_builder.dart": ( - hitCount: 137, + hitCount: 132, missCount: 0, ), // 100.0%.