-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add assists for macro documentation comments #78
Changes from 2 commits
53155cc
e7dbe49
6326111
0446d4c
e20145a
a835697
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
"bools", | ||
"combinators", | ||
"diffscrape", | ||
"endtemplate", | ||
"gocolly", | ||
"interps", | ||
"ints", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import 'package:analyzer/dart/ast/ast.dart'; | ||
import 'package:analyzer/source/source_range.dart'; | ||
import 'package:custom_lint_builder/custom_lint_builder.dart'; | ||
|
||
/// {@template altive_lints.AddMacroDocumentComment} | ||
/// An assist to add macro template documentation comments to function | ||
/// or constructor declarations. | ||
/// | ||
/// This assist helps maintain consistent documentation across | ||
/// the entire codebase by adding macro template comments | ||
/// to each function or constructor. These comments can be used | ||
/// for documentation generation or by other tools. | ||
/// | ||
/// Macro template comments follow this format: | ||
/// | ||
/// ```dart | ||
/// /// {[@]macro packageName.functionName} | ||
/// ``` | ||
/// | ||
/// Example: | ||
/// | ||
/// Before: | ||
/// ```dart | ||
/// void myFunction() { | ||
/// // Function implementation | ||
/// } | ||
/// ``` | ||
/// | ||
/// After applying the assist: | ||
/// ```dart | ||
/// /// {[@]macro my_package.myFunction} | ||
/// void myFunction() { | ||
/// // Function implementation | ||
/// } | ||
/// ``` | ||
/// | ||
/// {@endtemplate} | ||
class AddMacroDocumentComment extends DartAssist { | ||
/// {@macro altive_lints.AddMacroDocumentComment} | ||
AddMacroDocumentComment(); | ||
|
||
@override | ||
void run( | ||
CustomLintResolver resolver, | ||
ChangeReporter reporter, | ||
CustomLintContext context, | ||
SourceRange target, | ||
) { | ||
context.registry.addFunctionDeclaration((node) { | ||
_processNode(node, target, reporter, context); | ||
}); | ||
|
||
context.registry.addConstructorDeclaration((node) { | ||
_processNode(node, target, reporter, context); | ||
}); | ||
} | ||
|
||
void _processNode( | ||
AstNode node, | ||
SourceRange target, | ||
ChangeReporter reporter, | ||
CustomLintContext context, | ||
) { | ||
if (!target.intersects(node.sourceRange)) { | ||
return; | ||
} | ||
|
||
final changeBuilder = reporter.createChangeBuilder( | ||
message: 'Add macro documentation comment', | ||
priority: 20, | ||
); | ||
|
||
final packageName = context.pubspec.name; | ||
var name = ''; | ||
|
||
if (node is FunctionDeclaration) { | ||
name = node.name.lexeme; | ||
} else if (node is ConstructorDeclaration) { | ||
name = node.returnType.name; | ||
} | ||
|
||
final macroComment = '/// {@macro $packageName.$name}'; | ||
|
||
changeBuilder.addDartFileEdit((builder) { | ||
builder.addSimpleInsertion(node.offset, '$macroComment\n'); | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import 'package:analyzer/source/source_range.dart'; | ||
import 'package:custom_lint_builder/custom_lint_builder.dart'; | ||
|
||
/// {@template altive_lints.AddMacroTemplateDocumentComment} | ||
/// A Dart assist that adds a macro template documentation comment to a class | ||
/// declaration if it does not already have one. | ||
/// | ||
/// This assist helps in maintaining consistent documentation across the | ||
/// codebase by ensuring that each class has a macro template comment, which | ||
/// can be used for generating documentation or for other tooling purposes. | ||
/// | ||
/// The macro template comment follows the format: | ||
/// | ||
/// ```dart | ||
/// /// {[@]template packageName.className} | ||
/// /// | ||
/// /// {[@]endtemplate} | ||
/// ``` | ||
/// | ||
/// Example usage: | ||
/// | ||
/// Before: | ||
/// ```dart | ||
/// class MyClass { | ||
/// // Class implementation | ||
/// } | ||
/// ``` | ||
/// | ||
/// After running the assist: | ||
/// ```dart | ||
/// /// {[@]template my_package.MyClass} | ||
/// /// | ||
/// /// {[@]endtemplate} | ||
/// class MyClass { | ||
/// // Class implementation | ||
/// } | ||
/// ``` | ||
/// | ||
/// {@endtemplate} | ||
class AddMacroTemplateDocumentComment extends DartAssist { | ||
/// {@macro altive_lints.AddMacroTemplateDocumentComment} | ||
AddMacroTemplateDocumentComment(); | ||
|
||
@override | ||
void run( | ||
CustomLintResolver resolver, | ||
ChangeReporter reporter, | ||
CustomLintContext context, | ||
SourceRange target, | ||
) { | ||
context.registry.addClassDeclaration((node) { | ||
if (!target.intersects(node.sourceRange)) { | ||
return; | ||
} | ||
|
||
final docComment = node.documentationComment; | ||
if (docComment != null) { | ||
return; | ||
} | ||
|
||
final changeBuilder = reporter.createChangeBuilder( | ||
message: 'Add macro template documentation comment', | ||
priority: 20, | ||
); | ||
|
||
final packageName = context.pubspec.name; | ||
final className = node.name.lexeme; | ||
|
||
final template = [ | ||
'/// {@template $packageName.$className}', | ||
'/// ', | ||
'/// {@endtemplate}', | ||
].join('\n'); | ||
|
||
changeBuilder.addDartFileEdit((builder) { | ||
builder.addSimpleInsertion(node.offset, '$template\n'); | ||
}); | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,85 @@ | ||||||||||||||||||||||||||||||||||||||||
import 'package:analyzer/dart/ast/ast.dart'; | ||||||||||||||||||||||||||||||||||||||||
import 'package:analyzer/source/source_range.dart'; | ||||||||||||||||||||||||||||||||||||||||
import 'package:custom_lint_builder/custom_lint_builder.dart'; | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
/// {@template altive_lints.WrapWithMacroTemplateDocumentComment} | ||||||||||||||||||||||||||||||||||||||||
/// A Dart assist that wraps an existing documentation comment with a macro | ||||||||||||||||||||||||||||||||||||||||
/// template comment. | ||||||||||||||||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||||||||||||||||
/// This assist helps in maintaining consistent documentation across the | ||||||||||||||||||||||||||||||||||||||||
/// codebase by ensuring that each documentation comment is wrapped with a | ||||||||||||||||||||||||||||||||||||||||
/// macro template, which can be used for generating documentation or for | ||||||||||||||||||||||||||||||||||||||||
/// other tooling purposes. | ||||||||||||||||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||||||||||||||||
/// The macro template comment follows the format: | ||||||||||||||||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||||||||||||||||
/// ```dart | ||||||||||||||||||||||||||||||||||||||||
/// /// {[@]template packageName.className} | ||||||||||||||||||||||||||||||||||||||||
/// /// Existing documentation comment. | ||||||||||||||||||||||||||||||||||||||||
/// /// {[@]endtemplate} | ||||||||||||||||||||||||||||||||||||||||
/// ``` | ||||||||||||||||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||||||||||||||||
/// Example usage: | ||||||||||||||||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||||||||||||||||
/// Before: | ||||||||||||||||||||||||||||||||||||||||
/// ```dart | ||||||||||||||||||||||||||||||||||||||||
/// /// This is a class. | ||||||||||||||||||||||||||||||||||||||||
/// class MyClass { | ||||||||||||||||||||||||||||||||||||||||
/// // Class implementation | ||||||||||||||||||||||||||||||||||||||||
/// } | ||||||||||||||||||||||||||||||||||||||||
/// ``` | ||||||||||||||||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||||||||||||||||
/// After running the assist: | ||||||||||||||||||||||||||||||||||||||||
/// ```dart | ||||||||||||||||||||||||||||||||||||||||
/// /// {[@]template my_package.MyClass} | ||||||||||||||||||||||||||||||||||||||||
/// /// This is a class. | ||||||||||||||||||||||||||||||||||||||||
/// /// {[@]endtemplate} | ||||||||||||||||||||||||||||||||||||||||
/// class MyClass { | ||||||||||||||||||||||||||||||||||||||||
/// // Class implementation | ||||||||||||||||||||||||||||||||||||||||
/// } | ||||||||||||||||||||||||||||||||||||||||
/// ``` | ||||||||||||||||||||||||||||||||||||||||
/// | ||||||||||||||||||||||||||||||||||||||||
/// {@endtemplate} | ||||||||||||||||||||||||||||||||||||||||
class WrapWithMacroTemplateDocumentComment extends DartAssist { | ||||||||||||||||||||||||||||||||||||||||
/// {@macro altive_lints.WrapWithMacroTemplateDocumentComment} | ||||||||||||||||||||||||||||||||||||||||
WrapWithMacroTemplateDocumentComment(); | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
@override | ||||||||||||||||||||||||||||||||||||||||
void run( | ||||||||||||||||||||||||||||||||||||||||
CustomLintResolver resolver, | ||||||||||||||||||||||||||||||||||||||||
ChangeReporter reporter, | ||||||||||||||||||||||||||||||||||||||||
CustomLintContext context, | ||||||||||||||||||||||||||||||||||||||||
SourceRange target, | ||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||
context.registry.addComment((node) { | ||||||||||||||||||||||||||||||||||||||||
if (!target.intersects(node.sourceRange)) { | ||||||||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
if (!node.isDocumentation) { | ||||||||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I thought it might be worth considering adding this early return. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you! Since final currentComment = node.tokens.join();
if (currentComment.contains('{@template') &&
currentComment.contains('{@endtemplate}')) {
return;
} |
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
final changeBuilder = reporter.createChangeBuilder( | ||||||||||||||||||||||||||||||||||||||||
message: 'Wrap with macro template documentation comment', | ||||||||||||||||||||||||||||||||||||||||
priority: 20, | ||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
final packageName = context.pubspec.name; | ||||||||||||||||||||||||||||||||||||||||
final classNode = node.parent; | ||||||||||||||||||||||||||||||||||||||||
var className = ''; | ||||||||||||||||||||||||||||||||||||||||
if (classNode is ClassDeclaration) { | ||||||||||||||||||||||||||||||||||||||||
className = classNode.name.lexeme; | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
final templateStart = '/// {@template $packageName.$className}'; | ||||||||||||||||||||||||||||||||||||||||
const templateEnd = '/// {@endtemplate}'; | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
changeBuilder.addDartFileEdit((builder) { | ||||||||||||||||||||||||||||||||||||||||
builder | ||||||||||||||||||||||||||||||||||||||||
..addSimpleInsertion(node.offset, '$templateStart\n') | ||||||||||||||||||||||||||||||||||||||||
..addSimpleInsertion(node.end, '\n$templateEnd'); | ||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the example, using
@endtemplate
as is would be interpreted as the end of the template, so I’ve enclosed it in[]
to avoid this!