From 8ee3c366af77d3e80d6eef01bbbf65dddcb0ea83 Mon Sep 17 00:00:00 2001
From: Johannes Mey <johannes.mey@tu-dresden.de>
Date: Sun, 27 Dec 2020 22:55:34 +0100
Subject: [PATCH] add some code completion

---
 src/main/grammar/RelAstGrammar.bnf            | 15 ++++---
 .../RelAstGrammarCompletionContributor.java   | 43 +++++++++++++++++++
 src/main/resources/META-INF/plugin.xml        |  3 ++
 3 files changed, 56 insertions(+), 5 deletions(-)
 create mode 100644 src/main/java/org/jastadd/tooling/RelAstGrammarCompletionContributor.java

diff --git a/src/main/grammar/RelAstGrammar.bnf b/src/main/grammar/RelAstGrammar.bnf
index 0074794..e522f8e 100644
--- a/src/main/grammar/RelAstGrammar.bnf
+++ b/src/main/grammar/RelAstGrammar.bnf
@@ -19,20 +19,25 @@ relAstGrammarFile ::= comment* ((type_decl | relation) comment*)*
 
 comment ::= (WHITESPACE | MULTILINECOMMENT | DOCCOMMENT | SINGLELINECOMMENT)
 
-type_decl ::= ABSTRACT? ID (COL ID)? (ASSIGN (component | nta_component)*)? SCOL {methods=[getName]}
+type_decl ::= ABSTRACT? declared_name (COL type_reference)? (ASSIGN (component | nta_component)*)? SCOL {methods=[getName]}
 
 nta_component ::= SLASH component SLASH
 
-component ::= (ID (COL ID)? STAR?) | (LBRACKET ID (COL ID)? RBRACKET) | (LT ID (COL (java_type_use))? GT)
+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)
 
 java_type_use ::=  parameterized_java_type_use | simple_java_type_use
 
 parameterized_java_type_use ::= simple_java_type_use LT java_type_use (COMMA java_type_use)* GT
 
-simple_java_type_use ::=  ID (DOT ID)*
+simple_java_type_use ::=  java_name (DOT java_name)*
 
 relation ::=  REL ((unnamed_role LEFT navigable_role) | (navigable_role RIGHT unnamed_role) | (navigable_role BIDIRECTIONAL navigable_role)) SCOL
 
-unnamed_role ::= ID | navigable_role
+unnamed_role ::= type_reference | navigable_role
 
-navigable_role ::= ID DOT ID (STAR | QUESTION_MARK)?
+navigable_role ::= type_reference DOT declared_name (STAR | QUESTION_MARK)?
+
+// for auto-completion, it is helpful if we can distinguish the different IDs
+declared_name ::= ID
+type_reference ::= ID
+java_name ::= ID
diff --git a/src/main/java/org/jastadd/tooling/RelAstGrammarCompletionContributor.java b/src/main/java/org/jastadd/tooling/RelAstGrammarCompletionContributor.java
new file mode 100644
index 0000000..ac56ff8
--- /dev/null
+++ b/src/main/java/org/jastadd/tooling/RelAstGrammarCompletionContributor.java
@@ -0,0 +1,43 @@
+package org.jastadd.tooling;
+
+import com.intellij.codeInsight.completion.*;
+import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.patterns.PlatformPatterns;
+import com.intellij.psi.tree.TokenSet;
+import com.intellij.util.ProcessingContext;
+import org.jastadd.tooling.parser.RelAstGrammarTypes;
+import org.jastadd.tooling.psi.RelAstGrammarTypeDecl;
+import org.jastadd.tooling.psi.RelAstGrammarTypeReference;
+import org.jetbrains.annotations.NotNull;
+
+public class RelAstGrammarCompletionContributor extends CompletionContributor {
+
+  public RelAstGrammarCompletionContributor() {
+    extend(CompletionType.BASIC, PlatformPatterns.psiElement(RelAstGrammarTypes.ID).withParent(RelAstGrammarTypeReference.class),
+      new CompletionProvider<>() {
+        public void addCompletions(@NotNull CompletionParameters parameters,
+                                   @NotNull ProcessingContext context,
+                                   @NotNull CompletionResultSet resultSet) {
+
+          for (RelAstGrammarTypeDecl decl : RelAstGrammarUtil.findTypeDecl(parameters.getPosition().getProject())) {
+            resultSet.addElement(LookupElementBuilder.create(decl.getDeclaredName().getText()));
+          }
+        }
+      }
+    );
+
+    extend(CompletionType.BASIC, PlatformPatterns.psiElement(RelAstGrammarTypes.ID).afterLeaf("rel", "<->", "->", "<-", ":"),
+      new CompletionProvider<>() {
+        public void addCompletions(@NotNull CompletionParameters parameters,
+                                   @NotNull ProcessingContext context,
+                                   @NotNull CompletionResultSet resultSet) {
+          for (RelAstGrammarTypeDecl decl : RelAstGrammarUtil.findTypeDecl(parameters.getPosition().getProject())) {
+            resultSet.addElement(LookupElementBuilder.create(decl.getDeclaredName().getText()));
+          }
+        }
+      }
+    );
+
+  }
+
+}
diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml
index ce9e6d9..2e3ccc1 100644
--- a/src/main/resources/META-INF/plugin.xml
+++ b/src/main/resources/META-INF/plugin.xml
@@ -27,6 +27,9 @@
 
         <codeInsight.lineMarkerProvider language="JAVA"
                                         implementationClass="org.jastadd.tooling.RelAstGrammarLineMarkerProvider"/>
+
+        <completion.contributor language="JastAddGrammar"
+                                implementationClass="org.jastadd.tooling.RelAstGrammarCompletionContributor"/>
     </extensions>
 
     <actions>
-- 
GitLab