-
Notifications
You must be signed in to change notification settings - Fork 0
feat(phpstan): add CanonicalCapitalizationRule for enforcing term spelling #65
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
base: master
Are you sure you want to change the base?
Conversation
…lling Add abstract CanonicalCapitalizationRule base class that checks: - Variable names - Parameter names - Method names - Class names - String literals Add LabIDCapitalizationRule to enforce "Lab ID" spelling over variants like LabID, labID, LABID, Labid, Lab-ID, Lab Id, etc. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…ls only Per coding guidelines: "Unless the circumstances demand otherwise (all lower, no spaces, ...)" - canonical forms like "Lab ID" with spaces only apply to user-facing text in string literals, not to PHP identifiers (variables, methods, classes) where spaces are invalid. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Instead of checking for braces, detect the /* @lang GraphQL */ IDE annotation which explicitly marks GraphQL query strings. This is more precise and follows the existing convention in the codebase. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Tests that: - Wrong capitalizations in strings are detected (LabID -> Lab ID) - Correct capitalizations are ignored - GraphQL queries with @lang annotation are skipped - GraphQL queries without annotation are still checked 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…nRule Strings that look like valid identifiers (matching ^[a-zA-Z_][a-zA-Z0-9_]*$) are likely array keys, API field names, or database columns where spaces are not valid. Skip these to focus on user-facing text. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…ules Generalize GraphQL annotation check to skip any @lang annotated string (SQL, GraphQL, RegExp, etc.) since these contain identifiers that cannot have spaces. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
ReflectionMethod requires setAccessible(true) to invoke protected methods in PHP < 8.1. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
PHPStan internals (PHPStanTestCase) have compatibility issues with older PHP versions due to PHPStan/PHP-Parser version conflicts. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Resolve merge conflicts in phpstan.neon and phpstan-test.neon - Rename CapitalizationOfIDRuleIntegrationTest to IdToIDRuleIntegrationTest - Simplify LabIDCapitalizationRuleIntegrationTest using data-provider pattern - Include both ID → ID rules and Lab ID capitalization rule in test config 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…hods to public simplify tests
| abstract class CanonicalCapitalizationRule implements Rule | ||
| { | ||
| abstract protected function getCanonicalForm(): string; |
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.
Ich finde es nicht korrekt hier von Capitalization zu sprechen. Würde auch die Überschrift der Guideline abändern, wie wäre es mit Canonical ...:
- forms
- spelling
- ?
| protected function cannotContainSpaces(string $value): bool | ||
| { | ||
| return ! str_contains($value, ' '); |
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.
Diese Heuristik kann schon wild inakkurat sein. Wenn jemand fälschlicherweise Limes2 schreibt wo auch Limes 2 stehen könnte, würde es das nicht fangen.
| protected function hasLanguageAnnotation(String_ $node): bool | ||
| { | ||
| foreach ($node->getComments() as $comment) { | ||
| if (Str::contains($comment->getText(), '@lang')) { |
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.
Eventuell können wir das hier einschränken auf gewisse Languages. In @lang Markdown wären alle Formen ok.
| public function fixCapitalization(string $value, string $wrongVariant): string | ||
| { | ||
| return str_replace($wrongVariant, $this->getCanonicalForm(), $value); |
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.
| public function fixCapitalization(string $value, string $wrongVariant): string | |
| { | |
| return str_replace($wrongVariant, $this->getCanonicalForm(), $value); | |
| public function fixCapitalization(string $subject, string $wrongVariant): string | |
| { | |
| return str_replace($wrongVariant, $this->getCanonicalForm(), $subject); |
|
|
||
| public function getNodeType(): string | ||
| { | ||
| return String_::class; |
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.
Fangen wir damit auch alle möglichen Varianten in PHP Strings zu definieren?
| yield 'detects wrong capitalization' => [ | ||
| __DIR__ . '/data/lab-id-capitalization.php', | ||
| [ | ||
| 9 => ['String "The LabID is wrong" should use "Lab ID" instead of "LabID", change it to "The Lab ID is wrong".'], |
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.
Hier den ganzen String in der Nachricht zu zeigen kann sehr unübersichtlich werden, wenn es sich um lange Multiline-Werte handelt.
| 30 => ['String " | ||
| { | ||
| patient { | ||
| labID | ||
| } | ||
| } | ||
| " should use "Lab ID" instead of "labID", change it to " | ||
| { | ||
| patient { | ||
| Lab ID | ||
| } | ||
| } | ||
| ".'], |
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.
Negativbeispiel, in dem Fall sollte via @lang GraphQL der Wert ausgenommen werden.
| 66 => ['String " | ||
| SELECT exam_no AS labID | ||
| FROM examinations | ||
| " should use "Lab ID" instead of "labID", change it to " | ||
| SELECT exam_no AS Lab ID | ||
| FROM examinations | ||
| ".'], |
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.
Auch Negativbeispiel, @lang SQL sollte auch hier zur Exklusion führen.
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.
Testfälle:
- String Interpolation
- Nowdoc
- Heredoc
@langohne weitere Angabe@lang Markdown- Leerer String
- https://encyclopedia.thefreedictionary.com/Labidosaurus
Doppelte Lab-ID gefunden (labID: 12-123456)
Summary
CanonicalCapitalizationRulebase class for enforcing canonical spelling of termsLabIDCapitalizationRulethat enforces "Lab ID" spellingLabID,labID,LABID,Labid,labid,Lab-ID,lab-Id,Lab Id,lab idArchitecture
Uses template method pattern:
getCanonicalForm()- returns the correct spelling (e.g., "Lab ID")getWrongVariants()- returns array of wrong spellings to detectgetErrorIdentifier()- returns PHPStan error identifierThis allows easy creation of new rules for other canonical terms.
Test plan
findWrongVariant()methodfixCapitalization()method🤖 Generated with Claude Code