ADFA-4613: Surround with try/catch code action#1524
Conversation
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
📝 Walkthrough
WalkthroughAdds a Kotlin code action that wraps selected editor lines in a ChangesSurround with try/catch
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant KotlinCodeActionsMenu
participant SurroundWithTryCatchAction
participant computeSurroundWithTryCatchEdit
participant languageClient
KotlinCodeActionsMenu->>SurroundWithTryCatchAction: expose action
SurroundWithTryCatchAction->>computeSurroundWithTryCatchEdit: pass selected lines and editor text
computeSurroundWithTryCatchEdit-->>SurroundWithTryCatchAction: return TextEdit
SurroundWithTryCatchAction->>languageClient: performCodeAction with DocumentChange
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/utils/SurroundWithTryCatch.kt (1)
28-38: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueDerive the block indentation token from the surrounding code.
The implementation hardcodes
\tfor the added block depth. If the user's codebase uses spaces (e.g.,baseIndentconsists of spaces), this creates a mix of spaces and tabs (e.g.,\te.printStackTrace()). While the follow-up formatter might clean this up, inferring the indent token ensures the raw text edit remains consistent in case the formatter is unavailable or fails.♻️ Proposed refactor to dynamically infer indentation
val baseIndent = selected.first(String::isNotBlank).takeWhile { it == ' ' || it == '\t' } - val body = selected.joinToString("\n") { if (it.isBlank()) it else "\t$it" } + val indentToken = if (baseIndent.startsWith(" ")) " " else "\t" + val body = selected.joinToString("\n") { if (it.isBlank()) it else "$indentToken$it" } val newText = buildString { append(baseIndent).append("try {\n") append(body).append('\n') append(baseIndent).append("} catch (e: Exception) {\n") - append(baseIndent).append("\te.printStackTrace()\n") + append(baseIndent).append(indentToken).append("e.printStackTrace()\n") append(baseIndent).append("}") }🤖 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 `@lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/utils/SurroundWithTryCatch.kt` around lines 28 - 38, Update the indentation logic in the newText builder to derive the block indentation token from the surrounding code instead of hardcoding tab characters. Use the indentation style represented by baseIndent when indenting body lines and the catch statement, while preserving the existing try/catch structure and relative nesting.
🤖 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.
Nitpick comments:
In
`@lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/utils/SurroundWithTryCatch.kt`:
- Around line 28-38: Update the indentation logic in the newText builder to
derive the block indentation token from the surrounding code instead of
hardcoding tab characters. Use the indentation style represented by baseIndent
when indenting body lines and the catch statement, while preserving the existing
try/catch structure and relative nesting.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 499f9ecd-3320-4fb2-845e-d5c61d16d8fa
📒 Files selected for processing (6)
idetooltips/src/main/java/com/itsaky/androidide/idetooltips/TooltipTag.ktlsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/KotlinCodeActionsMenu.ktlsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/actions/SurroundWithTryCatchAction.ktlsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/utils/SurroundWithTryCatch.ktlsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/utils/SurroundWithTryCatchTest.ktresources/src/main/res/values/strings.xml
Summary
Adds a Surround with try/catch code action to the Kotlin K2 LSP. On a selection in the editor's "Code actions" menu, it wraps the selected lines in:
Jira: ADFA-4613 (subtask of ADFA-3317, Integrate K2 compiler with LSP)
Approach
AddThrowsAction). The action operates on the current selection; with no selection it wraps the current line.computeSurroundWithTryCatchEdit(text, startLine, endLine)computes a single whole-line replaceTextEdit(columns ignored, matchingCommentLineAction). It computes indentation itself, so the result is correct even if the follow-up formatter is unavailable.SurroundWithTryCatchAction : BaseKotlinCodeActionreads the editor selection, calls the helper, and routes the edit throughlanguageClient.performCodeAction(...)withCommand.CMD_FORMAT_CODE, mirroringAddImportAction. Registered inKotlinCodeActionsMenu.Fixed
catch (e: Exception)with ane.printStackTrace()body. Out of scope (deliberately):@Throws/exception-type inference, a diagnostic-triggered variant, PSI statement-snapping, and surround-with for other constructs.Changes
lsp/kotlin/.../utils/SurroundWithTryCatch.kt- pure edit helper (new)lsp/kotlin/.../actions/SurroundWithTryCatchAction.kt- the code action (new)lsp/kotlin/.../KotlinCodeActionsMenu.kt- register the actionidetooltips/.../TooltipTag.kt- tooltip tag constantresources/.../values/strings.xml-action_surround_with_try_catchstringTesting
SurroundWithTryCatchTest, 5 cases: single line, indented multi-line block, blank-line preservation, whitespace-only no-op, out-of-range guards), asserting exactnewTextandRangeincluding computed indices.:lsp:kotlin:testV7DebugUnitTest-> 5/5 pass, no regressions..ktfile, run "Surround with try/catch" from the Code actions menu, confirm the block is wrapped and reindented.