Skip to content

fix: FieldsTo* resolves caret class instead of first class in file#727

Merged
tangcent merged 1 commit into
masterfrom
fix/field-format-targets-caret-class
Jul 5, 2026
Merged

fix: FieldsTo* resolves caret class instead of first class in file#727
tangcent merged 1 commit into
masterfrom
fix/field-format-targets-caret-class

Conversation

@tangcent

@tangcent tangcent commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Problem

Right-clicking inside a data class in the editor (e.g. SalesReportVO declared after AnalyticsController in the same file) and selecting ToJson / ToJson5 / ToProperties formatted the wrong class — the controller, not the data class under the caret.

Root cause

FieldFormatAction.findPsiClass relied on CommonDataKeys.PSI_ELEMENT, which is populated by the Project View, not by the editor context-menu. With PSI_ELEMENT null, resolution fell through to:

PsiTreeUtil.findChildOfType(file, PsiClass::class.java)

which always returns the first top-level class in the file regardless of caret position. Any file with multiple top-level classes (controller + sibling VO/DTO classes, common in sample projects) hit this bug.

Fix

  • SelectedHelper.resolveSelection — added a caret-based resolution step (between the PSI_ELEMENT check and the PSI_FILE fallback) that resolves the PSI element at the caret offset and walks up to the nearest PsiMethod/PsiClass. Benefits every caller of SelectedHelper (export actions, field-format actions).
  • FieldFormatAction — dropped the bespoke findPsiClass and now uses SelectedHelper.resolveSelection(e)?.psiClass(), matching the convention used by ChannelExportAction/ExportApiAction.

Behavior

Right-clicking inside SalesReportVO (or any VO/DTO class) and choosing ToJson now correctly formats that data class, not AnalyticsController.

Tests

Added 5 cases to SelectedHelperTest covering caret-based resolution in a multi-class file:

Test Verifies
testResolveSelectionFromCaretInNonFirstClass Caret in SalesReportVO → resolves SalesReportVO, not AnalyticsController (the regression test for this bug)
testResolveSelectionFromCaretInFirstClass Caret in the first class still resolves correctly
testResolveSelectionFromCaretInMethodResolvesContainingClass Caret in a method walks up to its containing class
testResolveSelectionFallsBackToFileWhenCaretResolvesNothing EOF caret → falls through to PSI_FILE branch (preserves existing behaviour)
testPsiElementTakesPrecedenceOverEditorCaret PSI_ELEMENT wins over caret (guards documented precedence)

All 21 SelectedHelperTest cases pass.

Right-clicking inside a data class in the editor (e.g. SalesReportVO
declared after AnalyticsController in the same file) and selecting
ToJson/ToJson5/ToProperties formatted the wrong class — the controller,
not the data class under the caret.

Root cause: FieldFormatAction.findPsiClass relied on CommonDataKeys.
PSI_ELEMENT, which is populated by the Project View, not by the editor
context-menu. With PSI_ELEMENT null, resolution fell through to
PsiTreeUtil.findChildOfType(file, PsiClass), which always returns the
first top-level class in the file regardless of caret position.

Fix:
- SelectedHelper.resolveSelection: add a caret-based resolution step
  (between the PSI_ELEMENT check and the PSI_FILE fallback) that resolves
  the PSI element at the caret offset and walks up to the nearest
  PsiMethod/PsiClass. This benefits every caller of SelectedHelper
  (export actions, field-format actions).
- FieldFormatAction: drop the bespoke findPsiClass and use
  SelectedHelper.resolveSelection(e)?.psiClass(), matching the
  convention used by ChannelExportAction/ExportApiAction.

Tests: add 5 cases to SelectedHelperTest covering caret-based
resolution in a multi-class file (non-first class, first class, method
body, EOF fallback, PSI_ELEMENT precedence).
@github-actions github-actions Bot added the type: bug Something isn't working label Jul 5, 2026
@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

📦 Plugin has been packaged for this PR. You can download easy-api-3.1.5.252.0.zip from the GitHub Actions workflow run by clicking on the "Artifacts" dropdown.

@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 71.42857% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.997%. Comparing base (411ee5c) to head (60062ec).

Files with missing lines Patch % Lines
...om/itangcent/easyapi/ide/support/SelectedHelper.kt 71.429% 0 Missing and 2 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@              Coverage Diff              @@
##            master      #727       +/-   ##
=============================================
+ Coverage   63.989%   63.997%   +0.007%     
=============================================
  Files          363       363               
  Lines        20880     20887        +7     
  Branches      5130      5133        +3     
=============================================
+ Hits         13361     13367        +6     
  Misses        5645      5645               
- Partials      1874      1875        +1     
Flag Coverage Δ
unittests 63.997% <71.429%> (+0.007%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...om/itangcent/easyapi/ide/support/SelectedHelper.kt 50.000% <71.429%> (+2.941%) ⬆️

... and 1 file with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 411ee5c...60062ec. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tangcent tangcent merged commit 03395d4 into master Jul 5, 2026
12 checks passed
@tangcent tangcent deleted the fix/field-format-targets-caret-class branch July 5, 2026 08:21
@github-actions github-actions Bot mentioned this pull request Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant