rubocop-rbs_inline 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.claude/hooks/self-review.sh +89 -0
- data/.claude/settings.json +8 -0
- data/.rubocop.yml +9 -3
- data/CHANGELOG.md +19 -0
- data/CLAUDE.md +9 -14
- data/README.md +54 -6
- data/config/default.yml +3 -4
- data/lib/rubocop/cop/rbs_inline_cops.rb +15 -7
- data/lib/rubocop/cop/style/rbs_inline/data_class_comment_alignment.rb +2 -9
- data/lib/rubocop/cop/style/rbs_inline/data_define_with_block.rb +3 -9
- data/lib/rubocop/cop/style/rbs_inline/embedded_rbs_spacing.rb +3 -2
- data/lib/rubocop/cop/style/rbs_inline/invalid_comment.rb +2 -2
- data/lib/rubocop/cop/style/rbs_inline/invalid_types.rb +1 -0
- data/lib/rubocop/cop/style/rbs_inline/keyword_separator.rb +2 -2
- data/lib/rubocop/cop/style/rbs_inline/method_comment_spacing.rb +3 -2
- data/lib/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rb +2 -9
- data/lib/rubocop/cop/style/rbs_inline/missing_struct_class_annotation.rb +2 -16
- data/lib/rubocop/cop/style/rbs_inline/missing_type_annotation.rb +3 -16
- data/lib/rubocop/cop/style/rbs_inline/mixin/annotation_keywords.rb +16 -0
- data/lib/rubocop/cop/style/rbs_inline/{ast_utils.rb → mixin/ast_utils.rb} +16 -0
- data/lib/rubocop/cop/style/rbs_inline/{comment_parser.rb → mixin/comment_parser.rb} +8 -0
- data/lib/rubocop/cop/style/rbs_inline/mixin/data_class_matcher.rb +22 -0
- data/lib/rubocop/cop/style/rbs_inline/{data_struct_helper.rb → mixin/data_struct_helper.rb} +14 -5
- data/lib/rubocop/cop/style/rbs_inline/mixin/file_filter.rb +110 -0
- data/lib/rubocop/cop/style/rbs_inline/{source_code_helper.rb → mixin/source_code_helper.rb} +3 -5
- data/lib/rubocop/cop/style/rbs_inline/mixin/struct_class_matcher.rb +32 -0
- data/lib/rubocop/cop/style/rbs_inline/parameters_separator.rb +2 -2
- data/lib/rubocop/cop/style/rbs_inline/redundant_annotation_with_skip.rb +2 -11
- data/lib/rubocop/cop/style/rbs_inline/redundant_instance_variable_annotation.rb +1 -0
- data/lib/rubocop/cop/style/rbs_inline/redundant_type_annotation.rb +6 -15
- data/lib/rubocop/cop/style/rbs_inline/require_rbs_inline_comment.rb +74 -23
- data/lib/rubocop/cop/style/rbs_inline/struct_class_comment_alignment.rb +2 -16
- data/lib/rubocop/cop/style/rbs_inline/struct_new_with_block.rb +3 -9
- data/lib/rubocop/cop/style/rbs_inline/unmatched_annotations.rb +31 -6
- data/lib/rubocop/cop/style/rbs_inline/untyped_instance_variable.rb +16 -6
- data/lib/rubocop/cop/style/rbs_inline/variable_comment_spacing.rb +3 -2
- data/lib/rubocop/rbs_inline/version.rb +1 -1
- data/sig/gems/rubocop/rubocop.rbs +8 -0
- data/sig/rubocop/cop/style/rbs_inline/data_class_comment_alignment.rbs +4 -5
- data/sig/rubocop/cop/style/rbs_inline/data_define_with_block.rbs +4 -5
- data/sig/rubocop/cop/style/rbs_inline/embedded_rbs_spacing.rbs +2 -0
- data/sig/rubocop/cop/style/rbs_inline/invalid_comment.rbs +4 -3
- data/sig/rubocop/cop/style/rbs_inline/invalid_types.rbs +2 -0
- data/sig/rubocop/cop/style/rbs_inline/keyword_separator.rbs +4 -3
- data/sig/rubocop/cop/style/rbs_inline/method_comment_spacing.rbs +2 -0
- data/sig/rubocop/cop/style/rbs_inline/missing_data_class_annotation.rbs +4 -5
- data/sig/rubocop/cop/style/rbs_inline/missing_struct_class_annotation.rbs +4 -10
- data/sig/rubocop/cop/style/rbs_inline/missing_type_annotation.rbs +4 -8
- data/sig/rubocop/cop/style/rbs_inline/mixin/annotation_keywords.rbs +16 -0
- data/sig/rubocop/cop/style/rbs_inline/{ast_utils.rbs → mixin/ast_utils.rbs} +9 -1
- data/sig/rubocop/cop/style/rbs_inline/{class_comment_alignment.rbs → mixin/class_comment_alignment.rbs} +1 -1
- data/sig/rubocop/cop/style/rbs_inline/{comment_parser.rbs → mixin/comment_parser.rbs} +5 -1
- data/sig/rubocop/cop/style/rbs_inline/mixin/data_class_matcher.rbs +18 -0
- data/sig/rubocop/cop/style/rbs_inline/{data_struct_helper.rbs → mixin/data_struct_helper.rbs} +6 -1
- data/sig/rubocop/cop/style/rbs_inline/mixin/file_filter.rbs +63 -0
- data/sig/rubocop/cop/style/rbs_inline/{missing_class_annotation.rbs → mixin/missing_class_annotation.rbs} +1 -1
- data/sig/rubocop/cop/style/rbs_inline/{source_code_helper.rbs → mixin/source_code_helper.rbs} +1 -1
- data/sig/rubocop/cop/style/rbs_inline/mixin/struct_class_matcher.rbs +26 -0
- data/sig/rubocop/cop/style/rbs_inline/parameters_separator.rbs +4 -3
- data/sig/rubocop/cop/style/rbs_inline/redundant_annotation_with_skip.rbs +4 -4
- data/sig/rubocop/cop/style/rbs_inline/redundant_instance_variable_annotation.rbs +2 -0
- data/sig/rubocop/cop/style/rbs_inline/redundant_type_annotation.rbs +4 -4
- data/sig/rubocop/cop/style/rbs_inline/require_rbs_inline_comment.rbs +30 -5
- data/sig/rubocop/cop/style/rbs_inline/struct_class_comment_alignment.rbs +4 -10
- data/sig/rubocop/cop/style/rbs_inline/struct_new_with_block.rbs +4 -5
- data/sig/rubocop/cop/style/rbs_inline/unmatched_annotations.rbs +13 -0
- data/sig/rubocop/cop/style/rbs_inline/untyped_instance_variable.rbs +10 -0
- data/sig/rubocop/cop/style/rbs_inline/variable_comment_spacing.rbs +2 -0
- metadata +24 -17
- data/sig/rubocop/cop/style/rbs_inline/redundant_argument_type.rbs +0 -85
- data/sig/rubocop/cop/style/rbs_inline/redundant_return_type.rbs +0 -109
- /data/lib/rubocop/cop/style/rbs_inline/{class_comment_alignment.rb → mixin/class_comment_alignment.rb} +0 -0
- /data/lib/rubocop/cop/style/rbs_inline/{missing_class_annotation.rb → mixin/missing_class_annotation.rb} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e4bebfc6eae9ec29990f1dafdf2fc773737b2cf001c450702b138b1d9ab81dec
|
|
4
|
+
data.tar.gz: f9ebb04f3712f5f02cd6b7388ea74b056fdce19027be61ed6b651cf1b5915ca8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 46b9e51e95573630afbe686500cdf154a2cdf2d76bd19f441552fe76267682fb586118f96e7b0c5316352b49fc6e5ddc3b080fd1dc8b6711d31e382694ad767d
|
|
7
|
+
data.tar.gz: 9bd7d22ee40b4d009b1c2f2f86d855a37ee32349c12afffdebbda6cf5edf54bf9c474f67bdfb170987ea512c0934deb48d709f1afbc49acef88f968ebff4297a
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# PreToolUse hook: review code before `git commit`.
|
|
4
|
+
#
|
|
5
|
+
# Fires before a Bash `git commit` command and blocks the first commit attempt
|
|
6
|
+
# for a given change-set, asking Claude to review the code before committing.
|
|
7
|
+
# The review uses the `self-review` skill when available, and falls back to the
|
|
8
|
+
# bundled `code-review` skill otherwise — so the hook works even in projects
|
|
9
|
+
# that don't ship the custom self-review skill.
|
|
10
|
+
#
|
|
11
|
+
# A per-change-set marker (keyed by a hash of the diff, stored under .git/)
|
|
12
|
+
# prevents an infinite block loop: once a change-set has been surfaced for
|
|
13
|
+
# review, the matching commit is allowed through. If the review leads to fixes,
|
|
14
|
+
# the diff changes, so the new state is reviewed once more before it commits.
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
# Read JSON input from stdin
|
|
20
|
+
input=$(cat)
|
|
21
|
+
|
|
22
|
+
tool_name=$(echo "$input" | jq -r '.tool_name // empty')
|
|
23
|
+
command=$(echo "$input" | jq -r '.tool_input.command // empty')
|
|
24
|
+
|
|
25
|
+
# Only gate the Bash tool running a git commit.
|
|
26
|
+
if [[ "$tool_name" != "Bash" ]]; then
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
# Match `git commit`, or `git -C <path> commit`.
|
|
30
|
+
commit_re='git[[:space:]]+(-C[[:space:]]+[^[:space:]]+[[:space:]]+)?commit'
|
|
31
|
+
if [[ ! "$command" =~ $commit_re ]]; then
|
|
32
|
+
exit 0
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# If the command targets a specific repo via `git -C <path>`, operate there too.
|
|
36
|
+
work_dir="."
|
|
37
|
+
if [[ "$command" =~ git[[:space:]]+-C[[:space:]]+([^[:space:]]+) ]]; then
|
|
38
|
+
work_dir="${BASH_REMATCH[1]}"
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Not a git repo → nothing to do.
|
|
42
|
+
git_dir=$(git -C "$work_dir" rev-parse --absolute-git-dir 2>/dev/null || true)
|
|
43
|
+
if [[ -z "$git_dir" ]]; then
|
|
44
|
+
exit 0
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Hash what will be committed. `git status --porcelain` is included so a commit
|
|
48
|
+
# that only adds untracked files isn't mistaken for empty; `git diff HEAD` adds
|
|
49
|
+
# tracked content. On the first commit there is no HEAD, so use the working state.
|
|
50
|
+
if git -C "$work_dir" rev-parse --verify HEAD >/dev/null 2>&1; then
|
|
51
|
+
changeset=$(git -C "$work_dir" status --porcelain; git -C "$work_dir" diff HEAD)
|
|
52
|
+
else
|
|
53
|
+
changeset=$(git -C "$work_dir" status --porcelain; git -C "$work_dir" diff; git -C "$work_dir" diff --cached)
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Nothing to review (e.g. a message-only `--amend`) → let it proceed.
|
|
57
|
+
if [[ -z "$changeset" ]]; then
|
|
58
|
+
exit 0
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
hash=$(printf '%s' "$changeset" | git hash-object --stdin)
|
|
62
|
+
state_file="$git_dir/self-review-reviewed"
|
|
63
|
+
|
|
64
|
+
# Already surfaced for review → allow the commit.
|
|
65
|
+
if [[ -f "$state_file" ]] && grep -qxF "$hash" "$state_file"; then
|
|
66
|
+
exit 0
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# Record this change-set and block once to force a review first.
|
|
70
|
+
echo "$hash" >> "$state_file"
|
|
71
|
+
|
|
72
|
+
review_prompt='SELF-REVIEW REQUIRED before committing. Review the changes that are
|
|
73
|
+
about to be committed BEFORE running git commit again:
|
|
74
|
+
|
|
75
|
+
- If the `self-review` skill is available, invoke it (Skill tool, skill "self-review").
|
|
76
|
+
- Otherwise, run the bundled `/code-review` skill on the working diff.
|
|
77
|
+
|
|
78
|
+
If the review finds issues, fix them and review again. Once it is clean, run the same
|
|
79
|
+
git commit command again to proceed — it will be allowed through.'
|
|
80
|
+
|
|
81
|
+
jq -n --arg reason "$review_prompt" '{
|
|
82
|
+
"hookSpecificOutput": {
|
|
83
|
+
"hookEventName": "PreToolUse",
|
|
84
|
+
"permissionDecision": "deny",
|
|
85
|
+
"permissionDecisionReason": $reason
|
|
86
|
+
}
|
|
87
|
+
}'
|
|
88
|
+
|
|
89
|
+
exit 0
|
data/.claude/settings.json
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": ["RemoteTrigger"]
|
|
4
|
+
},
|
|
2
5
|
"hooks": {
|
|
3
6
|
"SessionStart": [
|
|
4
7
|
{
|
|
@@ -19,6 +22,11 @@
|
|
|
19
22
|
{
|
|
20
23
|
"type": "command",
|
|
21
24
|
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/pre-commit-check.sh"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"type": "command",
|
|
28
|
+
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/self-review.sh",
|
|
29
|
+
"timeout": 10000
|
|
22
30
|
}
|
|
23
31
|
]
|
|
24
32
|
}
|
data/.rubocop.yml
CHANGED
|
@@ -56,16 +56,22 @@ RSpec/NamedSubject:
|
|
|
56
56
|
RSpec/NestedGroups:
|
|
57
57
|
Max: 5
|
|
58
58
|
|
|
59
|
+
# Mixin specs mirror `lib/.../rbs_inline/mixin/`, but the modules keep the
|
|
60
|
+
# `RuboCop::Cop::Style::RbsInline` namespace, so the path never matches the constant.
|
|
61
|
+
RSpec/SpecFilePathFormat:
|
|
62
|
+
Exclude:
|
|
63
|
+
- "spec/rubocop/cop/style/rbs_inline/mixin/**/*_spec.rb"
|
|
64
|
+
|
|
59
65
|
# RbsInline
|
|
66
|
+
Style/RbsInline:
|
|
67
|
+
Mode: opt_out
|
|
68
|
+
|
|
60
69
|
Style/RbsInline/MissingTypeAnnotation:
|
|
61
70
|
EnforcedStyle: doc_style_and_return_annotation
|
|
62
71
|
|
|
63
72
|
Style/RbsInline/RedundantTypeAnnotation:
|
|
64
73
|
EnforcedStyle: doc_style_and_return_annotation
|
|
65
74
|
|
|
66
|
-
Style/RbsInline/RequireRbsInlineComment:
|
|
67
|
-
EnforcedStyle: never
|
|
68
|
-
|
|
69
75
|
# Style
|
|
70
76
|
Style/AccessorGrouping:
|
|
71
77
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.8.0 (2026-07-26)
|
|
4
|
+
|
|
5
|
+
### Enhancements
|
|
6
|
+
|
|
7
|
+
- **Style/RbsInline**: Added a shared `Mode` setting (`opt_in` / `opt_out`) at the department level to filter which files each cop checks based on the `# rbs_inline: enabled` / `disabled` magic comment.
|
|
8
|
+
- **Style/RbsInline/RequireRbsInlineComment**: Added the `AllowMissingComment` option, which lets projects use rbs-inline on only some of their files while keeping the opt-in filter for the rest.
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
- **Style/RbsInline/DataClassCommentAlignment**, **Style/RbsInline/StructClassCommentAlignment**: Fixed the expected annotation column being derived from arguments that cannot carry an annotation (a splat, or for `Struct.new` a leading struct name or `keyword_init:`), which reported false positives on already aligned code and made autocorrect over-pad the annotations.
|
|
13
|
+
- **Style/RbsInline/MissingDataClassAnnotation**, **Style/RbsInline/MissingStructClassAnnotation**: Fixed autocorrect padding the inserted annotations to the width of an argument that cannot carry one (a splat, or for `Struct.new` a leading struct name or `keyword_init:`).
|
|
14
|
+
- **Style/RbsInline/UnmatchedAnnotations**: Fixed a crash on method definitions taking a destructuring argument (ex. `def foo((a, b))`). The crash also aborted the inspection of the method definition, causing false positives on its valid annotations.
|
|
15
|
+
- **Style/RbsInline/RequireRbsInlineComment**: Fixed a crash (`IndexError`) on a file whose leading comment block ends without a trailing newline. The offense is now reported and the magic comment is inserted on its own line.
|
|
16
|
+
- **Style/RbsInline/RedundantTypeAnnotation**: Fixed `--auto-gen-config` generating an `EnforcedStyle` that does not resolve the offenses (including the unsupported `return_type_annotation`, which made RuboCop fail to start on the generated `.rubocop_todo.yml`). No style can make redundant annotations offense-free, so the offending files are now excluded instead.
|
|
17
|
+
|
|
18
|
+
### Deprecations
|
|
19
|
+
|
|
20
|
+
- **Style/RbsInline/RequireRbsInlineComment**: `EnforcedStyle` is deprecated in favor of the department-level `Mode`. Migrate `always` → `Style/RbsInline: Mode: opt_in`, `never` → `Style/RbsInline: Mode: opt_out`. Will be removed in the next major version.
|
|
21
|
+
|
|
3
22
|
## 1.7.0 (2026-07-20)
|
|
4
23
|
|
|
5
24
|
### New Features
|
data/CLAUDE.md
CHANGED
|
@@ -23,7 +23,7 @@ bundle exec rake rubocop:autocorrect_all # all autocorrect
|
|
|
23
23
|
bundle exec rake steep # runs steep check
|
|
24
24
|
bundle exec rake rbs:validate # validates RBS signatures
|
|
25
25
|
|
|
26
|
-
# Default rake task (
|
|
26
|
+
# Default rake task (rubocop, specs, steep, rbs:validate)
|
|
27
27
|
bundle exec rake
|
|
28
28
|
|
|
29
29
|
# Generate a new cop
|
|
@@ -34,32 +34,27 @@ bundle exec rake 'new_cop[Style/RbsInline/CopName]'
|
|
|
34
34
|
|
|
35
35
|
### Cop Structure
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Cops live in `lib/rubocop/cop/style/rbs_inline/`, one per file; the shared modules they mix in live in `lib/rubocop/cop/style/rbs_inline/mixin/`. Both are under the `RuboCop::Cop::Style::RbsInline` namespace — only the directory separates them, as in `rubocop`'s `cop/mixin/`. `config/default.yml` lists every cop and its options; read it instead of a list kept here.
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
- **InvalidTypes** - Validates RBS type syntax in annotations
|
|
41
|
-
- **KeywordSeparator** - Ensures keywords like `module-self` aren't followed by `:`
|
|
42
|
-
- **ParametersSeparator** - Ensures parameter annotations use `:` separator
|
|
43
|
-
- **RedundantArgumentType** - Detects redundant argument type specs (configurable style)
|
|
44
|
-
- **RedundantReturnType** - Detects redundant return type specs (3 style options)
|
|
45
|
-
- **UnmatchedAnnotations** - Ensures annotation parameters match actual method parameters
|
|
39
|
+
Conventions:
|
|
46
40
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
`comment_parser.rb` is a module mixed into cops that need to parse RBS::Inline annotations. It uses `RBS::Inline::AnnotationParser` and Prism to parse comments, and provides helpers for finding leading annotations, inline comments, and return annotations relative to method definitions.
|
|
41
|
+
- Every cop `prepend`s `FileFilter` except `RequireRbsInlineComment`.
|
|
42
|
+
- `Data.define` and `Struct.new` cops come in pairs sharing a base module. Behavior belongs in the module; only the node matcher and `MSG` in the cop.
|
|
50
43
|
|
|
51
44
|
### Plugin System
|
|
52
45
|
|
|
53
|
-
The gem integrates with RuboCop via LintRoller (`lib/rubocop/rbs_inline/plugin.rb`)
|
|
46
|
+
The gem integrates with RuboCop via LintRoller (`lib/rubocop/rbs_inline/plugin.rb`), which points RuboCop at `config/default.yml`.
|
|
54
47
|
|
|
55
48
|
### Type Signatures
|
|
56
49
|
|
|
57
|
-
|
|
50
|
+
`sig/rubocop/` is generated from `lib/` by the hooks in `.claude/hooks/`. Never write anything there. `sig/gems/` is hand-written stubs for third-party gems and is *not* regenerated — do not delete it when refreshing signatures.
|
|
58
51
|
|
|
59
52
|
### Testing Pattern
|
|
60
53
|
|
|
61
54
|
Tests use RuboCop's RSpec support helpers (`expect_offense` / `expect_no_offenses`). Test files mirror the cop file structure under `spec/rubocop/cop/style/rbs_inline/`.
|
|
62
55
|
|
|
56
|
+
`:config` specs build a bare `RuboCop::Config`, so `config/default.yml` and RuboCop's department-to-cop defaults are not merged in. A spec that sets a value at the department level proves nothing about how it resolves in a real run.
|
|
57
|
+
|
|
63
58
|
## Code Style Notes
|
|
64
59
|
|
|
65
60
|
- `Layout/LeadingCommentSpace` and `Style/CommentedKeyword` are disabled because RBS::Inline `#:` comments violate these rules by design.
|
data/README.md
CHANGED
|
@@ -27,6 +27,23 @@ plugins:
|
|
|
27
27
|
|
|
28
28
|
rubocop-rbs_inline provides the following cops to validate [RBS::Inline](https://github.com/soutaro/rbs-inline) annotations:
|
|
29
29
|
|
|
30
|
+
### Style/RbsInline (shared configuration)
|
|
31
|
+
|
|
32
|
+
The `Style/RbsInline` department has a shared `Mode` setting that gates whether each `Style/RbsInline/*` cop reports offenses on a given file:
|
|
33
|
+
|
|
34
|
+
- `Mode: opt_in` — cops only check files that carry `# rbs_inline: enabled`. Files with `# rbs_inline: disabled` or no magic comment are skipped. Matches RBS::Inline's opt-in mode.
|
|
35
|
+
- `Mode: opt_out` — cops check every file except those with `# rbs_inline: disabled`. Matches RBS::Inline's opt-out mode.
|
|
36
|
+
- unset — cops check every file (legacy behavior; the default will change to `opt_in` in the next major release).
|
|
37
|
+
|
|
38
|
+
Declare it once at the department level in your `.rubocop.yml`:
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
Style/RbsInline:
|
|
42
|
+
Mode: opt_in
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Unknown `Mode` values (e.g. `Mode: opt-in`) emit a warning and disable filtering for the run.
|
|
46
|
+
|
|
30
47
|
### Style/RbsInline/DataClassCommentAlignment
|
|
31
48
|
|
|
32
49
|
Checks that `#:` inline type annotations in a multiline `Data.define` call are aligned to the same column. The expected column is determined by the longest attribute name (plus its trailing comma). Folded `Data.define` calls (where multiple attributes share a line) are excluded.
|
|
@@ -238,7 +255,11 @@ Enforces that method definitions and `attr_*` declarations have RBS inline type
|
|
|
238
255
|
- `all`: Checks all methods regardless of visibility
|
|
239
256
|
- `public`: Only checks public methods and `attr_*` declarations
|
|
240
257
|
|
|
241
|
-
|
|
258
|
+
Always excluded, regardless of `EnforcedStyle`:
|
|
259
|
+
|
|
260
|
+
- Methods annotated with `# @rbs skip` or `# @rbs override`.
|
|
261
|
+
- Parameters whose name starts with `_`.
|
|
262
|
+
- The `...` forward-all parameter.
|
|
242
263
|
|
|
243
264
|
**Examples (EnforcedStyle: doc_style):**
|
|
244
265
|
```ruby
|
|
@@ -466,13 +487,26 @@ end
|
|
|
466
487
|
|
|
467
488
|
### Style/RbsInline/RequireRbsInlineComment
|
|
468
489
|
|
|
469
|
-
Enforces presence or absence of `# rbs_inline:` magic comment
|
|
490
|
+
Enforces the presence or absence of the `# rbs_inline:` magic comment, based on the shared [`Mode`](#stylerbsinline-shared-configuration) setting:
|
|
491
|
+
|
|
492
|
+
- Under `Mode: opt_in`, files must carry `# rbs_inline: enabled` (or `# rbs_inline: disabled`).
|
|
493
|
+
- Under `Mode: opt_out`, files must not carry `# rbs_inline: enabled`.
|
|
494
|
+
|
|
495
|
+
**Configuration:**
|
|
496
|
+
|
|
497
|
+
- `AllowMissingComment` (default: `false`) — under `Mode: opt_in`, set to `true` to skip enforcement of the magic comment on individual files. Useful when only part of the project uses rbs-inline: the shared `Mode: opt_in` filter still applies to every other cop (they only report on files that opt in), but this cop stops requiring the magic comment on files that intentionally do not use rbs-inline.
|
|
498
|
+
|
|
499
|
+
```yaml
|
|
500
|
+
Style/RbsInline:
|
|
501
|
+
Mode: opt_in
|
|
502
|
+
|
|
503
|
+
Style/RbsInline/RequireRbsInlineComment:
|
|
504
|
+
AllowMissingComment: true
|
|
505
|
+
```
|
|
470
506
|
|
|
471
|
-
|
|
472
|
-
- `always`: Requires `# rbs_inline: enabled` or `# rbs_inline: disabled`
|
|
473
|
-
- `never`: Forbids `# rbs_inline: enabled` (allows `# rbs_inline: disabled`)
|
|
507
|
+
The legacy `EnforcedStyle` parameter (`always` / `never`) is deprecated in favor of `Mode`; it will be removed in the next major release.
|
|
474
508
|
|
|
475
|
-
**Examples (
|
|
509
|
+
**Examples (Mode: opt_in):**
|
|
476
510
|
```ruby
|
|
477
511
|
# bad
|
|
478
512
|
class Foo
|
|
@@ -484,6 +518,18 @@ class Foo
|
|
|
484
518
|
end
|
|
485
519
|
```
|
|
486
520
|
|
|
521
|
+
**Examples (Mode: opt_in, AllowMissingComment: true):**
|
|
522
|
+
```ruby
|
|
523
|
+
# good - the magic comment is not enforced per file
|
|
524
|
+
class Foo
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
# good
|
|
528
|
+
# rbs_inline: enabled
|
|
529
|
+
class Foo
|
|
530
|
+
end
|
|
531
|
+
```
|
|
532
|
+
|
|
487
533
|
### Style/RbsInline/StructClassCommentAlignment
|
|
488
534
|
|
|
489
535
|
Checks that `#:` inline type annotations in a multiline `Struct.new` call are aligned to the same column. The expected column is determined by the longest attribute name (plus its trailing comma). Folded `Struct.new` calls (where multiple attributes share a line) are excluded.
|
|
@@ -613,6 +659,8 @@ Style/RbsInline/MissingTypeAnnotation:
|
|
|
613
659
|
Visibility: public
|
|
614
660
|
```
|
|
615
661
|
|
|
662
|
+
To restrict every cop to files that carry `# rbs_inline: enabled`, see [Style/RbsInline (shared configuration)](#stylerbsinline-shared-configuration).
|
|
663
|
+
|
|
616
664
|
See [config/default.yml](config/default.yml) for all available configuration options.
|
|
617
665
|
|
|
618
666
|
## Development
|
data/config/default.yml
CHANGED
|
@@ -5,6 +5,7 @@ Style/RbsInline:
|
|
|
5
5
|
Exclude:
|
|
6
6
|
- 'spec/**/*'
|
|
7
7
|
- 'test/**/*'
|
|
8
|
+
Mode: ~
|
|
8
9
|
|
|
9
10
|
Style/RbsInline/DataClassCommentAlignment:
|
|
10
11
|
Description: "Checks that `#:` inline type annotations in `Data.define` blocks are aligned."
|
|
@@ -94,10 +95,8 @@ Style/RbsInline/RequireRbsInlineComment:
|
|
|
94
95
|
Description: "Checks the presence or absence of `# rbs_inline: enabled` magic comment."
|
|
95
96
|
Enabled: true
|
|
96
97
|
VersionAdded: "1.5.0"
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
- always
|
|
100
|
-
- never
|
|
98
|
+
AllowMissingComment: false
|
|
99
|
+
EnforcedStyle: ~
|
|
101
100
|
|
|
102
101
|
Style/RbsInline/StructClassCommentAlignment:
|
|
103
102
|
Description: "Checks that `#:` inline type annotations in `Struct.new` blocks are aligned."
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
require_relative "style/rbs_inline/
|
|
7
|
-
require_relative "style/rbs_inline/
|
|
8
|
-
require_relative "style/rbs_inline/
|
|
3
|
+
# Mixins first, in dependency order. Cops follow, alphabetically: `rake new_cop` sorts a
|
|
4
|
+
# generated require only against the others in the same directory, so the two blocks have
|
|
5
|
+
# to stay apart for it to land in the right place.
|
|
6
|
+
require_relative "style/rbs_inline/mixin/annotation_keywords"
|
|
7
|
+
require_relative "style/rbs_inline/mixin/ast_utils"
|
|
8
|
+
require_relative "style/rbs_inline/mixin/source_code_helper"
|
|
9
|
+
require_relative "style/rbs_inline/mixin/comment_parser"
|
|
10
|
+
require_relative "style/rbs_inline/mixin/data_struct_helper"
|
|
11
|
+
require_relative "style/rbs_inline/mixin/missing_class_annotation"
|
|
12
|
+
require_relative "style/rbs_inline/mixin/class_comment_alignment"
|
|
13
|
+
require_relative "style/rbs_inline/mixin/data_class_matcher"
|
|
14
|
+
require_relative "style/rbs_inline/mixin/file_filter"
|
|
15
|
+
require_relative "style/rbs_inline/mixin/struct_class_matcher"
|
|
16
|
+
|
|
9
17
|
require_relative "style/rbs_inline/data_class_comment_alignment"
|
|
10
18
|
require_relative "style/rbs_inline/data_define_with_block"
|
|
11
19
|
require_relative "style/rbs_inline/embedded_rbs_spacing"
|
|
@@ -14,6 +22,7 @@ require_relative "style/rbs_inline/invalid_types"
|
|
|
14
22
|
require_relative "style/rbs_inline/keyword_separator"
|
|
15
23
|
require_relative "style/rbs_inline/method_comment_spacing"
|
|
16
24
|
require_relative "style/rbs_inline/missing_data_class_annotation"
|
|
25
|
+
require_relative "style/rbs_inline/missing_struct_class_annotation"
|
|
17
26
|
require_relative "style/rbs_inline/missing_type_annotation"
|
|
18
27
|
require_relative "style/rbs_inline/parameters_separator"
|
|
19
28
|
require_relative "style/rbs_inline/redundant_annotation_with_skip"
|
|
@@ -22,7 +31,6 @@ require_relative "style/rbs_inline/redundant_type_annotation"
|
|
|
22
31
|
require_relative "style/rbs_inline/require_rbs_inline_comment"
|
|
23
32
|
require_relative "style/rbs_inline/struct_class_comment_alignment"
|
|
24
33
|
require_relative "style/rbs_inline/struct_new_with_block"
|
|
25
|
-
require_relative "style/rbs_inline/missing_struct_class_annotation"
|
|
26
34
|
require_relative "style/rbs_inline/unmatched_annotations"
|
|
27
35
|
require_relative "style/rbs_inline/untyped_instance_variable"
|
|
28
36
|
require_relative "style/rbs_inline/variable_comment_spacing"
|
|
@@ -26,7 +26,9 @@ module RuboCop
|
|
|
26
26
|
# )
|
|
27
27
|
#
|
|
28
28
|
class DataClassCommentAlignment < Base
|
|
29
|
+
prepend FileFilter
|
|
29
30
|
include ClassCommentAlignment
|
|
31
|
+
include DataClassMatcher
|
|
30
32
|
extend AutoCorrector
|
|
31
33
|
|
|
32
34
|
MSG = "Misaligned inline type annotation for Data attribute."
|
|
@@ -37,15 +39,6 @@ module RuboCop
|
|
|
37
39
|
|
|
38
40
|
check_comment_alignment(node)
|
|
39
41
|
end
|
|
40
|
-
|
|
41
|
-
private
|
|
42
|
-
|
|
43
|
-
# @rbs node: RuboCop::AST::SendNode
|
|
44
|
-
def struct_like_class?(node) #: bool
|
|
45
|
-
return false unless node.method_name == :define
|
|
46
|
-
|
|
47
|
-
(r = node.receiver).is_a?(RuboCop::AST::ConstNode) && r.short_name == :Data
|
|
48
|
-
end
|
|
49
42
|
end
|
|
50
43
|
end
|
|
51
44
|
end
|
|
@@ -28,6 +28,9 @@ module RuboCop
|
|
|
28
28
|
# end
|
|
29
29
|
#
|
|
30
30
|
class DataDefineWithBlock < Base
|
|
31
|
+
prepend FileFilter
|
|
32
|
+
include DataClassMatcher
|
|
33
|
+
|
|
31
34
|
MSG = "Do not use `Data.define` with a block. RBS::Inline does not parse block contents, " \
|
|
32
35
|
"so methods defined in the block will not be recognized. " \
|
|
33
36
|
"Use a separate class definition instead."
|
|
@@ -41,15 +44,6 @@ module RuboCop
|
|
|
41
44
|
|
|
42
45
|
add_offense(node)
|
|
43
46
|
end
|
|
44
|
-
|
|
45
|
-
private
|
|
46
|
-
|
|
47
|
-
# @rbs node: RuboCop::AST::SendNode
|
|
48
|
-
def struct_like_class?(node) #: bool
|
|
49
|
-
return false unless node.method_name == :define
|
|
50
|
-
|
|
51
|
-
(r = node.receiver).is_a?(RuboCop::AST::ConstNode) && r.short_name == :Data
|
|
52
|
-
end
|
|
53
47
|
end
|
|
54
48
|
end
|
|
55
49
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "source_code_helper"
|
|
4
|
-
require_relative "comment_parser"
|
|
3
|
+
require_relative "mixin/source_code_helper"
|
|
4
|
+
require_relative "mixin/comment_parser"
|
|
5
5
|
|
|
6
6
|
module RuboCop
|
|
7
7
|
module Cop
|
|
@@ -26,6 +26,7 @@ module RuboCop
|
|
|
26
26
|
# end
|
|
27
27
|
#
|
|
28
28
|
class EmbeddedRbsSpacing < Base
|
|
29
|
+
prepend FileFilter
|
|
29
30
|
extend AutoCorrector
|
|
30
31
|
include SourceCodeHelper
|
|
31
32
|
include CommentParser
|
|
@@ -20,12 +20,12 @@ module RuboCop
|
|
|
20
20
|
# # @rbs param: String
|
|
21
21
|
#
|
|
22
22
|
class InvalidComment < Base
|
|
23
|
+
prepend FileFilter
|
|
23
24
|
extend AutoCorrector
|
|
25
|
+
include AnnotationKeywords
|
|
24
26
|
|
|
25
27
|
MSG = "Invalid RBS annotation comment found."
|
|
26
28
|
|
|
27
|
-
# refs: https://github.com/soutaro/rbs-inline/blob/main/lib/rbs/inline/annotation_parser/tokenizer.rb
|
|
28
|
-
RBS_INLINE_KEYWORDS = %w[inherits override use module-self generic skip module class].freeze #: Array[String]
|
|
29
29
|
RBS_INLINE_KEYWORD_PATTERN = RBS_INLINE_KEYWORDS.join("|") #: String
|
|
30
30
|
|
|
31
31
|
SIGNATURE_PATTERN = '\(.*\)\s*(\??\s*{.*?}\s*)?->\s*.*'
|
|
@@ -15,14 +15,14 @@ module RuboCop
|
|
|
15
15
|
# # @rbs module-self String
|
|
16
16
|
#
|
|
17
17
|
class KeywordSeparator < Base
|
|
18
|
+
prepend FileFilter
|
|
18
19
|
extend AutoCorrector
|
|
20
|
+
include AnnotationKeywords
|
|
19
21
|
include CommentParser
|
|
20
22
|
include RangeHelp
|
|
21
23
|
|
|
22
24
|
MSG = "Do not use `:` after the keyword."
|
|
23
25
|
|
|
24
|
-
# refs: https://github.com/soutaro/rbs-inline/blob/main/lib/rbs/inline/annotation_parser/tokenizer.rb
|
|
25
|
-
RBS_INLINE_KEYWORDS = %w[inherits override use module-self generic skip module class].freeze #: Array[String]
|
|
26
26
|
# `override` and `skip` are standalone markers that take no arguments.
|
|
27
27
|
# Even before a method definition they may not be followed by `:` alone,
|
|
28
28
|
# because `# @rbs override:` (no type) is not a valid parameter annotation.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "source_code_helper"
|
|
4
|
-
require_relative "comment_parser"
|
|
3
|
+
require_relative "mixin/source_code_helper"
|
|
4
|
+
require_relative "mixin/comment_parser"
|
|
5
5
|
|
|
6
6
|
module RuboCop
|
|
7
7
|
module Cop
|
|
@@ -56,6 +56,7 @@ module RuboCop
|
|
|
56
56
|
# end
|
|
57
57
|
#
|
|
58
58
|
class MethodCommentSpacing < Base
|
|
59
|
+
prepend FileFilter
|
|
59
60
|
extend AutoCorrector
|
|
60
61
|
include RangeHelp
|
|
61
62
|
include SourceCodeHelper
|
|
@@ -21,7 +21,9 @@ module RuboCop
|
|
|
21
21
|
# )
|
|
22
22
|
#
|
|
23
23
|
class MissingDataClassAnnotation < Base
|
|
24
|
+
prepend FileFilter
|
|
24
25
|
include MissingClassAnnotation
|
|
26
|
+
include DataClassMatcher
|
|
25
27
|
extend AutoCorrector
|
|
26
28
|
|
|
27
29
|
MSG = "Missing inline type annotation for Data attribute (e.g., `#: Type`)."
|
|
@@ -32,15 +34,6 @@ module RuboCop
|
|
|
32
34
|
|
|
33
35
|
check_missing_annotations(node)
|
|
34
36
|
end
|
|
35
|
-
|
|
36
|
-
private
|
|
37
|
-
|
|
38
|
-
# @rbs node: RuboCop::AST::SendNode
|
|
39
|
-
def struct_like_class?(node) #: bool
|
|
40
|
-
return false unless node.method_name == :define
|
|
41
|
-
|
|
42
|
-
(r = node.receiver).is_a?(RuboCop::AST::ConstNode) && r.short_name == :Data
|
|
43
|
-
end
|
|
44
37
|
end
|
|
45
38
|
end
|
|
46
39
|
end
|
|
@@ -22,7 +22,9 @@ module RuboCop
|
|
|
22
22
|
# )
|
|
23
23
|
#
|
|
24
24
|
class MissingStructClassAnnotation < Base
|
|
25
|
+
prepend FileFilter
|
|
25
26
|
include MissingClassAnnotation
|
|
27
|
+
include StructClassMatcher
|
|
26
28
|
extend AutoCorrector
|
|
27
29
|
|
|
28
30
|
MSG = "Missing inline type annotation for Struct attribute (e.g., `#: Type`)."
|
|
@@ -33,22 +35,6 @@ module RuboCop
|
|
|
33
35
|
|
|
34
36
|
check_missing_annotations(node)
|
|
35
37
|
end
|
|
36
|
-
|
|
37
|
-
private
|
|
38
|
-
|
|
39
|
-
# @rbs node: RuboCop::AST::SendNode
|
|
40
|
-
def struct_like_class?(node) #: bool
|
|
41
|
-
return false unless node.method_name == :new
|
|
42
|
-
|
|
43
|
-
(r = node.receiver).is_a?(RuboCop::AST::ConstNode) && r.short_name == :Struct
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# `Struct.new` treats a leading string argument as the struct name, so only
|
|
47
|
-
# symbol arguments are attributes.
|
|
48
|
-
# @rbs arg: RuboCop::AST::Node
|
|
49
|
-
def attr_argument?(arg) #: bool
|
|
50
|
-
arg.sym_type?
|
|
51
|
-
end
|
|
52
38
|
end
|
|
53
39
|
end
|
|
54
40
|
end
|
|
@@ -22,7 +22,8 @@ module RuboCop
|
|
|
22
22
|
# - `all`: Checks all methods regardless of visibility (default)
|
|
23
23
|
# - `public`: Only checks public methods and `attr_*` declarations
|
|
24
24
|
#
|
|
25
|
-
# Methods annotated with `# @rbs skip`
|
|
25
|
+
# Methods annotated with `# @rbs skip` or `# @rbs override`, parameters with a leading
|
|
26
|
+
# `_`, and the `...` parameter are always excluded.
|
|
26
27
|
#
|
|
27
28
|
# @example EnforcedStyle: doc_style
|
|
28
29
|
# # bad
|
|
@@ -116,6 +117,7 @@ module RuboCop
|
|
|
116
117
|
# attr_reader :name #: String
|
|
117
118
|
#
|
|
118
119
|
class MissingTypeAnnotation < Base # rubocop:disable Metrics/ClassLength
|
|
120
|
+
prepend FileFilter
|
|
119
121
|
include ASTUtils
|
|
120
122
|
include CommentParser
|
|
121
123
|
include ConfigurableEnforcedStyle
|
|
@@ -347,21 +349,6 @@ module RuboCop
|
|
|
347
349
|
add_offense(node, message: ATTRIBUTE_METHOD_MESSAGE)
|
|
348
350
|
end
|
|
349
351
|
|
|
350
|
-
# Returns the last line of the method parameter list (the closing ) line, or the def line if no parens).
|
|
351
|
-
# @rbs node: RuboCop::AST::DefNode
|
|
352
|
-
def method_parameter_list_end_line(node) #: Integer
|
|
353
|
-
args_node = args_node_for(node)
|
|
354
|
-
end_line(args_node, default: node.location.line)
|
|
355
|
-
end
|
|
356
|
-
|
|
357
|
-
# @rbs node: RuboCop::AST::DefNode
|
|
358
|
-
def args_node_for(node) #: RuboCop::AST::Node
|
|
359
|
-
case node.type
|
|
360
|
-
when :defs then node.children[2]
|
|
361
|
-
else node.children[1]
|
|
362
|
-
end
|
|
363
|
-
end
|
|
364
|
-
|
|
365
352
|
# @rbs node: RuboCop::AST::DefNode
|
|
366
353
|
def method_has_arguments?(node) #: bool
|
|
367
354
|
args_node_for(node).children.any?
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
module RbsInline
|
|
7
|
+
# Provides the list of keywords that may follow `# @rbs` in an annotation comment.
|
|
8
|
+
#
|
|
9
|
+
# refs: https://github.com/soutaro/rbs-inline/blob/main/lib/rbs/inline/annotation_parser/tokenizer.rb
|
|
10
|
+
module AnnotationKeywords
|
|
11
|
+
RBS_INLINE_KEYWORDS = %w[inherits override use module-self generic skip module class].freeze #: Array[String]
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -12,6 +12,22 @@ module RuboCop
|
|
|
12
12
|
location.end&.line || default
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
# Returns the arguments node of a method definition.
|
|
16
|
+
# @rbs node: RuboCop::AST::DefNode
|
|
17
|
+
def args_node_for(node) #: RuboCop::AST::Node
|
|
18
|
+
case node.type
|
|
19
|
+
when :def then node.children[1]
|
|
20
|
+
when :defs then node.children[2]
|
|
21
|
+
else raise
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Returns the last line of the method parameter list (the closing ) line, or the def line if no parens).
|
|
26
|
+
# @rbs node: RuboCop::AST::DefNode
|
|
27
|
+
def method_parameter_list_end_line(node) #: Integer
|
|
28
|
+
end_line(args_node_for(node), default: node.location.line)
|
|
29
|
+
end
|
|
30
|
+
|
|
15
31
|
# @rbs node: RuboCop::AST::Node
|
|
16
32
|
def name_location(node) #: untyped
|
|
17
33
|
location = node.location #: untyped
|