Add linter and guard, apply fixes and suppress by scope#49
Add linter and guard, apply fixes and suppress by scope#49WalterWoshid wants to merge 2 commits intoj-plugins:mainfrom
Conversation
- Run mago lint and guard with analyze; merge results into annotations - Apply single fix or apply-all by safety (safe / potentially unsafe / unsafe) - After apply: clear problem cache and restart daemon to avoid stale fixes when applying again while Mago is re-analyzing (3–5 s) - Format after fix: run Mago formatter when the option is enabled in settings - Mago: Suppress for statement, function, method, class (submenu when multiple); always show "for statement" so narrowest scope is available - Intention preview (Ctrl+Q) for apply and suppress - Remove ReformatFileAction; fix DaemonCodeAnalyzer.restart deprecation
|
This Pull Request also makes #47 obsolete, because it is included. |
654e856 to
3a848ce
Compare
xepozz
left a comment
There was a problem hiding this comment.
Thanks for improving the plugin, but let's make it a bit clear first
src/main/kotlin/com/github/xepozz/mago/qualityTool/MagoMessageProcessor.kt
Show resolved
Hide resolved
src/main/kotlin/com/github/xepozz/mago/qualityTool/MagoMessageProcessor.kt
Show resolved
Hide resolved
| val charStart = String(bytes.copyOf(byteStart), Charsets.UTF_8).length | ||
| val charEnd = String(bytes.copyOf(byteEnd), Charsets.UTF_8).length | ||
| return charStart until charEnd | ||
| private fun runExtraTool( |
There was a problem hiding this comment.
please create a separate class containing all this run logic
together with the lines above that decide to run additional tools
this message processor should not run additional tools.
in general, "quality tools" API looks overcomplicated to implement mago features. you partially implemented some kind of raw quality tool, so I'd suggest you to complete this step and remove all "quality tool" api. would you like to do it?
| } | ||
| } | ||
| } catch (_: Exception) { | ||
| // Ignore errors for individual tools |
| import com.jetbrains.php.lang.psi.elements.Method | ||
|
|
||
| class MarkIgnoreAction(val code: String, val line: Int) : IntentionAction { | ||
| class MagoIgnoreSubmenuAction( |
There was a problem hiding this comment.
please keep 1 class in 1 file
| else -> 0 | ||
| } | ||
|
|
||
| fun MagoEdit.maxSafetyLevel(): Int = replacements.maxOfOrNull { safetyLevel(it.safety) } ?: 0 |
There was a problem hiding this comment.
put maxSafetyLevel in the MagoEdit instead
| val maxSafetyValue = edits.flatMap { it.replacements }.maxOfOrNull { safetyLevel(it.safety) } ?: 0 | ||
| val safetySuffix = when (maxSafetyValue) { | ||
| 2 -> " (unsafe)" | ||
| 1 -> " (potentially unsafe)" | ||
| else -> "" | ||
| } | ||
| return when { | ||
| !fixDescription.isNullOrBlank() -> "Mago: " + fixDescription.trim() + safetySuffix | ||
| isApplyAll -> "Mago: Apply all suggested fixes$safetySuffix" | ||
| else -> "Mago: Apply suggested fix$safetySuffix" | ||
| } | ||
| } |
|
|
||
| /** Clear cached problems for this file so no fix is offered until the next Mago run. */ | ||
| fun clearProblemCache(file: PsiFile) { | ||
| file.putUserData(MAGO_HTML_LAST_PROBLEMS, null) |
There was a problem hiding this comment.
add another function where you put and read there data
| file.putUserData(MAGO_HTML_LAST_PROBLEMS, problems) | ||
| } | ||
|
|
||
| private fun formatGroupedHtmlMessage(problems: List<MagoProblemDescription>): String { |
| return AnnotationResult(problems) | ||
| } | ||
|
|
||
| override fun apply(file: PsiFile, annotationResult: AnnotationResult, holder: AnnotationHolder) { |
|
Thanks for the review, will do that tommorow :) |
Mago inspection now runs lint and guard together with analyze and shows all results in the editor. You can apply Mago autofixes from annotations and suppress issues by statement, function, method, or class. Fixes and suppress actions support intention preview (Ctrl+Q).
Changes
Linter and guard – When enabled in settings, the pipeline runs
mago lintandmago guardin addition to analyze and merges problems into the same annotations. Lint and guard issues get the same apply-fix and suppress quick fixes as analyze.Better descriptions

Apply fix – Apply a single Mago autofix from the problem annotation (Alt+Enter). Fix text uses issue help or message, prefixed with "Mago: ". Before there was a global "Mago: fix the whole file", which only ran the formatter. This has been removed.

Apply all by safety – Submenus: "Fix all (safe only)", "Fix all (potentially unsafe)", "Fix all (unsafe)". Each applies only that tier; apply-all uses in-memory edits (no CLI run) so undo works.

Mago: Suppress – Quick fix to add

@mago-ignore category:codewith options: for statement, for function, for method, for class. Submenu when multiple apply. Same-category codes merged into one comment.Format after fix option - Runs the formatter after applying a fix.

Platform – Target PhpStorm (PS) 2025.3.2. Remove ReformatFileAction.
Some known bugs/problems/missing stuff
The edits are out of sync if Mago is still analyzing after applying an edit. This could be suppressed by removing all annotations until its done analyzing (ugly) or adjusting the edit positions (too much work) or displaying a warning "Please wait for Mago to finish before applying more edits"
Sometimes, not sure how to reproduce, the annotations are out of place until Mago is done analyzing.
When "format after fix" is run, then hitting the Undo action, PhpStorm asks "Undo Reload from Disk?" which is a slight inconvenience, because the formatter is ran externally. This could be solved by applying the fix on a temporary file, running the formatter on that temporary file, then applying the changes to the editor, without needing 2 actions at once.
Suppressing via
@mago-ignoreon a method or class that already has a PHPDoc will add a second PHPDoc, this should be fixed.