| name | refactor |
| description | Refactor existing ABAP code to Clean ABAP style without changing behavior. Use when the user asks to refactor, clean up, modernize, or tidy ABAP code. Applies the rule set in ../CLAUDE.md in deterministic passes (naming, declaration, expression, method shape, error, class) and asks before writing back via MCP. Targets modern ABAP only — BTP ABAP Environment or S/4HANA on-prem in the ABAP Cloud development model. |
| license | Apache-2.0 |
clean-abap:refactor
Refactor existing ABAP code to conform to the Clean ABAP rule set in ../CLAUDE.md (relative to this skill's directory).
What this command does
You are refactoring ABAP source code to bring it into compliance with the Clean ABAP rule set. Style and structure only — business logic stays identical. If a change would alter what the code does, you do not make it; you flag it instead.
Inputs
Accept any of the following. If nothing is provided, ask which target the user wants.
- A code block pasted into the conversation (the most reliable path today)
- An ABAP object name — only works if a community MCP exposes source reads. The official
SAPSE.adt-vscode 1.0 MCP does not.
- A package name — only works with a community MCP that exposes repository search and source reads. Refactor object by object, never as a single bulk change.
If only the official MCP is connected, ask the user to paste the source from ADT in VS Code; then paste the refactored version back manually.
Procedure
- Load the rule set. Read every
## RULE: block in ../CLAUDE.md. Those are the only refactoring targets.
- Get the source. If pasted inline, use it. If only an object name was given, attempt source-read via whichever MCP is connected; if no MCP exposes source reads, ask the user to paste it from ADT. The official
SAPSE.adt-vscode 1.0 MCP does not have a source-read tool.
- Run the review first. Internally, perform the same analysis as
/clean-abap:review. Use the prioritised list as your refactor plan.
- Refactor in passes, in this order. Do not skip ahead:
- Naming pass — apply
use-problem-domain-names, no-magic-numbers-or-literals
- Declaration pass — apply
prefer-inline-declarations, no-default-key-on-internal-tables
- Expression pass — apply
use-string-templates-not-concatenate, prefer-is-not-initial-over-negation, prefer-case-over-long-if-elseif, use-table-expressions-not-read-table-plus-sy-subrc
- Method shape pass — apply
methods-do-one-thing-and-stay-small, at-most-three-importing-parameters, prefer-returning-over-exporting
- Error pass — apply
class-based-exceptions-not-sy-subrc, catch-specific-exceptions-not-cx-root
- Class shape pass — apply
final-classes-and-private-members-by-default, prefer-new-over-create-object
- Preserve behaviour. After every pass, mentally diff the program logic. If you cannot prove a change is behaviour-preserving (e.g. a refactor would change exception types caught upstream, would change SELECT result order, would alter authority checks), stop and ask instead of guessing.
- Show the diff before writing back. Produce a per-method or per-section before/after diff. Annotate every change with the rule name that motivated it.
- Ask for confirmation before writing back via MCP. Explicit confirmation per object — not a blanket yes for a package. After write-back, confirm the object activated cleanly.
Behaviour preservation — non-negotiable
These changes are out of scope for this command — they alter behaviour:
- Changing exception classes raised by a public method (callers catch them)
- Changing the order or set of database rows returned by a SELECT
- Removing authority checks, even if they look redundant
- Inlining or extracting code that crosses a
COMMIT WORK / ROLLBACK WORK
- Changing the public signature of a method except
EXPORTING → RETURNING for a single output where no caller relies on IS SUPPLIED
If a Clean ABAP rule appears to require one of the above, flag it in the report and skip the change. Behaviour change belongs in a separate task, not in a style refactor.
Output format
# Clean ABAP Refactor — <OBJECT NAME>
## Plan
1. <rule-name> — <count> occurrences
2. <rule-name> — <count> occurrences
...
## Changes
### <method or section name>
**Rule:** <rule-name>
**Before:**
` ` `abap
<original>
` ` `
**After:**
` ` `abap
<refactored>
` ` `
**Rationale:** <one sentence, no longer>
(repeat per change)
## Behaviour-preserving check
- [ ] No public method signature changed (except EXPORTING→RETURNING for single output)
- [ ] No exception classes added or removed from public methods
- [ ] No SELECTs reordered or filtered differently
- [ ] No authority checks removed
- [ ] No statements moved across COMMIT/ROLLBACK boundaries
## Skipped
<rule-name> at <location> — <one-line reason it would have changed behaviour>
## Confirmation
Write these changes back to <OBJECT NAME> via MCP? (yes / no / per-method)
Hard rules for this command
- Style and structure only. Never change what the code does.
- One object at a time. No silent batching across a package.
- Confirm before write-back. Always. Even if the user said yes for a previous object.
- Activate after writing. If activation fails, report the error and revert the write. Do not patch through activation errors.
- No rule-by-rule chatter. Group changes by method or section; one diff per change.
- If a Clean ABAP rule conflicts with the ABAP Cloud / RAP overlay, the overlay wins. Apply the overlay version of the rule. Note the conflict in the report.