aboutsummaryrefslogtreecommitdiffstats
path: root/language-ide
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2021-11-04 17:41:52 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2021-11-04 17:41:52 +0100
commit432ff3aaee8d45025f309436db541d0ec1b76485 (patch)
tree0d49c583f71f9972c6f5050540ac50e78992eaf2 /language-ide
parentfix(web): fix autocomplete prefix behavior (diff)
downloadrefinery-432ff3aaee8d45025f309436db541d0ec1b76485.tar.gz
refinery-432ff3aaee8d45025f309436db541d0ec1b76485.tar.zst
refinery-432ff3aaee8d45025f309436db541d0ec1b76485.zip
fix(language): hide current implicit proposal
Content assist proposals should not display the object that is only added to the model because the current context assist input refers to it (e.g., an implicit node or variable that is only referenced in the currently edited context).
Diffstat (limited to 'language-ide')
-rw-r--r--language-ide/src/main/java/tools/refinery/language/ide/ProblemIdeModule.java8
-rw-r--r--language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java79
2 files changed, 86 insertions, 1 deletions
diff --git a/language-ide/src/main/java/tools/refinery/language/ide/ProblemIdeModule.java b/language-ide/src/main/java/tools/refinery/language/ide/ProblemIdeModule.java
index 3502c29f..51cecf06 100644
--- a/language-ide/src/main/java/tools/refinery/language/ide/ProblemIdeModule.java
+++ b/language-ide/src/main/java/tools/refinery/language/ide/ProblemIdeModule.java
@@ -4,9 +4,11 @@
4package tools.refinery.language.ide; 4package tools.refinery.language.ide;
5 5
6import org.eclipse.xtext.ide.editor.contentassist.IPrefixMatcher; 6import org.eclipse.xtext.ide.editor.contentassist.IPrefixMatcher;
7import org.eclipse.xtext.ide.editor.contentassist.IdeCrossrefProposalProvider;
7import org.eclipse.xtext.ide.editor.syntaxcoloring.ISemanticHighlightingCalculator; 8import org.eclipse.xtext.ide.editor.syntaxcoloring.ISemanticHighlightingCalculator;
8 9
9import tools.refinery.language.ide.contentassist.FuzzyMatcher; 10import tools.refinery.language.ide.contentassist.FuzzyMatcher;
11import tools.refinery.language.ide.contentassist.ProblemCrossrefProposalProvider;
10import tools.refinery.language.ide.syntaxcoloring.ProblemSemanticHighlightingCalculator; 12import tools.refinery.language.ide.syntaxcoloring.ProblemSemanticHighlightingCalculator;
11 13
12/** 14/**
@@ -16,9 +18,13 @@ public class ProblemIdeModule extends AbstractProblemIdeModule {
16 public Class<? extends ISemanticHighlightingCalculator> bindISemanticHighlightingCalculator() { 18 public Class<? extends ISemanticHighlightingCalculator> bindISemanticHighlightingCalculator() {
17 return ProblemSemanticHighlightingCalculator.class; 19 return ProblemSemanticHighlightingCalculator.class;
18 } 20 }
19 21
20 @Override 22 @Override
21 public Class<? extends IPrefixMatcher> bindIPrefixMatcher() { 23 public Class<? extends IPrefixMatcher> bindIPrefixMatcher() {
22 return FuzzyMatcher.class; 24 return FuzzyMatcher.class;
23 } 25 }
26
27 public Class<? extends IdeCrossrefProposalProvider> bindIdeCrossrefProposalProvider() {
28 return ProblemCrossrefProposalProvider.class;
29 }
24} 30}
diff --git a/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java b/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java
new file mode 100644
index 00000000..416535ce
--- /dev/null
+++ b/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java
@@ -0,0 +1,79 @@
1package tools.refinery.language.ide.contentassist;
2
3import java.util.Objects;
4
5import org.eclipse.emf.ecore.EObject;
6import org.eclipse.emf.ecore.util.EcoreUtil;
7import org.eclipse.xtext.CrossReference;
8import org.eclipse.xtext.GrammarUtil;
9import org.eclipse.xtext.ide.editor.contentassist.ContentAssistContext;
10import org.eclipse.xtext.ide.editor.contentassist.ContentAssistEntry;
11import org.eclipse.xtext.ide.editor.contentassist.IdeCrossrefProposalProvider;
12import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
13import org.eclipse.xtext.resource.IEObjectDescription;
14
15import com.google.inject.Inject;
16
17import tools.refinery.language.model.ProblemUtil;
18import tools.refinery.language.model.problem.Problem;
19import tools.refinery.language.resource.ReferenceCounter;
20
21public class ProblemCrossrefProposalProvider extends IdeCrossrefProposalProvider {
22 @Inject
23 private ReferenceCounter referenceCounter;
24
25 @Override
26 protected ContentAssistEntry createProposal(IEObjectDescription candidate, CrossReference crossRef,
27 ContentAssistContext context) {
28 if (!shouldCreateProposal(candidate, crossRef, context)) {
29 return null;
30 }
31 return super.createProposal(candidate, crossRef, context);
32 }
33
34 protected boolean shouldCreateProposal(IEObjectDescription candidate, CrossReference crossRef,
35 ContentAssistContext context) {
36 var rootModel = context.getRootModel();
37 var eObjectOrProxy = candidate.getEObjectOrProxy();
38 if (!Objects.equals(rootModel.eResource(), eObjectOrProxy.eResource())) {
39 return true;
40 }
41 var currentValue = getCurrentValue(crossRef, context);
42 if (currentValue == null) {
43 return true;
44 }
45 var eObject = EcoreUtil.resolve(eObjectOrProxy, rootModel);
46 if (!Objects.equals(currentValue, eObject)) {
47 return true;
48 }
49 if (!ProblemUtil.isImplicit(eObject)) {
50 return true;
51 }
52 if (rootModel instanceof Problem problem) {
53 var referenceCounts = referenceCounter.getReferenceCounts(problem);
54 var count = referenceCounts.get(eObject);
55 return count != null && count >= 2;
56 }
57 return true;
58 }
59
60 protected EObject getCurrentValue(CrossReference crossRef, ContentAssistContext context) {
61 var value = getCurrentValue(crossRef, context.getCurrentModel());
62 if (value != null) {
63 return value;
64 }
65 var currentNodeSemanticObject = NodeModelUtils.findActualSemanticObjectFor(context.getCurrentNode());
66 return getCurrentValue(crossRef, currentNodeSemanticObject);
67 }
68
69 protected EObject getCurrentValue(CrossReference crossRef, EObject context) {
70 if (context == null) {
71 return null;
72 }
73 var eReference = GrammarUtil.getReference(crossRef, context.eClass());
74 if (eReference == null || eReference.isMany()) {
75 return null;
76 }
77 return (EObject) context.eGet(eReference);
78 }
79}