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

add new annotator for T:T components and a quick fix

parent a38a178f
No related branches found
No related tags found
No related merge requests found
...@@ -6,50 +6,31 @@ import com.intellij.lang.annotation.AnnotationHolder; ...@@ -6,50 +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.PsiClass;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.javadoc.PsiDocComment; import org.jastadd.tooling.psi.RelAstGrammarComponent;
import com.intellij.psi.javadoc.PsiDocTag;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Optional;
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); if (element instanceof RelAstGrammarComponent) {
RelAstGrammarComponent component = (RelAstGrammarComponent) element;
if (classOptional.isEmpty()) { if (component.getTypeReference() != null && component.getDeclaredName() != null) {
return; String name = component.getDeclaredName().getText();
if (name != null && !name.equals("") && name.equals(component.getTypeReference().getName())) {
holder.newAnnotation(HighlightSeverity.WEAK_WARNING, "Redundant name")
.range(component.getDeclaredName().getTextRange())
.highlightType(ProblemHighlightType.WEAK_WARNING)
.textAttributes(DefaultLanguageHighlighterColors.HIGHLIGHTED_REFERENCE)
.tooltip("When the name of a component is the same as its type, it can be omitted.")
.withFix(new RelAstGrammarRemoveRedundantComponentNameFix(component))
.create();
} }
PsiDocComment docComment = classOptional.get().getDocComment();
assert docComment != null; // asReferenceToTypeDecl ensures this is not null
PsiDocTag declaredAtTag = docComment.findTagByName("declaredat");
if (declaredAtTag == null) {
return;
} }
String declaredAt = Arrays.stream(declaredAtTag.getDataElements()).map(PsiElement::getText).collect(Collectors.joining());
PsiDocTag productionTag = docComment.findTagByName("astdecl");
if (productionTag == null) {
return;
} }
String production = Arrays.stream(productionTag.getDataElements()).map(PsiElement::getText).collect(Collectors.joining());
holder.newAnnotation(HighlightSeverity.INFORMATION, "JastAdd Nonterminal: " + production)
.range(element.getTextRange())
.highlightType(ProblemHighlightType.INFORMATION)
.textAttributes(DefaultLanguageHighlighterColors.HIGHLIGHTED_REFERENCE)
.tooltip("<b>JastAdd Nonterminal</b><br/>Production: <i>" + production + "</i><br/><i>Declared at </i>" + declaredAt)
.create();
} }
} }
package org.jastadd.tooling;
import com.intellij.codeInspection.ProblemHighlightType;
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.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import org.jastadd.tooling.psi.RelAstGrammarComponent;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Collectors;
import static org.jastadd.tooling.RelAstGrammarUtil.asReferenceToTypeDecl;
public class RelAstGrammarJavaAnnotator implements Annotator {
@Override
public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) {
Optional<PsiClass> classOptional = asReferenceToTypeDecl(element);
if (classOptional.isPresent()) {
PsiDocComment docComment = classOptional.get().getDocComment();
assert docComment != null; // asReferenceToTypeDecl ensures this is not null
PsiDocTag declaredAtTag = docComment.findTagByName("declaredat");
if (declaredAtTag == null) {
return;
}
String declaredAt = Arrays.stream(declaredAtTag.getDataElements()).map(PsiElement::getText).collect(Collectors.joining());
PsiDocTag productionTag = docComment.findTagByName("astdecl");
if (productionTag == null) {
return;
}
String production = Arrays.stream(productionTag.getDataElements()).map(PsiElement::getText).collect(Collectors.joining());
holder.newAnnotation(HighlightSeverity.INFORMATION, "JastAdd Nonterminal: " + production)
.range(element.getTextRange())
.highlightType(ProblemHighlightType.INFORMATION)
.textAttributes(DefaultLanguageHighlighterColors.HIGHLIGHTED_REFERENCE)
.tooltip("<b>JastAdd Nonterminal</b><br/>Production: <i>" + production + "</i><br/><i>Declared at </i>" + declaredAt)
.create();
}
}
}
package org.jastadd.tooling;
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.IncorrectOperationException;
import org.jastadd.tooling.parser.RelAstGrammarTypes;
import org.jastadd.tooling.psi.RelAstGrammarComponent;
import org.jetbrains.annotations.NotNull;
public class RelAstGrammarRemoveRedundantComponentNameFix extends BaseIntentionAction {
private final RelAstGrammarComponent component;
public RelAstGrammarRemoveRedundantComponentNameFix(RelAstGrammarComponent component) {
this.component = component;
}
@NotNull
@Override
public String getText() {
return "Remove the name of component '" + component.getText() + "'";
}
@NotNull
@Override
public String getFamilyName() {
return "Edit component";
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
return true;
}
@Override
public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) throws
IncorrectOperationException {
PsiElement first = component.getDeclaredName();
PsiElement last = component.getDeclaredName();
while (last != null && last.getNode().getElementType() != RelAstGrammarTypes.COL) {
last = last.getNextSibling();
}
if (last == null) {
throw new IncorrectOperationException("Unable to find ':' in component definition.");
} else {
component.deleteChildRange(first, last);
}
}
}
...@@ -19,6 +19,7 @@ public class RelAstGrammarTypeReferenceImplExtension extends RelAstGrammarNamedE ...@@ -19,6 +19,7 @@ public class RelAstGrammarTypeReferenceImplExtension extends RelAstGrammarNamedE
} }
public PsiElement setName(@NotNull String newName) { public PsiElement setName(@NotNull String newName) {
// FIXME this can break the grammar when the type is used in an unnamed component (and in many other cases probably)
ASTNode keyNode = getNode().getFirstChildNode(); ASTNode keyNode = getNode().getFirstChildNode();
if (keyNode != null) { if (keyNode != null) {
RelAstGrammarTypeReference name = RelAstGrammarElementFactory.createTypeReference(getProject(), newName); RelAstGrammarTypeReference name = RelAstGrammarElementFactory.createTypeReference(getProject(), newName);
......
...@@ -20,7 +20,9 @@ ...@@ -20,7 +20,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.RelAstGrammarJavaAnnotator"/>
<annotator language="JastAddGrammar" implementationClass="org.jastadd.tooling.RelAstGrammarAnnotator"/>
<codeInsight.lineMarkerProvider language="JAVA" <codeInsight.lineMarkerProvider language="JAVA"
implementationClass="org.jastadd.tooling.RelAstGrammarLineMarkerProvider"/> implementationClass="org.jastadd.tooling.RelAstGrammarLineMarkerProvider"/>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment