diff options
Diffstat (limited to 'language-ide/src/main')
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 @@ | |||
4 | package tools.refinery.language.ide; | 4 | package tools.refinery.language.ide; |
5 | 5 | ||
6 | import org.eclipse.xtext.ide.editor.contentassist.IPrefixMatcher; | 6 | import org.eclipse.xtext.ide.editor.contentassist.IPrefixMatcher; |
7 | import org.eclipse.xtext.ide.editor.contentassist.IdeCrossrefProposalProvider; | ||
7 | import org.eclipse.xtext.ide.editor.syntaxcoloring.ISemanticHighlightingCalculator; | 8 | import org.eclipse.xtext.ide.editor.syntaxcoloring.ISemanticHighlightingCalculator; |
8 | 9 | ||
9 | import tools.refinery.language.ide.contentassist.FuzzyMatcher; | 10 | import tools.refinery.language.ide.contentassist.FuzzyMatcher; |
11 | import tools.refinery.language.ide.contentassist.ProblemCrossrefProposalProvider; | ||
10 | import tools.refinery.language.ide.syntaxcoloring.ProblemSemanticHighlightingCalculator; | 12 | import 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 @@ | |||
1 | package tools.refinery.language.ide.contentassist; | ||
2 | |||
3 | import java.util.Objects; | ||
4 | |||
5 | import org.eclipse.emf.ecore.EObject; | ||
6 | import org.eclipse.emf.ecore.util.EcoreUtil; | ||
7 | import org.eclipse.xtext.CrossReference; | ||
8 | import org.eclipse.xtext.GrammarUtil; | ||
9 | import org.eclipse.xtext.ide.editor.contentassist.ContentAssistContext; | ||
10 | import org.eclipse.xtext.ide.editor.contentassist.ContentAssistEntry; | ||
11 | import org.eclipse.xtext.ide.editor.contentassist.IdeCrossrefProposalProvider; | ||
12 | import org.eclipse.xtext.nodemodel.util.NodeModelUtils; | ||
13 | import org.eclipse.xtext.resource.IEObjectDescription; | ||
14 | |||
15 | import com.google.inject.Inject; | ||
16 | |||
17 | import tools.refinery.language.model.ProblemUtil; | ||
18 | import tools.refinery.language.model.problem.Problem; | ||
19 | import tools.refinery.language.resource.ReferenceCounter; | ||
20 | |||
21 | public 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 | } | ||