aboutsummaryrefslogtreecommitdiffstats
path: root/language-ide
diff options
context:
space:
mode:
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}