Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve and show documentation for field and group #19

Merged
merged 2 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;

import static ac.quant.quickfixspec.common.PsiUtils.isComponentsDeclaration;
import static ac.quant.quickfixspec.common.PsiUtils.isTagDeclaration;

@Slf4j
public class QuickFixPsiReferenceProvider extends PsiReferenceProvider {
Expand All @@ -23,7 +23,7 @@ public class QuickFixPsiReferenceProvider extends PsiReferenceProvider {

XmlAttributeValue attributeValue = (XmlAttributeValue) element;

if (isComponentsDeclaration(attributeValue)) {
if (isTagDeclaration(attributeValue)) {
return PsiReference.EMPTY_ARRAY;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;


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

@Slf4j
public class QuickfixPsiReference implements PsiReference {

private final XmlAttributeValue attributeValue;
private final XmlTag rootTag;
private final String parentTagName;

public QuickfixPsiReference(final XmlAttributeValue attributeValue) {
this.attributeValue = attributeValue;
this.parentTagName = ((XmlTag) attributeValue.getParent().getParent()).getName();
this.rootTag = getRootTag(attributeValue);
}

Expand All @@ -37,8 +37,8 @@ public QuickfixPsiReference(final XmlAttributeValue attributeValue) {

@Override
public @Nullable PsiElement resolve() {
String componentName = attributeValue.getValue();
return findComponent(rootTag, componentName);
String tagName = attributeValue.getValue();
return findDefinition(tagName, parentTagName, rootTag);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@
import com.intellij.psi.xml.XmlAttributeValue;
import org.jetbrains.annotations.NotNull;
import lombok.extern.slf4j.Slf4j;
import static ac.quant.quickfixspec.common.PsiUtils.NAME_ATTRIBUTE;
import static ac.quant.quickfixspec.common.PsiUtils.TAGS_WITH_DEFINITION;

@Slf4j
public class QuickfixSpecPsiReferenceContributor extends PsiReferenceContributor {


@Override
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {


PsiElementPattern.Capture<XmlAttributeValue> psiElementCapture = PlatformPatterns.psiElement(XmlAttributeValue.class)
.withParent(XmlPatterns.xmlAttribute().withName("name"))
.withSuperParent(2, XmlPatterns.xmlTag().withName("component"));
.withParent(XmlPatterns.xmlAttribute().withName(NAME_ATTRIBUTE))
.withSuperParent(2, XmlPatterns.xmlTag().withName(TAGS_WITH_DEFINITION));

registrar.registerReferenceProvider(
psiElementCapture,
Expand Down
47 changes: 39 additions & 8 deletions src/main/java/ac/quant/quickfixspec/common/PsiUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,25 @@
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.annotations.Nullable;

import java.util.Map;

public class PsiUtils {

public final static String NAME_ATTRIBUTE = "name";

public static final Map<String, String> DEFINITION_GROUP_NAME = Map.of(
"component", "components",
"group", "fields",
"field", "fields"
);

public static final Map<String, String> DEFINITION_TAG_NAME = Map.of(
"component", "component",
"group", "field",
"field", "field"
);
public final static String[] TAGS_WITH_DEFINITION = new String[]{"component", "group", "field"};


// Helper method to navigate to the root tag
public static @Nullable XmlTag getRootTag(PsiElement element) {
Expand All @@ -22,25 +39,39 @@
return null;
}

public static @Nullable XmlTag findComponent(final XmlTag rootTag, final String componentName) {
public static @Nullable XmlTag findDefinition(final String tagName , final String parentTagName, final XmlTag rootTag) {

XmlTag[] componentsTags = rootTag.findSubTags("components");
XmlTag[] tags = rootTag.findSubTags(DEFINITION_GROUP_NAME.get(parentTagName));

for (XmlTag componentsTag : componentsTags) {
for (XmlTag componentTag : componentsTag.findSubTags("component")) {
String nameAttr = componentTag.getAttributeValue("name");
if (componentName.equals(nameAttr)) {
for (XmlTag tag : tags) {
for (XmlTag componentTag : tag.findSubTags(DEFINITION_TAG_NAME.get(parentTagName))) {
String nameAttr = componentTag.getAttributeValue(NAME_ATTRIBUTE);
if (tagName.equals(nameAttr)) {
return componentTag;
}
}
}
return null;
}

public static boolean isComponentsDeclaration(XmlAttributeValue valueElement) {
// answers the question :
// is the attribute value is inside one of the 2 tags that are used for declaration
// <components> <component name=""/> </components>
// <fields> <field name=""/> </fields>
public static boolean isTagDeclaration(XmlAttributeValue valueElement) {
XmlAttribute parentAttribute = (XmlAttribute) valueElement.getParent();
XmlTag xmlTag = parentAttribute.getParent();
XmlTag parentTag = xmlTag.getParentTag();
return parentTag != null && "components".equals(parentTag.getName());
if (parentTag == null) {
return false;
}

final String parentTagName = parentTag.getName();

if (DEFINITION_GROUP_NAME.containsValue(parentTagName)) {

Check warning on line 71 in src/main/java/ac/quant/quickfixspec/common/PsiUtils.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Redundant 'if' statement

`if` statement can be simplified
return true;
}

return false;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package ac.quant.quickfixspec.documentation


import ac.quant.quickfixspec.common.PsiUtils.findComponent
import ac.quant.quickfixspec.common.PsiUtils.findDefinition
import com.intellij.model.Pointer
import com.intellij.platform.backend.documentation.DocumentationResult
import com.intellij.platform.backend.documentation.DocumentationTarget
Expand All @@ -10,7 +10,8 @@ import com.intellij.psi.xml.XmlTag

@Suppress("UnstableApiUsage")
class QuickfixComponentDocumentationTarget(
private val componentName: String,
private val tagName: String,
private val parentTagName: String,
private val rootTag: XmlTag?
) : DocumentationTarget {

Expand All @@ -20,7 +21,7 @@ class QuickfixComponentDocumentationTarget(
}

override fun computePresentation(): TargetPresentation {
return TargetPresentation.builder(componentName).presentation()
return TargetPresentation.builder(tagName).presentation()
}

override fun computeDocumentationHint(): String {
Expand All @@ -29,21 +30,21 @@ class QuickfixComponentDocumentationTarget(
}

override fun computeDocumentation(): DocumentationResult {
val componentDetails = getComponentDetails(componentName)
val componentDetails = getTagDetails(tagName)
return DocumentationResult.documentation(componentDetails)
}

private fun getComponentDetails(componentName: String): String {
val component: XmlTag? = findComponent(rootTag, componentName)
component ?: return ""
return getDisplayText(component)
private fun getTagDetails(tagName: String): String {
val tag: XmlTag? = findDefinition(tagName, parentTagName, rootTag)
tag ?: return ""
return getDisplayText(tag)
}

private fun getDisplayText(component: XmlTag): String {
val text = component.children.joinToString("") { it.text }
private fun getDisplayText(tag: XmlTag): String {
val text = tag.children.joinToString("") { it.text }
val xmlEscapedText = xmlEscaped(text)
val indentationRemoved = indentationRemoved(xmlEscapedText)
val displayText = "<html><body><h1>${component.name}</h1><pre>$indentationRemoved</pre></body></html>"
val displayText = "<html><body><h1>${tag.name}</h1><pre>$indentationRemoved</pre></body></html>"
return displayText
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package ac.quant.quickfixspec.documentation

import ac.quant.quickfixspec.common.PsiUtils.NAME_ATTRIBUTE
import ac.quant.quickfixspec.common.PsiUtils.TAGS_WITH_DEFINITION
import ac.quant.quickfixspec.common.PsiUtils.DEFINITION_GROUP_NAME
import ac.quant.quickfixspec.common.PsiUtils.getRootTag
import com.intellij.platform.backend.documentation.DocumentationTarget
import com.intellij.platform.backend.documentation.DocumentationTargetProvider
Expand All @@ -22,24 +25,27 @@ class QuickfixComponentDocumentationTargetProvider : DocumentationTargetProvider
rootTag = getRootTag(attribute)
}

if ("name" != attribute.name) {
if (NAME_ATTRIBUTE != attribute.name) {
return emptyList()
}

val tag = attribute.parent as? XmlTag ?: return emptyList()

if ("component" != tag.name) {
if (tag.name !in TAGS_WITH_DEFINITION) {
return emptyList()
}

val tagParent = tag.parent as? XmlTag ?: return emptyList()

if ("components" == tagParent.name) {

// skip definition when tagParent.name is "components" or "fields"

if (tagParent.name in DEFINITION_GROUP_NAME.values) {
return emptyList()
}

val componentName = attribute.value ?: return emptyList()
return listOf(QuickfixComponentDocumentationTarget(componentName, rootTag))
val attrNameValue = attribute.value ?: return emptyList()
return listOf(QuickfixComponentDocumentationTarget(attrNameValue, tag.name, rootTag))

}

Expand Down