Skip to content

Commit

Permalink
Add inspection to replace component reference with full definition (#20)
Browse files Browse the repository at this point in the history
* resolve and show documentation for field and group

* remove unused import

* Add Inspection to replace component reference with full definition

* remove unused imports

---------

Co-authored-by: Dan Timofte <dantimofte@proton.me>
  • Loading branch information
dantimofte and Dan Timofte authored Oct 5, 2024
1 parent 506d922 commit e3a1bde
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 17 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@
- v0.0.1 Add tag number next to the field name
- v0.1.0 Add type next to the field name
- v0.2.0 Add possibility to ctrl/cmd + click on the component name to navigate to the definition
- v0.2.0 when mouse hovering over a component name, display the component definition
- v0.2.0 Mouse hovering over a component name will display the component definition
- v0.3.0 Cmd click for fields and groups to go to the field definition
- v0.3.0 Mouse hovering over a field or group name will display the field definition
- v0.3.0 Add Inspection to replace component reference with the full component definition
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
# quickfix-spec

![Build](https://github.com/dantimofte/quickfix-spec/workflows/Build/badge.svg)
[![Version](https://img.shields.io/jetbrains/plugin/v/MARKETPLACE_ID.svg)](https://plugins.jetbrains.com/plugin/MARKETPLACE_ID)
[![Downloads](https://img.shields.io/jetbrains/plugin/d/MARKETPLACE_ID.svg)](https://plugins.jetbrains.com/plugin/MARKETPLACE_ID)
[![Version](https://img.shields.io/jetbrains/plugin/v/MARKETPLACE_ID.svg)](https://plugins.jetbrains.com/plugin/25332-quickfix-xml-spec)
[![Downloads](https://img.shields.io/jetbrains/plugin/d/MARKETPLACE_ID.svg)](https://plugins.jetbrains.com/plugin/25332-quickfix-xml-spec)

## Template ToDo list
- [x] Create a new [IntelliJ Platform Plugin Template][template] project.
- [x] Get familiar with the [template documentation][template].
- [ ] Adjust the [pluginGroup](./gradle.properties) and [pluginName](./gradle.properties), as well as the [id](./src/main/resources/META-INF/plugin.xml) and [sources package](./src/main/kotlin).
- [ ] Adjust the plugin description in `README` (see [Tips][docs:plugin-description])
- [ ] Review the [Legal Agreements](https://plugins.jetbrains.com/docs/marketplace/legal-agreements.html?from=IJPluginTemplate).
- [ ] [Publish a plugin manually](https://plugins.jetbrains.com/docs/intellij/publishing-plugin.html?from=IJPluginTemplate) for the first time.
- [ ] Set the `MARKETPLACE_ID` in the above README badges. You can obtain it once the plugin is published to JetBrains Marketplace.
- [ ] Set the [Plugin Signing](https://plugins.jetbrains.com/docs/intellij/plugin-signing.html?from=IJPluginTemplate) related [secrets](https://github.com/JetBrains/intellij-platform-plugin-template#environment-variables).
- [ ] Set the [Deployment Token](https://plugins.jetbrains.com/docs/marketplace/plugin-upload.html?from=IJPluginTemplate).
- [ ] Click the <kbd>Watch</kbd> button on the top of the [IntelliJ Platform Plugin Template][template] to be notified about releases containing new features and fixes.
- [x] Adjust the [pluginGroup](./gradle.properties) and [pluginName](./gradle.properties), as well as the [id](./src/main/resources/META-INF/plugin.xml) and [sources package](./src/main/kotlin).
- [x] Adjust the plugin description in `README` (see [Tips][docs:plugin-description])
- [x] Review the [Legal Agreements](https://plugins.jetbrains.com/docs/marketplace/legal-agreements.html?from=IJPluginTemplate).
- [X] [Publish a plugin manually](https://plugins.jetbrains.com/docs/intellij/publishing-plugin.html?from=IJPluginTemplate) for the first time.
- [x] Set the `MARKETPLACE_ID` in the above README badges. You can obtain it once the plugin is published to JetBrains Marketplace.
- [x] Set the [Plugin Signing](https://plugins.jetbrains.com/docs/intellij/plugin-signing.html?from=IJPluginTemplate) related [secrets](https://github.com/JetBrains/intellij-platform-plugin-template#environment-variables).
- [x] Set the [Deployment Token](https://plugins.jetbrains.com/docs/marketplace/plugin-upload.html?from=IJPluginTemplate).
- [x] Click the <kbd>Watch</kbd> button on the top of the [IntelliJ Platform Plugin Template][template] to be notified about releases containing new features and fixes.

<!-- Plugin description -->
This Plugin is going to make it easier to work with the QuickFix XML Specification.
Expand All @@ -35,7 +35,7 @@ This Plugin is going to make it easier to work with the QuickFix XML Specificati

- Using JetBrains Marketplace:

Go to [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/MARKETPLACE_ID) and install it by clicking the <kbd>Install to ...</kbd> button in case your IDE is running.
Go to [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/25332-quickfix-xml-spec) and install it by clicking the <kbd>Install to ...</kbd> button in case your IDE is running.

You can also download the [latest release](https://plugins.jetbrains.com/plugin/MARKETPLACE_ID/versions) from JetBrains Marketplace and install it manually using
<kbd>Settings/Preferences</kbd> > <kbd>Plugins</kbd> > <kbd>⚙️</kbd> > <kbd>Install plugin from disk...</kbd>
Expand Down
6 changes: 1 addition & 5 deletions src/main/java/ac/quant/quickfixspec/common/PsiUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@ public static boolean isTagDeclaration(XmlAttributeValue valueElement) {

final String parentTagName = parentTag.getName();

if (DEFINITION_GROUP_NAME.containsValue(parentTagName)) {
return true;
}

return false;
return DEFINITION_GROUP_NAME.containsValue(parentTagName);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package ac.quant.quickfixspec.inspections;

import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.SmartPointerManager;
import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;

import static ac.quant.quickfixspec.common.PsiUtils.*;

public class ReplaceWithDefinitionInspection extends LocalInspectionTool {

@Override
public @NotNull PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
return new PsiElementVisitor() {
@Override
public void visitElement(@NotNull PsiElement element) {
if (isNotComponentTagReference(element)) {
return;
}

final XmlTag rootTag = getRootTag(element);
final XmlTag tag = (XmlTag) element;
if (rootTag == null) {
return;
}

final String componentName = tag.getAttributeValue("name");


XmlTag definition = findDefinition(componentName, tag.getName(), rootTag);
if (definition != null) {
holder.registerProblem(tag, "Replace with definition", new ReplaceWithDefinitionQuickFix(definition));
}
}
};
}

private boolean isNotComponentTagReference(@NotNull PsiElement element) {
if (!(element instanceof XmlTag tag)) {
return true;
}

final XmlTag parentTag = tag.getParentTag();
if (parentTag == null) {
return true;
}

if (parentTag.getName().equals("components")) {
return true;
}

// if the tag is not self-closing that means it is a definition
if (tag.getSubTags().length > 0) {
return true;
}

return !tag.getName().equals("component");
}

private static class ReplaceWithDefinitionQuickFix implements LocalQuickFix {
@SafeFieldForPreview
private final SmartPsiElementPointer<XmlTag> definitionPointer;

ReplaceWithDefinitionQuickFix(XmlTag definition) {
this.definitionPointer = SmartPointerManager.createPointer(definition);
}

@Override
public @NotNull String getName() {
return "Replace with definition";
}

@Override
public @NotNull String getFamilyName() {
return getName();
}

@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) throws IncorrectOperationException {
// Get the <component> tag that is to be replaced
XmlTag tagToReplace = (XmlTag) descriptor.getPsiElement();

// Retrieve the full definition of the <component> from the pointer
XmlTag definition = definitionPointer.getElement();

if (definition != null) {
// Create a copy of the definition tag to be inserted
XmlTag newTag = (XmlTag) definition.copy();

// Replace the original <component> tag with the full definition
tagToReplace.replace(newTag);
}
}
}
}
1 change: 1 addition & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
</extensions>

<extensions defaultExtensionNs="com.intellij">
<localInspection displayName="Expand component" groupName="Quickfix spec" language="XML" implementationClass="ac.quant.quickfixspec.inspections.ReplaceWithDefinitionInspection"/>
<editorFloatingToolbarProvider implementation="ac.quant.quickfixspec.toolbar.QuickfixFloatingToolbar"/>
<psi.referenceContributor language="XML" implementation="ac.quant.quickfixspec.clickableviews.QuickfixSpecPsiReferenceContributor"/>
</extensions>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<html lang="en">
<body>
<p>
Detects shorthand <code>&lt;component&gt;</code> tags (e.g., <code>&lt;component name="compName1" /&gt;</code>) within
<code>&lt;message&gt;</code> sections and suggests replacing them with their full definition from the
<code>&lt;components&gt;</code> section of the same XML file.
</p>

<h3>Example</h3>
<pre><code class="language-xml">
&lt;message&gt;
&lt;component name="compName1" /&gt;
&lt;/message&gt;

&lt;components&gt;
&lt;component name="compName1"&gt;
&lt;field name="aa" /&gt;
&lt;field name="bb" /&gt;
&lt;/component&gt;
&lt;/components&gt;
</code></pre>

<p>
Suggestion: Expand <code>&lt;component name="compName1" /&gt;</code> to:
</p>

<pre><code class="language-xml">
&lt;component name="compName1"&gt;
&lt;field name="aa" /&gt;
&lt;field name="bb" /&gt;
&lt;/component&gt;
</code></pre>

</body>
</html>

0 comments on commit e3a1bde

Please sign in to comment.