From 0023a469e2c54d551c9df6ece9b80e88481e99e2 Mon Sep 17 00:00:00 2001 From: Johannes Mey <johannes.mey@tu-dresden.de> Date: Sun, 21 Nov 2021 21:22:22 +0100 Subject: [PATCH] distinguish name and refernce --- src/main/grammar/Grammar.bnf | 16 ++++++-- .../tooling/grammar/GrammarAnnotator.java | 6 +-- .../GrammarChooseByNameContributor.java | 2 +- .../GrammarRefactoringSupportProvider.java | 4 +- .../tooling/grammar/GrammarReference.java | 2 +- ...rammarRemoveRedundantComponentNameFix.java | 4 +- .../grammar/psi/GrammarElementFactory.java | 9 ++++- .../GrammarComponentNameImplExtension.java | 37 +++++++++++++++++++ .../impl/GrammarTypeDeclImplExtension.java | 10 ++--- .../impl/GrammarTypeNameImplExtension.java | 36 ++++++++++++++++++ 10 files changed, 106 insertions(+), 20 deletions(-) create mode 100644 src/main/java/org/jastadd/tooling/grammar/psi/impl/GrammarComponentNameImplExtension.java create mode 100644 src/main/java/org/jastadd/tooling/grammar/psi/impl/GrammarTypeNameImplExtension.java diff --git a/src/main/grammar/Grammar.bnf b/src/main/grammar/Grammar.bnf index d5165bd..ca92e0f 100644 --- a/src/main/grammar/Grammar.bnf +++ b/src/main/grammar/Grammar.bnf @@ -19,7 +19,7 @@ GrammarFile ::= comment* ((type_decl | relation) comment*)* comment ::= (WHITESPACE | MULTILINECOMMENT | DOCCOMMENT | SINGLELINECOMMENT) -type_decl ::= ABSTRACT? declared_name (COL type_reference)? (ASSIGN (component | nta_component)*)? SCOL +type_decl ::= ABSTRACT? type_name (COL type_reference)? (ASSIGN (component | nta_component)*)? SCOL { extends="org.jastadd.tooling.grammar.psi.impl.GrammarTypeDeclImplExtension" implements="org.jastadd.tooling.grammar.psi.GrammarNamedElement" @@ -27,7 +27,7 @@ type_decl ::= ABSTRACT? declared_name (COL type_reference)? (ASSIGN (component | nta_component ::= SLASH component SLASH -component ::= (declared_name COL type_reference STAR?) | (type_reference STAR?) | (LBRACKET declared_name COL type_reference RBRACKET) | (LBRACKET type_reference RBRACKET) | (LT declared_name (COL (java_type_use))? GT) +component ::= (component_name COL type_reference STAR?) | (type_reference STAR?) | (LBRACKET component_name COL type_reference RBRACKET) | (LBRACKET type_reference RBRACKET) | (LT component_name (COL (java_type_use))? GT) java_type_use ::= parameterized_java_type_use | simple_java_type_use @@ -39,14 +39,22 @@ relation ::= REL ((unnamed_role LEFT navigable_role) | (navigable_role RIGHT un unnamed_role ::= type_reference | navigable_role -navigable_role ::= type_reference DOT declared_name (STAR | QUESTION_MARK)? +navigable_role ::= type_reference DOT component_name (STAR | QUESTION_MARK)? // for auto-completion, it is helpful if we can distinguish the different IDs -declared_name ::= ID +type_name ::= ID + type_reference ::= ID { extends="org.jastadd.tooling.grammar.psi.impl.GrammarTypeReferenceImplExtension" implements="org.jastadd.tooling.grammar.psi.GrammarNamedElement" } +component_name ::= ID +{ + extends="org.jastadd.tooling.grammar.psi.impl.GrammarComponentNameImplExtension" + implements="org.jastadd.tooling.grammar.psi.GrammarNamedElement" +} + + java_name ::= ID diff --git a/src/main/java/org/jastadd/tooling/grammar/GrammarAnnotator.java b/src/main/java/org/jastadd/tooling/grammar/GrammarAnnotator.java index 6797345..7e50155 100644 --- a/src/main/java/org/jastadd/tooling/grammar/GrammarAnnotator.java +++ b/src/main/java/org/jastadd/tooling/grammar/GrammarAnnotator.java @@ -18,11 +18,11 @@ public class GrammarAnnotator implements Annotator { if (element instanceof GrammarComponent) { GrammarComponent component = (GrammarComponent) element; - if (component.getTypeReference() != null && component.getDeclaredName() != null) { - String name = component.getDeclaredName().getText(); + if (component.getTypeReference() != null && component.getComponentName() != null) { + String name = component.getComponentName().getText(); if (name != null && !name.equals("") && name.equals(component.getTypeReference().getName())) { holder.newAnnotation(HighlightSeverity.WEAK_WARNING, "Redundant name") - .range(component.getDeclaredName().getTextRange()) + .range(component.getComponentName().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.") diff --git a/src/main/java/org/jastadd/tooling/grammar/GrammarChooseByNameContributor.java b/src/main/java/org/jastadd/tooling/grammar/GrammarChooseByNameContributor.java index f1d88f5..615f51e 100644 --- a/src/main/java/org/jastadd/tooling/grammar/GrammarChooseByNameContributor.java +++ b/src/main/java/org/jastadd/tooling/grammar/GrammarChooseByNameContributor.java @@ -18,7 +18,7 @@ public class GrammarChooseByNameContributor implements ChooseByNameContributor { List<GrammarTypeDecl> typeDecls = GrammarUtil.findTypeDecl(project); List<String> names = new ArrayList<>(typeDecls.size()); for (GrammarTypeDecl typeDecl : typeDecls) { - if (typeDecl.getName() != null && typeDecl.getName().length() > 0) { + if (typeDecl.getName() != null && !typeDecl.getName().isEmpty()) { names.add(typeDecl.getName()); } } diff --git a/src/main/java/org/jastadd/tooling/grammar/GrammarRefactoringSupportProvider.java b/src/main/java/org/jastadd/tooling/grammar/GrammarRefactoringSupportProvider.java index 1e70ce5..c726f79 100644 --- a/src/main/java/org/jastadd/tooling/grammar/GrammarRefactoringSupportProvider.java +++ b/src/main/java/org/jastadd/tooling/grammar/GrammarRefactoringSupportProvider.java @@ -3,7 +3,7 @@ package org.jastadd.tooling.grammar; import com.intellij.lang.refactoring.RefactoringSupportProvider; import com.intellij.psi.PsiElement; -import org.jastadd.tooling.grammar.psi.GrammarDeclaredName; +import org.jastadd.tooling.grammar.psi.GrammarTypeName; import org.jastadd.tooling.grammar.psi.GrammarTypeReference; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -14,7 +14,7 @@ public class GrammarRefactoringSupportProvider extends RefactoringSupportProvide public boolean isMemberInplaceRenameAvailable(@NotNull PsiElement elementToRename, @Nullable PsiElement context) { // in-place rename is still not available since not all requirements are met // see https://intellij-support.jetbrains.com/hc/en-us/community/posts/360006918740-How-do-I-enable-in-place-rename-Renaming-via-dialog-works-fine- - return (elementToRename instanceof GrammarDeclaredName) || (elementToRename instanceof GrammarTypeReference); + return (elementToRename instanceof GrammarTypeName) || (elementToRename instanceof GrammarTypeReference); } } diff --git a/src/main/java/org/jastadd/tooling/grammar/GrammarReference.java b/src/main/java/org/jastadd/tooling/grammar/GrammarReference.java index 3c6fc4b..2825e66 100644 --- a/src/main/java/org/jastadd/tooling/grammar/GrammarReference.java +++ b/src/main/java/org/jastadd/tooling/grammar/GrammarReference.java @@ -48,7 +48,7 @@ public class GrammarReference extends PsiReferenceBase<PsiElement> implements Ps List<GrammarTypeDecl> typeDecls = GrammarUtil.findTypeDecl(project); List<LookupElement> variants = new ArrayList<>(); for (final GrammarTypeDecl typeDecl : typeDecls) { - if (typeDecl.getName() != null && typeDecl.getName().length() > 0) { + if (typeDecl.getName() != null && !typeDecl.getName().isEmpty()) { variants.add(LookupElementBuilder .create(typeDecl).withIcon(JastAddIcons.FILE) .withPresentableText(typeDecl.getName()) diff --git a/src/main/java/org/jastadd/tooling/grammar/GrammarRemoveRedundantComponentNameFix.java b/src/main/java/org/jastadd/tooling/grammar/GrammarRemoveRedundantComponentNameFix.java index b906a76..a95cb2a 100644 --- a/src/main/java/org/jastadd/tooling/grammar/GrammarRemoveRedundantComponentNameFix.java +++ b/src/main/java/org/jastadd/tooling/grammar/GrammarRemoveRedundantComponentNameFix.java @@ -38,8 +38,8 @@ public class GrammarRemoveRedundantComponentNameFix extends BaseIntentionAction @Override public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) throws IncorrectOperationException { - PsiElement first = component.getDeclaredName(); - PsiElement last = component.getDeclaredName(); + PsiElement first = component.getComponentName(); + PsiElement last = component.getComponentName(); while (last != null && last.getNode().getElementType() != GrammarTypes.COL) { last = last.getNextSibling(); } diff --git a/src/main/java/org/jastadd/tooling/grammar/psi/GrammarElementFactory.java b/src/main/java/org/jastadd/tooling/grammar/psi/GrammarElementFactory.java index 05a33fa..aaacf26 100644 --- a/src/main/java/org/jastadd/tooling/grammar/psi/GrammarElementFactory.java +++ b/src/main/java/org/jastadd/tooling/grammar/psi/GrammarElementFactory.java @@ -13,9 +13,9 @@ public class GrammarElementFactory { throw new IllegalStateException("Utility class"); } - public static GrammarDeclaredName createDeclaredName(Project project, String name) { + public static GrammarTypeName createTypeName(Project project, String name) { final GrammarFile file = createFile(project, name + ";"); - return (GrammarDeclaredName) file.getFirstChild().getFirstChild(); + return (GrammarTypeName) file.getFirstChild().getFirstChild(); } public static GrammarTypeReference createTypeReference(Project project, String name) { @@ -23,6 +23,11 @@ public class GrammarElementFactory { return (GrammarTypeReference) (Objects.requireNonNull(file.getFirstChild().getNode().findChildByType(GrammarTypes.TYPE_REFERENCE)).getPsi()); } + public static GrammarComponentName createComponentName(Project project, String name) { + final GrammarFile file = createFile(project, "X ::= " + name + ":X ;"); + return (GrammarComponentName) file.getFirstChild().getFirstChild(); + } + public static GrammarFile createFile(Project project, String text) { String name = "dummy.relast"; return (GrammarFile) PsiFileFactory.getInstance(project). diff --git a/src/main/java/org/jastadd/tooling/grammar/psi/impl/GrammarComponentNameImplExtension.java b/src/main/java/org/jastadd/tooling/grammar/psi/impl/GrammarComponentNameImplExtension.java new file mode 100644 index 0000000..84e04ad --- /dev/null +++ b/src/main/java/org/jastadd/tooling/grammar/psi/impl/GrammarComponentNameImplExtension.java @@ -0,0 +1,37 @@ +package org.jastadd.tooling.grammar.psi.impl; + +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import org.jastadd.tooling.grammar.psi.GrammarComponentName; +import org.jastadd.tooling.grammar.psi.GrammarElementFactory; +import org.jastadd.tooling.grammar.psi.GrammarNamedElement; +import org.jastadd.tooling.grammar.psi.GrammarTypeReference; +import org.jetbrains.annotations.NotNull; + +public class GrammarComponentNameImplExtension extends GrammarNamedElementImpl implements GrammarNamedElement { + + public GrammarComponentNameImplExtension(@NotNull ASTNode node) { + super(node); + } + + public String getName() { + // this finds the *first* ID, which is what we want + return getNode().getText(); + } + + 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(); + if (keyNode != null) { + GrammarComponentName name = GrammarElementFactory.createComponentName(getProject(), newName); + ASTNode newKeyNode = name.getNode().getFirstChildNode(); + getNode().replaceChild(keyNode, newKeyNode); + } + return this; + } + + public PsiElement getNameIdentifier() { + return getNode().getPsi(); + } + +} diff --git a/src/main/java/org/jastadd/tooling/grammar/psi/impl/GrammarTypeDeclImplExtension.java b/src/main/java/org/jastadd/tooling/grammar/psi/impl/GrammarTypeDeclImplExtension.java index 8634701..39bd24d 100644 --- a/src/main/java/org/jastadd/tooling/grammar/psi/impl/GrammarTypeDeclImplExtension.java +++ b/src/main/java/org/jastadd/tooling/grammar/psi/impl/GrammarTypeDeclImplExtension.java @@ -3,9 +3,9 @@ package org.jastadd.tooling.grammar.psi.impl; import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; import org.jastadd.tooling.grammar.parser.GrammarTypes; -import org.jastadd.tooling.grammar.psi.GrammarDeclaredName; import org.jastadd.tooling.grammar.psi.GrammarElementFactory; import org.jastadd.tooling.grammar.psi.GrammarNamedElement; +import org.jastadd.tooling.grammar.psi.GrammarTypeName; import org.jetbrains.annotations.NotNull; public class GrammarTypeDeclImplExtension extends GrammarNamedElementImpl implements GrammarNamedElement { @@ -16,7 +16,7 @@ public class GrammarTypeDeclImplExtension extends GrammarNamedElementImpl implem public String getName() { // this finds the *first* ID, which is what we want - ASTNode keyNode = getNode().findChildByType(GrammarTypes.DECLARED_NAME); + ASTNode keyNode = getNode().findChildByType(GrammarTypes.TYPE_NAME); if (keyNode != null) { return keyNode.getText(); } else { @@ -25,9 +25,9 @@ public class GrammarTypeDeclImplExtension extends GrammarNamedElementImpl implem } public PsiElement setName(@NotNull String newName) { - ASTNode keyNode = getNode().findChildByType(GrammarTypes.DECLARED_NAME); + ASTNode keyNode = getNode().findChildByType(GrammarTypes.TYPE_NAME); if (keyNode != null) { - GrammarDeclaredName name = GrammarElementFactory.createDeclaredName(getProject(), newName); + GrammarTypeName name = GrammarElementFactory.createTypeName(getProject(), newName); ASTNode newKeyNode = name.getNode(); getNode().replaceChild(keyNode, newKeyNode); } @@ -35,7 +35,7 @@ public class GrammarTypeDeclImplExtension extends GrammarNamedElementImpl implem } public PsiElement getNameIdentifier() { - ASTNode keyNode = getNode().findChildByType(GrammarTypes.DECLARED_NAME); + ASTNode keyNode = getNode().findChildByType(GrammarTypes.TYPE_NAME); if (keyNode != null) { return keyNode.getPsi(); } else { diff --git a/src/main/java/org/jastadd/tooling/grammar/psi/impl/GrammarTypeNameImplExtension.java b/src/main/java/org/jastadd/tooling/grammar/psi/impl/GrammarTypeNameImplExtension.java new file mode 100644 index 0000000..753e63c --- /dev/null +++ b/src/main/java/org/jastadd/tooling/grammar/psi/impl/GrammarTypeNameImplExtension.java @@ -0,0 +1,36 @@ +package org.jastadd.tooling.grammar.psi.impl; + +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import org.jastadd.tooling.grammar.psi.GrammarElementFactory; +import org.jastadd.tooling.grammar.psi.GrammarNamedElement; +import org.jastadd.tooling.grammar.psi.GrammarTypeName; +import org.jetbrains.annotations.NotNull; + +public class GrammarTypeNameImplExtension extends GrammarNamedElementImpl implements GrammarNamedElement { + + public GrammarTypeNameImplExtension(@NotNull ASTNode node) { + super(node); + } + + public String getName() { + // this finds the *first* ID, which is what we want + return getNode().getText(); + } + + 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(); + if (keyNode != null) { + GrammarTypeName name = GrammarElementFactory.createTypeName(getProject(), newName); + ASTNode newKeyNode = name.getNode().getFirstChildNode(); + getNode().replaceChild(keyNode, newKeyNode); + } + return this; + } + + public PsiElement getNameIdentifier() { + return getNode().getPsi(); + } + +} -- GitLab