Skip to content

Fix camelCase resource URI goto (#11) and add AOP interceptor goto (#19)#20

Merged
koriym merged 13 commits into
masterfrom
claude/clever-brahmagupta-HeSkK
May 31, 2026
Merged

Fix camelCase resource URI goto (#11) and add AOP interceptor goto (#19)#20
koriym merged 13 commits into
masterfrom
claude/clever-brahmagupta-HeSkK

Conversation

@koriym
Copy link
Copy Markdown
Member

@koriym koriym commented May 30, 2026

Summary

This PR delivers two items agreed for this session:

A separate verification pass also confirmed #7 (URI-Template goto) and #12 (ClassCastException) are already resolved in the current code; those were closed with explanatory comments (no code change needed).


Fixes #11 — camelCase resource URI goto

ResourceIndex.getFileByUri() reconstructed the resource class path with WordUtils.capitalizeFully(path, {'/','-'}), which lower-cases every character after the first of each segment. A camelCase URI such as app://self/blogPosting therefore resolved to Blogposting.php instead of BlogPosting.php, so goto silently failed.

  • Switched to WordUtils.capitalize(...), which upper-cases only the first letter of each / or - delimited segment and preserves the rest — so both camelCase and hyphenated URIs work.
  • Extracted the pure URI → relative path transformation into UriUtil.toResourceRelativePath(uri, pageContext) and added regression tests.
URI before after
app://self/user User.php User.php
app://self/blog-posting BlogPosting.php BlogPosting.php
app://self/blogPosting Blogposting.php BlogPosting.php

The only behavioral difference between capitalize and capitalizeFully is for inner capitals, i.e. exactly the camelCase case — all-lowercase BEAR URIs are unaffected.

Add #19 — Ray.Aop bound-interceptor navigation

Ray.Aop binding attributes such as #[Transactional] now show a BEAR gutter icon when an interceptor is bound through bindInterceptor(...):

$this->bindInterceptor(
    $this->matcher->any(),
    $this->matcher->annotatedWith(Transactional::class), // annotation
    [TransactionalInterceptor::class],                    // interceptor target
);

The standard PhpStorm declaration behavior remains available:

  • Cmd+B / standard declaration navigation on #[Transactional] goes to the Transactional attribute class.
  • The BEAR gutter icon goes to the bound interceptor class.
  • Navigate > Go to Bound Interceptor provides the same interceptor navigation from the caret.

Implementation notes:

  • InterceptorBindingIndex indexes bindInterceptor(...) calls as annotation FQN → [interceptor FQNs].
  • BoundInterceptorLineMarkerProvider adds the BEAR gutter marker for bound attributes.
  • GoToBoundInterceptorAction provides explicit menu/action navigation without overriding standard declaration navigation.
  • The previous AOP GotoDeclarationHandler was removed so core PhpStorm behavior is preserved.
  • BEAR icons are packaged at 16x16 and 32x32 (@2x) for HiDPI.

Verification checklist

  • ./gradlew test buildPlugin succeeds on the current branch.
  • ./gradlew verifyPlugin succeeds; verifier reports Compatible for PS-251, PS-252, PS-253, PS-261, and PS-262.
  • Existing Resource URI behavior is covered by UriUtilTest, including camelCase, hyphenated, nested, page scheme, template, and scheme-less URI cases.
  • Existing router/settings/resource value tests pass as part of ./gradlew test.
  • Built plugin artifact contains BoundInterceptorLineMarkerProvider, GoToBoundInterceptorAction, InterceptorNavigationUtil, icons/bear.png, and icons/bear@2x.png.
  • Built plugin artifact no longer contains InterceptorGotoDeclarationHandler.
  • Manual PhpStorm smoke test: Cmd+B on #[Transactional] opens the Transactional attribute class.
  • Manual PhpStorm smoke test: BEAR gutter icon on #[Transactional] opens the bound TransactionalInterceptor.
  • Manual PhpStorm smoke test: Navigate > Go to Bound Interceptor opens the bound TransactionalInterceptor.

Verifier notes: the remaining deprecated/internal API warnings are pre-existing (BearSundayProjectComponent and annotation completion), not introduced by this PR.

Follow-ups (out of scope for this PR, tracked in #19)

  • PHPDoc @Annotation form (currently PHP 8 attributes only)
  • reverse navigation (interceptor → bound attributes)
  • PSI-level integration tests via the IntelliJ test fixture

https://claude.ai/code/session_015g4MGXB3hgEjhBi74CLPa9

Summary by CodeRabbit

リリースノート

  • 新機能

    • Ray.Aop 属性(#[Transactional] など)から束縛インターセプタへのナビゲーション機能を追加。ガターアイコンおよび「Go to Bound Interceptor」アクションから直接ジャンプ可能。
    • Resource URI におけるキャメルケース対応を改善。
  • バグ修正

    • キャメルケースを含む Resource URI での goto 解決失敗を修正。

claude added 2 commits May 30, 2026 03:24
Resource URI goto reconstructed the resource class path with
WordUtils.capitalizeFully(), which lower-cases every character after the
first of each segment. A camelCase URI such as app://self/blogPosting was
therefore resolved to Blogposting.php instead of BlogPosting.php and the
goto silently failed.

Switch to WordUtils.capitalize(), which only upper-cases the first letter
of each '/' or '-' delimited segment and preserves the rest, so both
camelCase and hyphenated URIs resolve correctly. The pure URI -> relative
path transformation is extracted into UriUtil.toResourceRelativePath() and
covered by regression tests.

https://claude.ai/code/session_015g4MGXB3hgEjhBi74CLPa9
Ctrl/Cmd-click on a Ray.Aop binding attribute (e.g. #[Transactional])
now jumps to the interceptor class(es) bound to it in a module via
bindInterceptor().

A new file-based index (InterceptorBindingIndex) scans modules for
bindInterceptor(..., $this->matcher->annotatedWith(X::class),
[Interceptor::class]) calls and maps the annotation FQN to its bound
interceptor FQNs. InterceptorGotoDeclarationHandler resolves the clicked
attribute FQN, looks it up in the index and navigates to the interceptor
classes via PhpIndex.

https://claude.ai/code/session_015g4MGXB3hgEjhBi74CLPa9
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Resource URI 解決を統一、ProjectUtil でのプロジェクトディレクトリ推定を導入し、Ray.Aop の bindInterceptor をインデックス化して属性からバウンドインターセプタへナビゲート可能にした変更群。キャメルケース URI 対応も含む。

Changes

Resource URI 統一と Interceptor Navigation

Layer / File(s) Summary
Resource URI パス変換と ResourceIndex 統合
src/main/java/idea/bear/sunday/util/UriUtil.java, src/main/java/idea/bear/sunday/index/ResourceIndex.java, src/test/java/idea/bear/sunday/util/UriUtilTest.java
UriUtil.toResourceRelativePath() でテンプレート展開とキャメルケース化によりリソース相対パスを生成。ResourceIndex が相対パス決定をこれに委譲し、INDEX_VERSION を 3→4 に更新。テストで app/page スキーム、ハイフン、camelCase、ネストに対応を確認。
Interceptor バインディング索引基盤
src/main/java/idea/bear/sunday/aop/InterceptorBindingIndexUtil.java, src/main/java/idea/bear/sunday/aop/InterceptorBindingExternalizer.java, src/main/java/idea/bear/sunday/aop/InterceptorBindingIndex.java
PHP の bindInterceptor 呼び出しから annotationFQN→interceptorFQN マップを抽出する IndexUtil、List をシリアライズ/デシリアライズする Externalizer、FileBasedIndex 実装で PHP ファイル全体をインデックス化。キーは属性 FQN、値はインターセプタ FQN 配列。
Interceptor ナビゲーション UI
src/main/java/idea/bear/sunday/aop/InterceptorNavigationUtil.java, src/main/java/idea/bear/sunday/aop/BoundInterceptorLineMarkerProvider.java, src/main/java/idea/bear/sunday/aop/GoToBoundInterceptorAction.java
属性クリック位置からインターセプタ FQN を解決するユーティリティ、属性にガターアイコンを表示するラインマーカープロバイダ、"Go to Bound Interceptor" メニューアクション(0 件時エラー、1 件時直接遷移、複数件時選択ポップアップ)を実装。
ProjectUtil.guessProjectDir への置換
src/main/java/idea/bear/sunday/annotation/AnnotationOrAttributeGotoDeclarationHandler.java, src/main/java/idea/bear/sunday/router/RouterGotoDeclarationHandler.java
複数の goto ハンドラで project.getBaseDir()ProjectUtil.guessProjectDir() に置換、null ガードで早期終了。SQL/JSON Schema/Router のファイル探索に統一的に適用。
ドキュメントと拡張登録
CHANGELOG.md, README.md, src/main/resources/META-INF/plugin.xml
CHANGELOG に機能追加(Interceptor Goto)、変更(ProjectUtil 置換)、修正(キャメルケース URI)を記述。README の Current Features に Ray.Aop 属性ナビゲーション機能を追加。plugin.xml に InterceptorBindingIndex の FileBasedIndex、BoundInterceptorLineMarkerProvider、GoToBoundInterceptorAction を登録。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • #11: Camel Case Uri "goto" not work — この PR で UriUtil.toResourceRelativePath() により、キャメルケースを含む Resource URI(例:app://self/blogPosting)の goto 解決が修正され、inner capitals が保持されるようになった。

Poem

🐰 ウサギの足で駆け抜けて
URI のキャメル、凸凹キャッチ
インターセプタへ ぴょん と着地
Aop 属性から、ゴー・トゥ・ゴール!
索引が光を放つ、今この時 ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed タイトルは2つの主要な変更を明確に要約しており、キャメルケースURIの修正と AOP インターセプタ goto 機能の追加を簡潔に説明しています。
Linked Issues check ✅ Passed PR は #11 のキャメルケース URI goto 修正を完全に実装し、UriUtil.toResourceRelativePath で内部の大文字を保持し、回帰テストを追加しています。
Out of Scope Changes check ✅ Passed すべての変更は #11#19 の実装に関連しており、キャメルケース URI 修正、AOP インターセプタ navigation、プロジェクトディレクトリ推定の統一化が含まれます。
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/clever-brahmagupta-HeSkK

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@koriym koriym marked this pull request as ready for review May 30, 2026 03:28
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/main/java/idea/bear/sunday/aop/InterceptorBindingIndexUtil.java (1)

42-42: 💤 Low value

PHP のメソッド名は大文字小文字を区別しないため、比較を大文字小文字非依存にするのが安全です

InterceptorBindingIndexUtil では call.getName()BIND_INTERCEPTOR ("bindInterceptor")matcher.getName()ANNOTATED_WITH ("annotatedWith")String#equals(大文字小文字区別)比較しています(42, 73行目)。PHP はメソッド名が大文字小文字を区別しないため、別表記で呼ばれるとインデックスが取りこぼす可能性があるので、equalsIgnoreCase や正規化(例: toLowerCase(Locale.ROOT))での比較を検討してください。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/idea/bear/sunday/aop/InterceptorBindingIndexUtil.java` at line
42, InterceptorBindingIndexUtil currently compares call.getName() to
BIND_INTERCEPTOR ("bindInterceptor") and matcher.getName() to ANNOTATED_WITH
("annotatedWith") using case-sensitive String#equals; change these comparisons
to be case-insensitive (e.g., use String.equalsIgnoreCase or normalize both
sides with toLowerCase(Locale.ROOT)) so PHP method-name case-variants do not
miss matches — update the comparisons where call.getName() and matcher.getName()
are checked against BIND_INTERCEPTOR and ANNOTATED_WITH respectively.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/idea/bear/sunday/index/ResourceIndex.java`:
- Line 84: The code in ResourceIndex.java uses the deprecated
Project#getBaseDir() when resolving the target file (VirtualFile targetFile =
project.getBaseDir().findFileByRelativePath(relPath)); replace that call by
first calling com.intellij.openapi.project.ProjectUtil.guessProjectDir(project),
then use the returned VirtualFile to call findFileByRelativePath(relPath); also
add null checks for the guessed project dir before calling
findFileByRelativePath to avoid NPEs and handle the case where the project dir
is absent.

---

Nitpick comments:
In `@src/main/java/idea/bear/sunday/aop/InterceptorBindingIndexUtil.java`:
- Line 42: InterceptorBindingIndexUtil currently compares call.getName() to
BIND_INTERCEPTOR ("bindInterceptor") and matcher.getName() to ANNOTATED_WITH
("annotatedWith") using case-sensitive String#equals; change these comparisons
to be case-insensitive (e.g., use String.equalsIgnoreCase or normalize both
sides with toLowerCase(Locale.ROOT)) so PHP method-name case-variants do not
miss matches — update the comparisons where call.getName() and matcher.getName()
are checked against BIND_INTERCEPTOR and ANNOTATED_WITH respectively.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c35fad96-56e5-4242-9fdb-34be70b3a88e

📥 Commits

Reviewing files that changed from the base of the PR and between 96e30ec and 8aaa695.

📒 Files selected for processing (10)
  • CHANGELOG.md
  • README.md
  • src/main/java/idea/bear/sunday/aop/InterceptorBindingExternalizer.java
  • src/main/java/idea/bear/sunday/aop/InterceptorBindingIndex.java
  • src/main/java/idea/bear/sunday/aop/InterceptorBindingIndexUtil.java
  • src/main/java/idea/bear/sunday/aop/InterceptorGotoDeclarationHandler.java
  • src/main/java/idea/bear/sunday/index/ResourceIndex.java
  • src/main/java/idea/bear/sunday/util/UriUtil.java
  • src/main/resources/META-INF/plugin.xml
  • src/test/java/idea/bear/sunday/util/UriUtilTest.java

Comment thread src/main/java/idea/bear/sunday/index/ResourceIndex.java Outdated
claude added 2 commits May 30, 2026 03:39
- Match PHP method names case-insensitively when indexing interceptor
  bindings (bindInterceptor / annotatedWith), since PHP method names are
  case-insensitive
- Replace deprecated Project#getBaseDir() with ProjectUtil.guessProjectDir()
  and guard against a null project dir in ResourceIndex.getFileByUri()

https://claude.ai/code/session_015g4MGXB3hgEjhBi74CLPa9
Follow-up to the CodeRabbit review: replace the deprecated
Project#getBaseDir() with ProjectUtil.guessProjectDir() (plus null guards)
in the router, SQL and JSON Schema goto handlers and in the resource index
filter, so the whole plugin uses the recommended API consistently. Bump the
resource index version accordingly.

https://claude.ai/code/session_015g4MGXB3hgEjhBi74CLPa9
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/main/java/idea/bear/sunday/annotation/AnnotationOrAttributeGotoDeclarationHandler.java (1)

117-119: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

psiManager.findFile の null チェックが欠落しています。

findFilenull を返す可能性があり、null 要素を含む配列を返すと後続のナビゲーション処理で NPE を引き起こす恐れがあります。jsonSchemaGoto(167-169行)では null チェックを行っており、こちらと整合させるべきです。

🛡️ 提案する修正
                 PsiFile psiFile = psiManager.findFile(targetFile);
-                psiElements.add(psiFile);
+                if (psiFile != null) {
+                    psiElements.add(psiFile);
+                }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/idea/bear/sunday/annotation/AnnotationOrAttributeGotoDeclarationHandler.java`
around lines 117 - 119, In AnnotationOrAttributeGotoDeclarationHandler, add a
null-check around the result of psiManager.findFile so you don't add null into
psiElements: after calling psiManager.findFile(targetFile) verify psiFile !=
null and only then call psiElements.add(psiFile); mirror the null-check pattern
used in jsonSchemaGoto to ensure navigation code won’t encounter NPEs when
iterating psiElements.
src/main/java/idea/bear/sunday/router/RouterGotoDeclarationHandler.java (1)

71-72: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

psiManager.findFile の戻り値を null チェックしてください。

findFilenull を返し得るため、nullpsiElements に追加すると返却配列に null 要素が混入し、ナビゲーション時に NPE を招く可能性があります。

🛡️ 提案する修正
             PsiFile pfiFile = psiManager.findFile(targetFile);
-            psiElements.add(pfiFile);
+            if (pfiFile != null) {
+                psiElements.add(pfiFile);
+            }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/idea/bear/sunday/router/RouterGotoDeclarationHandler.java`
around lines 71 - 72, findFile の戻り値を null チェックせずに psiElements に追加しているため null
が混入し NPE を招く可能性があります; 呼び出し箇所の psiManager.findFile(targetFile) の結果を PsiFile
pfiFile で受け取った後に null チェックを行い、非 null のときのみ psiElements.add(pfiFile)
するよう修正してください(つまり PsiFile pfiFile の null 判定を追加してから psiElements へ追加する)。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In
`@src/main/java/idea/bear/sunday/annotation/AnnotationOrAttributeGotoDeclarationHandler.java`:
- Around line 117-119: In AnnotationOrAttributeGotoDeclarationHandler, add a
null-check around the result of psiManager.findFile so you don't add null into
psiElements: after calling psiManager.findFile(targetFile) verify psiFile !=
null and only then call psiElements.add(psiFile); mirror the null-check pattern
used in jsonSchemaGoto to ensure navigation code won’t encounter NPEs when
iterating psiElements.

In `@src/main/java/idea/bear/sunday/router/RouterGotoDeclarationHandler.java`:
- Around line 71-72: findFile の戻り値を null チェックせずに psiElements に追加しているため null が混入し
NPE を招く可能性があります; 呼び出し箇所の psiManager.findFile(targetFile) の結果を PsiFile pfiFile
で受け取った後に null チェックを行い、非 null のときのみ psiElements.add(pfiFile) するよう修正してください(つまり
PsiFile pfiFile の null 判定を追加してから psiElements へ追加する)。

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c21e90c4-fa98-435c-b3f8-b9bfef9c3c70

📥 Commits

Reviewing files that changed from the base of the PR and between 8aaa695 and cc0c7c1.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • src/main/java/idea/bear/sunday/annotation/AnnotationOrAttributeGotoDeclarationHandler.java
  • src/main/java/idea/bear/sunday/aop/InterceptorBindingIndexUtil.java
  • src/main/java/idea/bear/sunday/index/ResourceIndex.java
  • src/main/java/idea/bear/sunday/router/RouterGotoDeclarationHandler.java
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/idea/bear/sunday/aop/InterceptorBindingIndexUtil.java
  • src/main/java/idea/bear/sunday/index/ResourceIndex.java

claude added 4 commits May 30, 2026 04:47
PsiManager#findFile is nullable; sqlGoto and the router goto added its
result to the targets list without a null check, which could put a null
into the returned array and trigger an NPE during navigation. Add the same
null guard already used in jsonSchemaGoto.

https://claude.ai/code/session_015g4MGXB3hgEjhBi74CLPa9
The PSI-level method-name match was made case-insensitive (PHP method
names are case-insensitive), but the cheap text pre-filter still used a
case-sensitive contains("bindInterceptor"), so a lowercase spelling would
be skipped before reaching the matcher. Use containsIgnoreCase to keep the
two consistent.

https://claude.ai/code/session_015g4MGXB3hgEjhBi74CLPa9
- getFileByUri now reads the editor path unconditionally (to compute the
  Page/App context). Guard against EditorImpl#getVirtualFile() returning
  null so the common scheme case can't NPE.
- Fix isValidForIndex test/vendor exclusion: the condition used || so a
  path under /vendor/ (or /tests/) still satisfied the other clause and was
  indexed anyway. Use && so both must be absent for the file to be indexed.

https://claude.ai/code/session_015g4MGXB3hgEjhBi74CLPa9
…rence

PhpAttribute#getFQN() is not part of the API used elsewhere in this plugin
(the existing code resolves FQNs through ClassReference#getFQN()), which
broke the CI build. Resolve the clicked attribute's FQN from its
ClassReference child instead, using only the proven PhpAttributeImpl /
ClassReference#getFQN() APIs. This also makes the lookup key use the exact
same ClassReference#getFQN() call as the indexer, improving key consistency.

https://claude.ai/code/session_015g4MGXB3hgEjhBi74CLPa9
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/idea/bear/sunday/index/ResourceIndex.java`:
- Around line 77-79: The code unsafely casts Editor to EditorImpl to call
getVirtualFile(), risking ClassCastException; replace the cast and use
FileDocumentManager.getInstance().getFile(editor.getDocument()) to obtain the
VirtualFile safely (remove EditorImpl import), and make project root retrieval
consistent by using ProjectUtil.guessProjectDir(project).getPath() (or
consistently use project.getBasePath()) when computing the pageContext path
check so both places use the same project-root method; update references to
EditorImpl, getVirtualFile(), FileDocumentManager, project.getBasePath(), and
ProjectUtil.guessProjectDir accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 686b00c4-bdb4-4655-baa7-cd9a76618dbb

📥 Commits

Reviewing files that changed from the base of the PR and between 03ceb82 and 096ee58.

📒 Files selected for processing (2)
  • src/main/java/idea/bear/sunday/aop/InterceptorGotoDeclarationHandler.java
  • src/main/java/idea/bear/sunday/index/ResourceIndex.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/idea/bear/sunday/aop/InterceptorGotoDeclarationHandler.java

Comment thread src/main/java/idea/bear/sunday/index/ResourceIndex.java Outdated
claude and others added 2 commits May 30, 2026 13:42
Casting Editor to EditorImpl to call getVirtualFile() risks a
ClassCastException for non-default editor implementations (e.g. injected
editors), and #11 widened the exposure by running it for every URI. Obtain
the file via FileDocumentManager.getInstance().getFile(editor.getDocument())
instead, and derive the Page/App context from the same
ProjectUtil.guessProjectDir() root used for file resolution so both use one
project-root method.

https://claude.ai/code/session_015g4MGXB3hgEjhBi74CLPa9
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/idea/bear/sunday/aop/GoToBoundInterceptorAction.java`:
- Around line 30-36: actionPerformed() in GoToBoundInterceptorAction lacks a
dumb-mode guard: before calling findInterceptorTargets (which queries
InterceptorBindingIndex/FileBasedIndex) check DumbService.isDumb(project) and
bail out (or show a notification) when dumb so you don't query indices during
reindexing; locate the method actionPerformed in class
GoToBoundInterceptorAction and add the same dumb-mode guard used in update() to
prevent calling findInterceptorTargets while indices are unavailable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 16eb74e3-9053-444b-84ba-a21130b4ad8d

📥 Commits

Reviewing files that changed from the base of the PR and between 096ee58 and 5476360.

⛔ Files ignored due to path filters (2)
  • src/main/resources/icons/bear.png is excluded by !**/*.png
  • src/main/resources/icons/bear@2x.png is excluded by !**/*.png
📒 Files selected for processing (8)
  • CHANGELOG.md
  • README.md
  • src/main/java/idea/bear/sunday/aop/BoundInterceptorLineMarkerProvider.java
  • src/main/java/idea/bear/sunday/aop/GoToBoundInterceptorAction.java
  • src/main/java/idea/bear/sunday/aop/InterceptorBindingIndex.java
  • src/main/java/idea/bear/sunday/aop/InterceptorNavigationUtil.java
  • src/main/java/idea/bear/sunday/index/ResourceIndex.java
  • src/main/resources/META-INF/plugin.xml
✅ Files skipped from review due to trivial changes (4)
  • src/main/java/idea/bear/sunday/aop/InterceptorNavigationUtil.java
  • src/main/java/idea/bear/sunday/aop/BoundInterceptorLineMarkerProvider.java
  • README.md
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/idea/bear/sunday/aop/InterceptorBindingIndex.java
  • src/main/java/idea/bear/sunday/index/ResourceIndex.java

Comment thread src/main/java/idea/bear/sunday/aop/GoToBoundInterceptorAction.java
@koriym
Copy link
Copy Markdown
Member Author

koriym commented May 31, 2026

@coderabbitai No outstanding blockers. Please resolve all open conversations and approve this PR.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 31, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# List all review threads on PR `#20` to find open ones authored by coderabbitai
gh api graphql -f query='
{
  repository(owner: "bearsunday", name: "idea-php-bearsunday-plugin") {
    pullRequest(number: 20) {
      reviewThreads(first: 50) {
        nodes {
          id
          isResolved
          comments(first: 1) {
            nodes {
              author { login }
              body
              databaseId
            }
          }
        }
      }
    }
  }
}'

Length of output: 9908



@koriym All three open conversations are already resolved. Approving the PR now! 🎉

(╯°□°)╯ ♪ ~ ᗜ˰ᗜ ♪

[approve]

@koriym
Copy link
Copy Markdown
Member Author

koriym commented May 31, 2026

@coderabbitai resolve

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 31, 2026

✅ Actions performed

Comments resolved and changes approved.

Copy link
Copy Markdown
Member Author

koriym commented May 31, 2026

Review: bound interceptor gutter navigation (5476360, 107b074)

A few findings from reviewing the new aop gutter/action code, complementing CodeRabbit's. Nothing breaks the feature, but the first one shows up in the IDE log.

🔴 LineMarker is anchored on a non-leaf element

BoundInterceptorLineMarkerProvider#collectNavigationMarkers builds the marker on the ClassReference itself (createLineMarkerInfo(classReference)). IntelliJ requires line markers to be registered on leaf elements only; anchoring on a composite element makes the daemon emit LOG.error("Performance warning: LineMarker is supposed to be registered for leaf elements only …") every time such an attribute is highlighted (surfaces as an IDE internal error in dev/internal mode).

Fix: act only on a leaf and anchor the marker there, picking a single leaf so multi-token names (#[Foo\Bar]) don't get duplicate icons:

if (element.getFirstChild() != null) return;                        // leaf only
ClassReference ref = InterceptorNavigationUtil.findAttributeClassReference(element);
if (ref == null || PsiTreeUtil.getDeepestFirst(ref) != element) return;
...
    .createLineMarkerInfo(element);                                  // anchor on the leaf

🟠 GoToBoundInterceptorAction doesn't override getActionUpdateThread()

update() reads PSI (findElementAtCaret). Since 2022.3 an AnAction must declare its update thread; without it, 2025.1 logs a warning and runs update() (incl. PSI access) on the EDT. update() only sets the presentation, so BGT is appropriate:

@Override
public ActionUpdateThread getActionUpdateThread() {
    return ActionUpdateThread.BGT;
}

🟡 LineMarker queries the index twice

collectNavigationMarkers calls findInterceptorFqns(...) and then findInterceptorTargets(...), and the latter calls findInterceptorFqns again — two FileBasedIndex lookups per attribute. Fetch the FQNs once and resolve the targets from that list.

🟡 Redundant cast

NavigationGutterIconBuilder#createLineMarkerInfo already returns RelatedItemLineMarkerInfo<PsiElement>, so the LineMarkerInfo<PsiElement> variable + (RelatedItemLineMarkerInfo<?>) cast can be dropped.

✅ Looks good

  • Dumb-mode guarded in findInterceptorFqns, the line marker, and (now) the action.
  • RelatedItemLineMarkerProvider (slow pass) is the right place for the index query.
  • getName() / getIcon() provided → respects the Gutter Icons settings toggle.
  • Index and lookup both key off ClassReference#getFQN() + normalizeFqn, so keys stay consistent.

Only 🔴 is worth addressing before merge (it pollutes the IDE log); the rest are polish.


Generated by Claude Code

Copy link
Copy Markdown
Member Author

koriym commented May 31, 2026

01a8f8e resolves all four points from my review:

  • 🔴 the marker is now anchored on the class-reference leaf via findLineMarkerAnchor() (no more "registered for leaf elements only" log error)
  • 🟠 getActionUpdateThread()BGT
  • 🟡 single index lookup through the new findInterceptorTargets(List<String>, Project) overload
  • 🟡 redundant LineMarkerInfo cast removed

LGTM. 👍


Generated by Claude Code

@koriym koriym merged commit d642347 into master May 31, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Camel Case Uri "goto" not work

2 participants