Skip to content
Snippets Groups Projects
Commit 68b25042 authored by Johannes Mey's avatar Johannes Mey
Browse files

extract analysis code and create line marker for nonterminal usages

parent f8d10017
No related branches found
No related tags found
No related merge requests found
...@@ -6,63 +6,31 @@ import com.intellij.lang.annotation.AnnotationHolder; ...@@ -6,63 +6,31 @@ import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator; import com.intellij.lang.annotation.Annotator;
import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
import com.intellij.psi.JavaResolveResult;
import com.intellij.psi.PsiClass; import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiJavaCodeReferenceElement;
import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag; import com.intellij.psi.javadoc.PsiDocTag;
import org.jastadd.tooling.psi.RelAstGrammarTypeDecl;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.jastadd.tooling.RelAstGrammarUtil.asReferenceToTypeDecl;
public class RelAstGrammarAnnotator implements Annotator { public class RelAstGrammarAnnotator implements Annotator {
@Override @Override
public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) { public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) {
Optional<PsiClass> classOptional = asReferenceToTypeDecl(element);
// Ensure the Psi Element is an reference if (classOptional.isEmpty()) {
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) {
return; return;
} }
// Ensure that the reference is valid and accessible PsiDocComment docComment = classOptional.get().getDocComment();
JavaResolveResult result = javaCodeReferenceElement.advancedResolve(true); assert docComment != null; // asReferenceToTypeDecl ensures this is not null
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;
}
PsiDocTag declaredAtTag = docComment.findTagByName("declaredat"); PsiDocTag declaredAtTag = docComment.findTagByName("declaredat");
if (declaredAtTag == null) { if (declaredAtTag == null) {
...@@ -82,12 +50,6 @@ public class RelAstGrammarAnnotator implements Annotator { ...@@ -82,12 +50,6 @@ public class RelAstGrammarAnnotator implements Annotator {
.textAttributes(DefaultLanguageHighlighterColors.HIGHLIGHTED_REFERENCE) .textAttributes(DefaultLanguageHighlighterColors.HIGHLIGHTED_REFERENCE)
.tooltip("<b>JastAdd Nonterminal</b><br/>Production: <i>" + production + "</i><br/><i>Declared at </i>" + declaredAt) .tooltip("<b>JastAdd Nonterminal</b><br/>Production: <i>" + production + "</i><br/><i>Declared at </i>" + declaredAt)
.create(); .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
}
} }
} }
...@@ -3,45 +3,36 @@ package org.jastadd.tooling; ...@@ -3,45 +3,36 @@ package org.jastadd.tooling;
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo; import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo;
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider; import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider;
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
import com.intellij.openapi.project.Project; import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiLiteralExpression; import org.jastadd.tooling.psi.RelAstGrammarTypeDecl;
import com.intellij.psi.impl.source.tree.java.PsiJavaTokenImpl;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Optional;
import static org.jastadd.tooling.RelAstGrammarUtil.asReferenceToTypeDecl;
public class RelAstGrammarLineMarkerProvider extends RelatedItemLineMarkerProvider { public class RelAstGrammarLineMarkerProvider extends RelatedItemLineMarkerProvider {
@Override @Override
protected void collectNavigationMarkers(@NotNull PsiElement element, protected void collectNavigationMarkers(@NotNull PsiElement element,
@NotNull Collection<? super RelatedItemLineMarkerInfo<?>> result) { @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 Optional<PsiClass> classOptional = asReferenceToTypeDecl(element);
PsiLiteralExpression literalExpression = (PsiLiteralExpression) element.getParent();
String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null; if (classOptional.isEmpty()) {
if ((value == null) ||
!value.startsWith(SimpleAnnotator.SIMPLE_PREFIX_STR + SimpleAnnotator.SIMPLE_SEPARATOR_STR)) {
return; return;
} }
// Get the Simple language property usage // Get the list of typeDecls for given key
Project project = element.getProject(); List<RelAstGrammarTypeDecl> typeDecls = RelAstGrammarUtil.findTypeDecl(element.getProject(), classOptional.get().getName());
String possibleProperties = value.substring( if (!typeDecls.isEmpty()) {
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
NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder<PsiElement> builder =
NavigationGutterIconBuilder.create(SimpleIcons.FILE) NavigationGutterIconBuilder.create(JastAddIcons.FILE)
.setTargets(properties) .setTargets(typeDecls)
.setTooltipText("Navigate to Simple language property"); .setTooltipText("Navigate to production rule for RelAst nonterminal");
result.add(builder.createLineMarkerInfo(element)); result.add(builder.createLineMarkerInfo(element));
} }
} }
......
package org.jastadd.tooling; 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.project.Project;
import com.intellij.openapi.vfs.VirtualFile; 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.FileTypeIndex;
import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTreeUtil;
import org.jastadd.tooling.psi.RelAstGrammarFile; import org.jastadd.tooling.psi.RelAstGrammarFile;
import org.jastadd.tooling.psi.RelAstGrammarTypeDecl; import org.jastadd.tooling.psi.RelAstGrammarTypeDecl;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays; import java.util.stream.Collectors;
import java.util.Collection;
import java.util.List;
public class RelAstGrammarUtil { public class RelAstGrammarUtil {
...@@ -71,4 +76,47 @@ public class RelAstGrammarUtil { ...@@ -71,4 +76,47 @@ public class RelAstGrammarUtil {
return result; 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);
}
} }
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
<colorSettingsPage implementation="org.jastadd.tooling.RelAstGrammarColorSettingsPage"/> <colorSettingsPage implementation="org.jastadd.tooling.RelAstGrammarColorSettingsPage"/>
<annotator language="JAVA" implementationClass="org.jastadd.tooling.RelAstGrammarAnnotator"/> <annotator language="JAVA" implementationClass="org.jastadd.tooling.RelAstGrammarAnnotator"/>
<codeInsight.lineMarkerProvider language="JAVA"
implementationClass="org.jastadd.tooling.RelAstGrammarLineMarkerProvider"/>
</extensions> </extensions>
<actions> <actions>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment