[cfe] Add MethodDeclaration

In preparation for merging SourceMethodBuilder and SyntheticMethodBuilder

Change-Id: I1de377596d710070e4516b09aacb85f5cbab49b4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/417800
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
Johnni Winther
2025-03-26 01:41:15 -07:00
committed by Commit Queue
parent 60ea089c87
commit 8d693e032d
8 changed files with 1438 additions and 1195 deletions
+1 -2
View File
@@ -49,9 +49,7 @@ import '../source/source_enum_builder.dart';
import '../source/source_extension_builder.dart';
import '../source/source_extension_type_declaration_builder.dart';
import '../source/source_factory_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_method_builder.dart';
import '../source/source_property_builder.dart';
@@ -66,6 +64,7 @@ import 'constructor/declaration.dart';
import 'factory/declaration.dart';
import 'getter/declaration.dart';
import 'getter/encoding.dart';
import 'method/declaration.dart';
import 'setter/declaration.dart';
import 'setter/encoding.dart';
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,102 @@
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:kernel/ast.dart';
import 'package:kernel/transformations/flags.dart';
import '../../base/local_scope.dart';
import '../../builder/declaration_builders.dart';
import '../../builder/formal_parameter_builder.dart';
import '../../builder/type_builder.dart';
import '../../kernel/body_builder_context.dart';
import '../../source/source_library_builder.dart';
import '../../source/source_member_builder.dart';
import '../../type_inference/type_schema.dart';
import '../fragment.dart';
import 'declaration.dart';
class MethodFragmentBodyBuilderContext extends BodyBuilderContext {
final MethodFragment _fragment;
final MethodDeclaration _declaration;
MethodFragmentBodyBuilderContext(
this._fragment,
this._declaration,
SourceLibraryBuilder libraryBuilder,
DeclarationBuilder? declarationBuilder,
{required bool isDeclarationInstanceMember})
: super(libraryBuilder, declarationBuilder,
isDeclarationInstanceMember: isDeclarationInstanceMember);
@override
// Coverage-ignore(suite): Not run.
AugmentSuperTarget? get augmentSuperTarget {
if (_fragment.builder.isAugmentation) {
return _fragment.builder.augmentSuperTarget;
}
return null;
}
@override
List<FormalParameterBuilder>? get formals => _declaration.formals;
@override
FunctionNode get function => _declaration.function;
@override
bool get isExternalFunction => _fragment.modifiers.isExternal;
@override
int get memberNameLength => _fragment.name.length;
@override
int get memberNameOffset => _fragment.nameOffset;
@override
TypeBuilder get returnType => _fragment.returnType;
@override
DartType get returnTypeContext {
final bool isReturnTypeUndeclared =
_fragment.returnType is OmittedTypeBuilder &&
function.returnType is DynamicType;
return isReturnTypeUndeclared ? const UnknownType() : function.returnType;
}
@override
LocalScope computeFormalParameterInitializerScope(LocalScope parent) {
/// Initializer formals or super parameters cannot occur in getters so
/// we don't need to create a new scope.
return parent;
}
@override
VariableDeclaration getFormalParameter(int index) =>
_declaration.getFormalParameter(index);
@override
VariableDeclaration? getTearOffParameter(int index) =>
_declaration.getTearOffParameter(index);
@override
void registerFunctionBody(Statement body) {
function.body = body..parent = function;
}
@override
void registerSuperCall() {
// TODO(johnniwinther): This should be set on the member built from this
// fragment and copied to the origin if necessary.
_fragment.builder.invokeTarget.transformerFlags |=
TransformerFlag.superCalls;
}
@override
void setAsyncModifier(AsyncMarker asyncModifier) {
assert(
asyncModifier == _fragment.asyncModifier,
"Unexpected change in async modifier on $_fragment from "
"${_fragment.asyncModifier} to $asyncModifier.");
}
}
@@ -0,0 +1,256 @@
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/type_environment.dart';
import '../../base/local_scope.dart';
import '../../base/messages.dart';
import '../../base/scope.dart';
import '../../builder/declaration_builders.dart';
import '../../builder/formal_parameter_builder.dart';
import '../../builder/metadata_builder.dart';
import '../../builder/type_builder.dart';
import '../../kernel/body_builder_context.dart';
import '../../kernel/hierarchy/class_member.dart';
import '../../kernel/hierarchy/members_builder.dart';
import '../../kernel/type_algorithms.dart';
import '../../source/name_scheme.dart';
import '../../source/source_class_builder.dart';
import '../../source/source_library_builder.dart';
import '../../source/source_loader.dart';
import '../../source/source_member_builder.dart';
import '../../source/source_method_builder.dart';
import '../fragment.dart';
import 'body_builder_context.dart';
import 'encoding.dart';
abstract class MethodDeclaration {
Uri get fileUri;
List<FormalParameterBuilder>? get formals;
List<FormalParameterBuilder>? get formalsForTesting;
FunctionNode get function;
Procedure get invokeTarget;
bool get isOperator;
List<MetadataBuilder>? get metadata;
Procedure? get readTarget;
TypeBuilder get returnType;
List<TypeParameter>? get thisTypeParameters;
VariableDeclaration? get thisVariable;
List<NominalParameterBuilder>? get typeParametersForTesting;
void becomeNative(SourceLoader loader);
void buildOutlineExpressions(
ClassHierarchy classHierarchy,
SourceLibraryBuilder libraryBuilder,
DeclarationBuilder? declarationBuilder,
SourceMethodBuilder methodBuilder,
Annotatable annotatable,
{required bool isClassInstanceMember,
required bool createFileUriExpression});
void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
NameScheme nameScheme, BuildNodesCallback f,
{required Reference reference,
required Reference? tearOffReference,
required List<TypeParameter>? classTypeParameters});
void checkTypes(
SourceLibraryBuilder libraryBuilder, TypeEnvironment typeEnvironment);
void checkVariance(
SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment);
int computeDefaultTypes(ComputeDefaultTypeContext context);
BodyBuilderContext createBodyBuilderContext(SourceMethodBuilder builder);
void createEncoding(
ProblemReporting problemReporting,
SourceMethodBuilder builder,
MethodEncodingStrategy encodingStrategy,
List<NominalParameterBuilder> unboundNominalParameters);
LocalScope createFormalParameterScope(LookupScope typeParameterScope);
void ensureTypes(
ClassMembersBuilder membersBuilder,
SourceClassBuilder enclosingClassBuilder,
Set<ClassMember>? overrideDependencies);
VariableDeclaration getFormalParameter(int index);
VariableDeclaration? getTearOffParameter(int index);
}
class MethodDeclarationImpl implements MethodDeclaration {
final MethodFragment _fragment;
late final MethodEncoding _encoding;
MethodDeclarationImpl(this._fragment) {
_fragment.declaration = this;
}
@override
Uri get fileUri => _fragment.fileUri;
@override
// TODO: implement formals
List<FormalParameterBuilder>? get formals => _encoding.formals;
// Coverage-ignore(suite): Not run.
@override
List<FormalParameterBuilder>? get formalsForTesting =>
_encoding.formalsForTesting;
@override
FunctionNode get function => _encoding.function;
@override
Procedure get invokeTarget => _encoding.invokeTarget;
@override
bool get isOperator => _fragment.isOperator;
@override
List<MetadataBuilder>? get metadata => _fragment.metadata;
@override
Procedure? get readTarget => _encoding.readTarget;
@override
TypeBuilder get returnType => _fragment.returnType;
@override
List<TypeParameter>? get thisTypeParameters => _encoding.thisTypeParameters;
@override
VariableDeclaration? get thisVariable => _encoding.thisVariable;
// Coverage-ignore(suite): Not run.
@override
List<NominalParameterBuilder>? get typeParametersForTesting =>
_encoding.clonedAndDeclaredTypeParameters;
@override
void becomeNative(SourceLoader loader) {
_encoding.becomeNative(loader);
}
@override
void buildOutlineExpressions(
ClassHierarchy classHierarchy,
SourceLibraryBuilder libraryBuilder,
DeclarationBuilder? declarationBuilder,
SourceMethodBuilder methodBuilder,
Annotatable annotatable,
{required bool isClassInstanceMember,
required bool createFileUriExpression}) {
_encoding.buildOutlineExpressions(
classHierarchy,
libraryBuilder,
declarationBuilder,
createBodyBuilderContext(methodBuilder),
annotatable,
isClassInstanceMember: isClassInstanceMember,
createFileUriExpression: createFileUriExpression);
}
@override
void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
NameScheme nameScheme, BuildNodesCallback f,
{required Reference reference,
required Reference? tearOffReference,
required List<TypeParameter>? classTypeParameters}) {
_encoding.buildOutlineNode(libraryBuilder, nameScheme, f,
reference: reference,
tearOffReference: tearOffReference,
isAbstractOrExternal:
_fragment.modifiers.isAbstract || _fragment.modifiers.isExternal,
classTypeParameters: classTypeParameters);
}
@override
void checkTypes(
SourceLibraryBuilder libraryBuilder, TypeEnvironment typeEnvironment) {
_encoding.checkTypes(libraryBuilder, typeEnvironment);
}
@override
void checkVariance(
SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
_encoding.checkVariance(sourceClassBuilder, typeEnvironment);
}
@override
int computeDefaultTypes(ComputeDefaultTypeContext context) {
return _encoding.computeDefaultTypes(context);
}
@override
BodyBuilderContext createBodyBuilderContext(SourceMethodBuilder builder) {
return new MethodFragmentBodyBuilderContext(
_fragment, this, builder.libraryBuilder, builder.declarationBuilder,
isDeclarationInstanceMember: builder.isDeclarationInstanceMember);
}
@override
void createEncoding(
ProblemReporting problemReporting,
SourceMethodBuilder builder,
MethodEncodingStrategy encodingStrategy,
List<NominalParameterBuilder> unboundNominalParameters) {
_encoding = encodingStrategy.createMethodEncoding(
builder, _fragment, unboundNominalParameters);
_fragment.typeParameterNameSpace.addTypeParameters(
problemReporting, _encoding.clonedAndDeclaredTypeParameters,
ownerName: _fragment.name, allowNameConflict: true);
returnType.registerInferredTypeListener(_encoding);
}
@override
LocalScope createFormalParameterScope(LookupScope typeParameterScope) {
return _encoding.createFormalParameterScope(typeParameterScope);
}
@override
void ensureTypes(
ClassMembersBuilder membersBuilder,
SourceClassBuilder enclosingClassBuilder,
Set<ClassMember>? overrideDependencies) {
if (overrideDependencies != null) {
membersBuilder.inferMethodType(enclosingClassBuilder, _encoding.function,
returnType, _fragment.declaredFormals, overrideDependencies,
name: _fragment.name,
fileUri: fileUri,
nameOffset: _fragment.nameOffset,
nameLength: _fragment.name.length);
}
_encoding.ensureTypes(
enclosingClassBuilder.libraryBuilder, membersBuilder.hierarchyBuilder);
}
@override
VariableDeclaration getFormalParameter(int index) {
return _encoding.getFormalParameter(index);
}
@override
VariableDeclaration? getTearOffParameter(int index) {
return _encoding.getTearOffParameter(index);
}
}
File diff suppressed because it is too large Load Diff
@@ -2122,7 +2122,7 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult {
fragment.declaration.becomeNative(loader);
}
for (MethodFragment fragment in _nativeMethodFragments) {
fragment.becomeNative(loader);
fragment.declaration.becomeNative(loader);
}
for (ConstructorFragment fragment in _nativeConstructorFragments) {
fragment.builder.becomeNative(loader);
@@ -14,7 +14,7 @@ import '../builder/formal_parameter_builder.dart';
import '../builder/metadata_builder.dart';
import '../builder/method_builder.dart';
import '../builder/type_builder.dart';
import '../fragment/fragment.dart';
import '../fragment/method/declaration.dart';
import '../kernel/hierarchy/class_member.dart';
import '../kernel/hierarchy/members_builder.dart';
import '../kernel/kernel_helper.dart';
@@ -52,8 +52,8 @@ class SourceMethodBuilder extends SourceMemberBuilderImpl
/// The declarations that introduces this method. Subsequent methods of the
/// same name must be augmentations.
final MethodFragment _introductory;
final List<MethodFragment> _augmentations;
final MethodDeclaration _introductory;
final List<MethodDeclaration> _augmentations;
final Modifiers _modifiers;
@@ -74,8 +74,8 @@ class SourceMethodBuilder extends SourceMemberBuilderImpl
required this.isStatic,
required Modifiers modifiers,
required NameScheme nameScheme,
required MethodFragment introductory,
required List<MethodFragment> augmentations,
required MethodDeclaration introductory,
required List<MethodDeclaration> augmentations,
required Reference? reference,
required Reference? tearOffReference})
: _nameScheme = nameScheme,
@@ -127,19 +127,19 @@ class SourceMethodBuilder extends SourceMemberBuilderImpl
@override
void buildOutlineNodes(BuildNodesCallback f) {
List<MethodFragment> augmentedFragments = [
List<MethodDeclaration> augmentedFragments = [
_introductory,
..._augmentations
];
// TODO(johnniwinther): Support augmenting a concrete method with an
// abstract method.
MethodFragment lastFragment = augmentedFragments.removeLast();
MethodDeclaration lastFragment = augmentedFragments.removeLast();
lastFragment.buildOutlineNode(libraryBuilder, _nameScheme, f,
reference: _reference,
tearOffReference: _tearOffReference,
classTypeParameters: classBuilder?.cls.typeParameters);
for (MethodFragment augmented in augmentedFragments) {
for (MethodDeclaration augmented in augmentedFragments) {
augmented.buildOutlineNode(
libraryBuilder, _nameScheme, noAddBuildNodesCallback,
reference: new Reference(),
@@ -156,14 +156,14 @@ class SourceMethodBuilder extends SourceMemberBuilderImpl
void buildOutlineExpressions(ClassHierarchy classHierarchy,
List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {
if (!hasBuiltOutlineExpressions) {
_introductory.buildOutlineExpressions(
classHierarchy, libraryBuilder, declarationBuilder, _invokeTarget,
_introductory.buildOutlineExpressions(classHierarchy, libraryBuilder,
declarationBuilder, this, _invokeTarget,
isClassInstanceMember: isClassInstanceMember,
createFileUriExpression:
_invokeTarget.fileUri != _introductory.fileUri);
for (MethodFragment augmentation in _augmentations) {
augmentation.buildOutlineExpressions(
classHierarchy, libraryBuilder, declarationBuilder, _invokeTarget,
for (MethodDeclaration augmentation in _augmentations) {
augmentation.buildOutlineExpressions(classHierarchy, libraryBuilder,
declarationBuilder, this, _invokeTarget,
isClassInstanceMember: isClassInstanceMember,
createFileUriExpression:
_invokeTarget.fileUri != augmentation.fileUri);
@@ -179,7 +179,7 @@ class SourceMethodBuilder extends SourceMemberBuilderImpl
// default values declared on the introductory method and omitted on the
// augmenting method.
_introductory.checkTypes(library, typeEnvironment);
for (MethodFragment augmentation in _augmentations) {
for (MethodDeclaration augmentation in _augmentations) {
augmentation.checkTypes(library, typeEnvironment);
}
}
@@ -189,7 +189,7 @@ class SourceMethodBuilder extends SourceMemberBuilderImpl
SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
if (!isClassInstanceMember) return;
_introductory.checkVariance(sourceClassBuilder, typeEnvironment);
for (MethodFragment augmentation in _augmentations) {
for (MethodDeclaration augmentation in _augmentations) {
augmentation.checkVariance(sourceClassBuilder, typeEnvironment);
}
}
@@ -241,7 +241,7 @@ class SourceMethodBuilder extends SourceMemberBuilderImpl
int computeDefaultTypes(ComputeDefaultTypeContext context,
{required bool inErrorRecovery}) {
int count = _introductory.computeDefaultTypes(context);
for (MethodFragment augmentation in _augmentations) {
for (MethodDeclaration augmentation in _augmentations) {
count += augmentation.computeDefaultTypes(context);
}
return count;
@@ -25,6 +25,8 @@ import '../fragment/constructor/declaration.dart';
import '../fragment/factory/declaration.dart';
import '../fragment/fragment.dart';
import '../fragment/getter/declaration.dart';
import '../fragment/method/declaration.dart';
import '../fragment/method/encoding.dart';
import '../fragment/setter/declaration.dart';
import 'builder_factory.dart';
import 'name_scheme.dart';
@@ -1857,13 +1859,17 @@ void _computeBuildersFromFragments(String name, List<Fragment> fragments,
}
Modifiers modifiers = fragment.modifiers;
List<MethodFragment> augmentationFragments = [];
MethodDeclaration introductoryDeclaration =
new MethodDeclarationImpl(fragment);
List<MethodDeclaration> augmentationDeclarations = [];
if (augmentations != null) {
for (Fragment augmentation in augmentations) {
// Promote [augmentation] to [MethodFragment].
augmentation as MethodFragment;
augmentationFragments.add(augmentation);
augmentationDeclarations
.add(new MethodDeclarationImpl(augmentation));
createNominalParameterBuilders(
augmentation.declaredTypeParameters, unboundNominalParameters);
@@ -1874,7 +1880,6 @@ void _computeBuildersFromFragments(String name, List<Fragment> fragments,
modifiers -= Modifiers.External;
}
}
augmentations = null;
}
SourceMethodBuilder methodBuilder = new SourceMethodBuilder(
@@ -1885,17 +1890,28 @@ void _computeBuildersFromFragments(String name, List<Fragment> fragments,
declarationBuilder: declarationBuilder,
isStatic: modifiers.isStatic,
modifiers: modifiers,
introductory: fragment,
augmentations: augmentationFragments,
introductory: introductoryDeclaration,
augmentations: augmentationDeclarations,
nameScheme: nameScheme,
reference: procedureReference,
tearOffReference: tearOffReference);
fragment.setBuilder(problemReporting, methodBuilder, encodingStrategy,
unboundNominalParameters);
for (MethodFragment augmentation in augmentationFragments) {
augmentation.setBuilder(problemReporting, methodBuilder,
fragment.builder = methodBuilder;
if (augmentations != null) {
for (Fragment augmentation in augmentations) {
// Promote [augmentation] to [MethodFragment].
augmentation as MethodFragment;
augmentation.builder = methodBuilder;
}
augmentations = null;
}
introductoryDeclaration.createEncoding(problemReporting, methodBuilder,
encodingStrategy, unboundNominalParameters);
for (MethodDeclaration augmentation in augmentationDeclarations) {
augmentation.createEncoding(problemReporting, methodBuilder,
encodingStrategy, unboundNominalParameters);
}
builders.add(new _AddBuilder(
fragment.name, methodBuilder, fragment.fileUri, fragment.nameOffset,
inPatch: fragment.enclosingDeclaration?.isPatch ??