diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart index 7b6f5e926cb..25b1ce8f17c 100644 --- a/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart +++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart @@ -193,16 +193,29 @@ abstract class ConstructorDefinitionBuilder implements DefinitionBuilder { /// /// The [initializers] should not contain trailing or preceding commas. /// + /// If [docComments] are supplied, they will be added above this augment + /// declaration. + /// /// TODO: Link the library augmentations proposal to describe the semantics. - void augment({FunctionBodyCode? body, List? initializers}); + void augment({ + FunctionBodyCode? body, + List? initializers, + CommentCode? docComments, + }); } /// The APIs used by [Macro]s to augment functions or methods. abstract class FunctionDefinitionBuilder implements DefinitionBuilder { /// Augments the function. /// + /// If [docComments] are supplied, they will be added above this augment + /// declaration. + /// /// TODO: Link the library augmentations proposal to describe the semantics. - void augment(FunctionBodyCode body); + void augment( + FunctionBodyCode body, { + CommentCode? docComments, + }); } /// The API used by [Macro]s to augment a top level variable or instance field. @@ -212,11 +225,19 @@ abstract class VariableDefinitionBuilder implements DefinitionBuilder { /// For [getter] and [setter] the full function declaration should be /// provided, minus the `augment` keyword (which will be implicitly added). /// + /// If [initializerDocComments] are supplied, they will be added above the + /// augment declaration for [initializer]. It is an error to provide + /// [initializerDocComments] but not [initializer]. + /// + /// To provide doc comments for [getter] or [setter], just include them in + /// the [DeclarationCode] object for those. + /// /// TODO: Link the library augmentations proposal to describe the semantics. void augment({ DeclarationCode? getter, DeclarationCode? setter, ExpressionCode? initializer, + CommentCode? initializerDocComments, }); } diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/code.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/code.dart index 351e8b27df3..ccbea97f618 100644 --- a/pkg/_fe_analyzer_shared/lib/src/macros/api/code.dart +++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/code.dart @@ -32,6 +32,17 @@ class DeclarationCode extends Code { DeclarationCode.fromParts(super.parts) : super.fromParts(); } +/// A piece of code representing a code comment. This may contain identifier +/// references inside of `[]` brackets if the comments are doc comments. +class CommentCode extends Code { + @override + CodeKind get kind => CodeKind.comment; + + CommentCode.fromString(super.code) : super.fromString(); + + CommentCode.fromParts(super.parts) : super.fromParts(); +} + /// A piece of code representing a syntactically valid expression. class ExpressionCode extends Code { @override @@ -331,6 +342,7 @@ extension Join on List { } enum CodeKind { + comment, declaration, expression, functionBody, diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/builder_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/builder_impls.dart index fd9b98ea73c..96e6ba6865c 100644 --- a/pkg/_fe_analyzer_shared/lib/src/macros/executor/builder_impls.dart +++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/builder_impls.dart @@ -299,9 +299,9 @@ class FunctionDefinitionBuilderImpl extends DefinitionBuilderBase }); @override - void augment(FunctionBodyCode body) { + void augment(FunctionBodyCode body, {CommentCode? docComments}) { DeclarationCode augmentation = - _buildFunctionAugmentation(body, declaration); + _buildFunctionAugmentation(body, declaration, docComments: docComments); if (declaration is MemberDeclaration) { _typeAugmentations.update( (declaration as MethodDeclarationImpl).definingType, @@ -330,12 +330,15 @@ class ConstructorDefinitionBuilderImpl extends DefinitionBuilderBase }); @override - void augment({FunctionBodyCode? body, List? initializers}) { + void augment( + {FunctionBodyCode? body, + List? initializers, + CommentCode? docComments}) { body ??= new FunctionBodyCode.fromString('''{ augment super(); }'''); DeclarationCode augmentation = _buildFunctionAugmentation(body, declaration, - initializers: initializers); + initializers: initializers, docComments: docComments); _typeAugmentations.update( declaration.definingType, (value) => value..add(augmentation), ifAbsent: () => [augmentation]); @@ -362,12 +365,14 @@ class VariableDefinitionBuilderImpl extends DefinitionBuilderBase void augment( {DeclarationCode? getter, DeclarationCode? setter, - ExpressionCode? initializer}) { + ExpressionCode? initializer, + CommentCode? initializerDocComments}) { List augmentations = _buildVariableAugmentations( declaration, getter: getter, setter: setter, - initializer: initializer); + initializer: initializer, + initializerDocComments: initializerDocComments); if (declaration is MemberDeclaration) { _typeAugmentations.update( (declaration as FieldDeclarationImpl).definingType, @@ -384,7 +389,13 @@ List _buildVariableAugmentations( VariableDeclaration declaration, {DeclarationCode? getter, DeclarationCode? setter, - ExpressionCode? initializer}) { + ExpressionCode? initializer, + CommentCode? initializerDocComments}) { + if (initializerDocComments != null && initializer == null) { + throw new ArgumentError( + 'initializerDocComments cannot be provided if an initializer is not ' + 'provided.'); + } List augmentations = []; if (getter != null) { augmentations.add(new DeclarationCode.fromParts([ @@ -402,6 +413,7 @@ List _buildVariableAugmentations( } if (initializer != null) { augmentations.add(new DeclarationCode.fromParts([ + if (initializerDocComments != null) initializerDocComments, 'augment ', if (declaration is FieldDeclaration && declaration.isStatic) 'static ', if (declaration.isFinal) 'final ', @@ -424,10 +436,11 @@ List _buildVariableAugmentations( /// constructor. DeclarationCode _buildFunctionAugmentation( FunctionBodyCode body, FunctionDeclaration declaration, - {List? initializers}) { + {List? initializers, CommentCode? docComments}) { assert(initializers == null || declaration is ConstructorDeclaration); return new DeclarationCode.fromParts([ + if (docComments != null) docComments, 'augment ', if (declaration is ConstructorDeclaration) ...[ declaration.definingType.name, diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor/serialization_extensions.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor/serialization_extensions.dart index 40c435a2674..31f8fbf7176 100644 --- a/pkg/_fe_analyzer_shared/lib/src/macros/executor/serialization_extensions.dart +++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor/serialization_extensions.dart @@ -387,6 +387,8 @@ extension DeserializerExtensions on Deserializer { switch (kind) { case CodeKind.raw: return new Code.fromParts(_readParts()) as T; + case CodeKind.comment: + return new CommentCode.fromParts(_readParts()) as T; case CodeKind.declaration: return new DeclarationCode.fromParts(_readParts()) as T; case CodeKind.expression: @@ -538,6 +540,7 @@ extension SerializeCode on Code { self.bound.serializeNullable(serializer); serializer.addString(self.name); return; + case CodeKind.comment: case CodeKind.declaration: case CodeKind.expression: case CodeKind.raw: