From 68b25042001c8779ec244762f4f98b393783064a Mon Sep 17 00:00:00 2001 From: Johannes Mey <johannes.mey@tu-dresden.de> Date: Sun, 27 Dec 2020 12:41:36 +0100 Subject: [PATCH] extract analysis code and create line marker for nonterminal usages --- .../tooling/RelAstGrammarAnnotator.java | 52 +++-------------- .../RelAstGrammarLineMarkerProvider.java | 49 +++++++--------- .../jastadd/tooling/RelAstGrammarUtil.java | 58 +++++++++++++++++-- src/main/resources/META-INF/plugin.xml | 3 + 4 files changed, 83 insertions(+), 79 deletions(-) diff --git a/src/main/java/org/jastadd/tooling/RelAstGrammarAnnotator.java b/src/main/java/org/jastadd/tooling/RelAstGrammarAnnotator.java index 026ea61..a103a37 100644 --- a/src/main/java/org/jastadd/tooling/RelAstGrammarAnnotator.java +++ b/src/main/java/org/jastadd/tooling/RelAstGrammarAnnotator.java @@ -6,63 +6,31 @@ import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.Annotator; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; -import com.intellij.psi.JavaResolveResult; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiJavaCodeReferenceElement; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocTag; -import org.jastadd.tooling.psi.RelAstGrammarTypeDecl; import org.jetbrains.annotations.NotNull; import java.util.Arrays; -import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; +import static org.jastadd.tooling.RelAstGrammarUtil.asReferenceToTypeDecl; + public class RelAstGrammarAnnotator implements Annotator { @Override public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) { + Optional<PsiClass> classOptional = asReferenceToTypeDecl(element); - // Ensure the Psi Element is an reference - if (!(element instanceof PsiJavaCodeReferenceElement)) { - return; - } - - - // Ensure the Psi element references something with a name - PsiJavaCodeReferenceElement javaCodeReferenceElement = (PsiJavaCodeReferenceElement) element; - String value = javaCodeReferenceElement.getReferenceName(); - if (value == null) { + if (classOptional.isEmpty()) { return; } - // Ensure that the reference is valid and accessible - JavaResolveResult result = javaCodeReferenceElement.advancedResolve(true); - if (!result.isValidResult() || !result.isAccessible() || result.getElement() == null) { - return; - } - - // Ensure that the reference is a Java class - PsiElement reference = result.getElement(); - if (!(reference instanceof PsiClass)) { - return; - } - - // Ensure that the class has a doc comment which contains the tag ast with the value node - PsiClass refClass = (PsiClass) reference; - PsiDocComment docComment = refClass.getDocComment(); - if (docComment == null) { - return; - } - PsiDocTag astTag = docComment.findTagByName("ast"); - if (astTag == null) { - return; - } - if (astTag.getValueElement() == null || !astTag.getValueElement().getText().equals("node")) { - return; - } + PsiDocComment docComment = classOptional.get().getDocComment(); + assert docComment != null; // asReferenceToTypeDecl ensures this is not null PsiDocTag declaredAtTag = docComment.findTagByName("declaredat"); if (declaredAtTag == null) { @@ -82,12 +50,6 @@ public class RelAstGrammarAnnotator implements Annotator { .textAttributes(DefaultLanguageHighlighterColors.HIGHLIGHTED_REFERENCE) .tooltip("<b>JastAdd Nonterminal</b><br/>Production: <i>" + production + "</i><br/><i>Declared at </i>" + declaredAt) .create(); - - // Get the list of typeDecls for given key - List<RelAstGrammarTypeDecl> typeDecls = RelAstGrammarUtil.findTypeDecl(element.getProject(), value); - if (!typeDecls.isEmpty()) { - // TODO decide what to do here - } } } diff --git a/src/main/java/org/jastadd/tooling/RelAstGrammarLineMarkerProvider.java b/src/main/java/org/jastadd/tooling/RelAstGrammarLineMarkerProvider.java index c134114..a5ed753 100644 --- a/src/main/java/org/jastadd/tooling/RelAstGrammarLineMarkerProvider.java +++ b/src/main/java/org/jastadd/tooling/RelAstGrammarLineMarkerProvider.java @@ -1,47 +1,38 @@ package org.jastadd.tooling; import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo; - import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider; - import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; - import com.intellij.openapi.project.Project; - import com.intellij.psi.PsiElement; - import com.intellij.psi.PsiLiteralExpression; - import com.intellij.psi.impl.source.tree.java.PsiJavaTokenImpl; - import org.jetbrains.annotations.NotNull; +import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider; +import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import org.jastadd.tooling.psi.RelAstGrammarTypeDecl; +import org.jetbrains.annotations.NotNull; - import java.util.Collection; - import java.util.List; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +import static org.jastadd.tooling.RelAstGrammarUtil.asReferenceToTypeDecl; public class RelAstGrammarLineMarkerProvider extends RelatedItemLineMarkerProvider { @Override protected void collectNavigationMarkers(@NotNull PsiElement element, @NotNull Collection<? super RelatedItemLineMarkerInfo<?>> result) { - // This must be an element with a literal expression as a parent - if (!(element instanceof PsiJavaTokenImpl) || !(element.getParent() instanceof PsiLiteralExpression)) { - return; - } - // The literal expression must start with the Simple language literal expression - PsiLiteralExpression literalExpression = (PsiLiteralExpression) element.getParent(); - String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null; - if ((value == null) || - !value.startsWith(SimpleAnnotator.SIMPLE_PREFIX_STR + SimpleAnnotator.SIMPLE_SEPARATOR_STR)) { + Optional<PsiClass> classOptional = asReferenceToTypeDecl(element); + + if (classOptional.isEmpty()) { return; } - // Get the Simple language property usage - Project project = element.getProject(); - String possibleProperties = value.substring( - SimpleAnnotator.SIMPLE_PREFIX_STR.length() + SimpleAnnotator.SIMPLE_SEPARATOR_STR.length() - ); - final List<SimpleProperty> properties = SimpleUtil.findProperties(project, possibleProperties); - if (properties.size() > 0) { - // Add the property to a collection of line marker info + // Get the list of typeDecls for given key + List<RelAstGrammarTypeDecl> typeDecls = RelAstGrammarUtil.findTypeDecl(element.getProject(), classOptional.get().getName()); + if (!typeDecls.isEmpty()) { NavigationGutterIconBuilder<PsiElement> builder = - NavigationGutterIconBuilder.create(SimpleIcons.FILE) - .setTargets(properties) - .setTooltipText("Navigate to Simple language property"); + NavigationGutterIconBuilder.create(JastAddIcons.FILE) + .setTargets(typeDecls) + .setTooltipText("Navigate to production rule for RelAst nonterminal"); result.add(builder.createLineMarkerInfo(element)); } } diff --git a/src/main/java/org/jastadd/tooling/RelAstGrammarUtil.java b/src/main/java/org/jastadd/tooling/RelAstGrammarUtil.java index 37b37fc..fe5c59b 100644 --- a/src/main/java/org/jastadd/tooling/RelAstGrammarUtil.java +++ b/src/main/java/org/jastadd/tooling/RelAstGrammarUtil.java @@ -1,19 +1,24 @@ package org.jastadd.tooling; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.lang.annotation.HighlightSeverity; +import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiManager; +import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTag; import com.intellij.psi.search.FileTypeIndex; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; import org.jastadd.tooling.psi.RelAstGrammarFile; import org.jastadd.tooling.psi.RelAstGrammarTypeDecl; +import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; public class RelAstGrammarUtil { @@ -71,4 +76,47 @@ public class RelAstGrammarUtil { return result; } + public static Optional<PsiClass> asReferenceToTypeDecl(@NotNull final PsiElement element) { + + // Ensure the Psi Element is an reference + if (!(element instanceof PsiJavaCodeReferenceElement)) { + return Optional.empty(); + } + + // Ensure the Psi element references something with a name + PsiJavaCodeReferenceElement javaCodeReferenceElement = (PsiJavaCodeReferenceElement) element; + String value = javaCodeReferenceElement.getReferenceName(); + if (value == null) { + return Optional.empty(); + } + + // Ensure that the reference is valid and accessible + JavaResolveResult result = javaCodeReferenceElement.advancedResolve(true); + if (!result.isValidResult() || !result.isAccessible() || result.getElement() == null) { + return Optional.empty(); + } + + // Ensure that the reference is a Java class + PsiElement reference = result.getElement(); + if (!(reference instanceof PsiClass)) { + return Optional.empty(); + } + + // Ensure that the class has a doc comment which contains the tag ast with the value node + PsiClass refClass = (PsiClass) reference; + PsiDocComment docComment = refClass.getDocComment(); + if (docComment == null) { + return Optional.empty(); + } + PsiDocTag astTag = docComment.findTagByName("ast"); + if (astTag == null) { + return Optional.empty(); + } + if (astTag.getValueElement() == null || !astTag.getValueElement().getText().equals("node")) { + return Optional.empty(); + } + + return Optional.of(refClass); + } + } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index c1886d9..ce9e6d9 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -24,6 +24,9 @@ <colorSettingsPage implementation="org.jastadd.tooling.RelAstGrammarColorSettingsPage"/> <annotator language="JAVA" implementationClass="org.jastadd.tooling.RelAstGrammarAnnotator"/> + + <codeInsight.lineMarkerProvider language="JAVA" + implementationClass="org.jastadd.tooling.RelAstGrammarLineMarkerProvider"/> </extensions> <actions> -- GitLab