Skip to content

Commit

Permalink
feat: Add assists for macro documentation comments (#78)
Browse files Browse the repository at this point in the history
* feat: Add assists for macro documentation comments

* doc: Update README with new macro documentation assists

* feat: Prevent wrapping of existing macro template documentation comments
  • Loading branch information
naipaka authored Dec 17, 2024
1 parent c3c70f8 commit 8126ddc
Show file tree
Hide file tree
Showing 6 changed files with 345 additions and 0 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"bools",
"combinators",
"diffscrape",
"endtemplate",
"gocolly",
"interps",
"ints",
Expand Down
79 changes: 79 additions & 0 deletions packages/altive_lints/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ There are also Altive-made rules by custom_lint.
- [prefer\_dedicated\_media\_query\_methods](#prefer_dedicated_media_query_methods)
- [prefer\_to\_include\_sliver\_in\_name](#prefer_to_include_sliver_in_name)
- [prefer\_space\_between\_elements](#prefer_space_between_elements)
- [All assists in altive\_lints](#all-assists-in-altive_lints)
- [Add macro template documentation comment](#add-macro-template-documentation-comment)
- [Add macro documentation comment](#add-macro-documentation-comment)
- [Wrap with macro template documentation comment](#wrap-with-macro-template-documentation-comment)
- [Lint rules adopted by altive\_lints and why](#lint-rules-adopted-by-altive_lints-and-why)
- [public\_member\_api\_docs](#public_member_api_docs)
- [Migration guide](#migration-guide)
Expand Down Expand Up @@ -318,6 +322,81 @@ class MyWidget extends StatelessWidget {
}
```

## All assists in altive_lints

### Add macro template documentation comment

Adds a Macros template to class declarations.
When you place the cursor on the class declaration and execute **"Add macro template documentation comment"**, the documentation is created.

**Before:**

```dart
class MyClass {
// Class implementation
}
```

**After applying the assist:**

```dart
/// {@template my_package.MyClass}
///
/// {@endtemplate}
class MyClass {
// Class implementation
}
```

### Add macro documentation comment

Adds Macros comments to constructors and method declarations.
When you place the cursor on a constructor or method declaration and execute **"Add macro documentation comment"**, the documentation is created.

**Before:**

```dart
void myFunction() {
// Function implementation
}
```

**After applying the assist:**

```dart
/// {@macro my_package.myFunction}
void myFunction() {
// Function implementation
}
```

### Wrap with macro template documentation comment

Wraps existing documentation comments with a Macros template.
When you select the documentation comment and execute **"Wrap with macro template documentation comment"**, the documentation is created.

**Before:**

```dart
/// Some comment
/// More comments
class MyClass {
// Class implementation
}
```

**After applying the assist:**

```dart
/// {@template my_package.MyClass}
/// Some comment
/// More comments
/// {@endtemplate}
class MyClass {
// Class implementation
}
```

## Lint rules adopted by altive_lints and why

Reasons for adopting each lint rule.
Expand Down
10 changes: 10 additions & 0 deletions packages/altive_lints/lib/altive_lints.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import 'package:custom_lint_builder/custom_lint_builder.dart';

import 'src/assists/add_macro_document_comments.dart';
import 'src/assists/add_macro_template_document_comment.dart';
import 'src/assists/wrap_with_macro_template_document_comment.dart';
import 'src/lints/avoid_consecutive_sliver_to_box_adapter.dart';
import 'src/lints/avoid_hardcoded_color.dart';
import 'src/lints/avoid_hardcoded_japanese.dart';
Expand All @@ -26,4 +29,11 @@ class _AltivePlugin extends PluginBase {
const PreferSpaceBetweenElements(),
const PreferToIncludeSliverInName(),
];

@override
List<Assist> getAssists() => [
AddMacroDocumentComment(),
AddMacroTemplateDocumentComment(),
WrapWithMacroTemplateDocumentComment(),
];
}
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,87 @@
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;
}

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');
});
});
}
}

0 comments on commit 8126ddc

Please sign in to comment.