diff options
Diffstat (limited to 'subprojects/language-ide/src/main/java')
2 files changed, 49 insertions, 16 deletions
diff --git a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java index e194ee31..ea90a82e 100644 --- a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java +++ b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java | |||
@@ -5,39 +5,60 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.language.ide.contentassist; | 6 | package tools.refinery.language.ide.contentassist; |
7 | 7 | ||
8 | import java.util.Objects; | 8 | import com.google.inject.Inject; |
9 | |||
10 | import org.eclipse.emf.ecore.EObject; | 9 | import org.eclipse.emf.ecore.EObject; |
11 | import org.eclipse.emf.ecore.util.EcoreUtil; | 10 | import org.eclipse.emf.ecore.util.EcoreUtil; |
12 | import org.eclipse.xtext.CrossReference; | 11 | import org.eclipse.xtext.CrossReference; |
13 | import org.eclipse.xtext.GrammarUtil; | 12 | import org.eclipse.xtext.GrammarUtil; |
14 | import org.eclipse.xtext.ide.editor.contentassist.ContentAssistContext; | 13 | import org.eclipse.xtext.ide.editor.contentassist.ContentAssistContext; |
15 | import org.eclipse.xtext.ide.editor.contentassist.ContentAssistEntry; | ||
16 | import org.eclipse.xtext.ide.editor.contentassist.IdeCrossrefProposalProvider; | 14 | import org.eclipse.xtext.ide.editor.contentassist.IdeCrossrefProposalProvider; |
15 | import org.eclipse.xtext.naming.QualifiedName; | ||
17 | import org.eclipse.xtext.nodemodel.util.NodeModelUtils; | 16 | import org.eclipse.xtext.nodemodel.util.NodeModelUtils; |
18 | import org.eclipse.xtext.resource.IEObjectDescription; | 17 | import org.eclipse.xtext.resource.IEObjectDescription; |
19 | 18 | import org.eclipse.xtext.scoping.IScope; | |
20 | import com.google.inject.Inject; | ||
21 | |||
22 | import tools.refinery.language.model.problem.Problem; | 19 | import tools.refinery.language.model.problem.Problem; |
20 | import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; | ||
23 | import tools.refinery.language.resource.ReferenceCounter; | 21 | import tools.refinery.language.resource.ReferenceCounter; |
24 | import tools.refinery.language.utils.ProblemUtil; | 22 | import tools.refinery.language.utils.ProblemUtil; |
25 | 23 | ||
24 | import java.util.ArrayList; | ||
25 | import java.util.HashMap; | ||
26 | import java.util.List; | ||
27 | import java.util.Objects; | ||
28 | |||
26 | public class ProblemCrossrefProposalProvider extends IdeCrossrefProposalProvider { | 29 | public class ProblemCrossrefProposalProvider extends IdeCrossrefProposalProvider { |
27 | @Inject | 30 | @Inject |
28 | private ReferenceCounter referenceCounter; | 31 | private ReferenceCounter referenceCounter; |
29 | 32 | ||
30 | @Override | 33 | @Override |
31 | protected ContentAssistEntry createProposal(IEObjectDescription candidate, CrossReference crossRef, | 34 | protected Iterable<IEObjectDescription> queryScope(IScope scope, CrossReference crossReference, |
32 | ContentAssistContext context) { | 35 | ContentAssistContext context) { |
33 | if (!shouldCreateProposal(candidate, crossRef, context)) { | 36 | var eObjectDescriptionsByName = new HashMap<QualifiedName, List<IEObjectDescription>>(); |
34 | return null; | 37 | for (var candidate : super.queryScope(scope, crossReference, context)) { |
38 | if (isExistingObject(candidate, crossReference, context)) { | ||
39 | // {@code getQualifiedName()} will refer to the full name for objects that are loaded from the global | ||
40 | // scope, but {@code getName()} returns the qualified name that we set in | ||
41 | // {@code ProblemResourceDescriptionStrategy}. | ||
42 | var qualifiedName = candidate.getName(); | ||
43 | var candidateList = eObjectDescriptionsByName.computeIfAbsent(qualifiedName, | ||
44 | ignored -> new ArrayList<>()); | ||
45 | candidateList.add(candidate); | ||
46 | } | ||
35 | } | 47 | } |
36 | return super.createProposal(candidate, crossRef, context); | 48 | var eObjectDescriptions = new ArrayList<IEObjectDescription>(); |
49 | for (var candidates : eObjectDescriptionsByName.values()) { | ||
50 | if (candidates.size() == 1) { | ||
51 | var candidate = candidates.get(0); | ||
52 | if (shouldBeVisible(candidate)) { | ||
53 | eObjectDescriptions.add(candidate); | ||
54 | } | ||
55 | } | ||
56 | } | ||
57 | return eObjectDescriptions; | ||
37 | } | 58 | } |
38 | 59 | ||
39 | protected boolean shouldCreateProposal(IEObjectDescription candidate, CrossReference crossRef, | 60 | protected boolean isExistingObject(IEObjectDescription candidate, CrossReference crossRef, |
40 | ContentAssistContext context) { | 61 | ContentAssistContext context) { |
41 | var rootModel = context.getRootModel(); | 62 | var rootModel = context.getRootModel(); |
42 | var eObjectOrProxy = candidate.getEObjectOrProxy(); | 63 | var eObjectOrProxy = candidate.getEObjectOrProxy(); |
43 | if (!Objects.equals(rootModel.eResource(), eObjectOrProxy.eResource())) { | 64 | if (!Objects.equals(rootModel.eResource(), eObjectOrProxy.eResource())) { |
@@ -60,6 +81,11 @@ public class ProblemCrossrefProposalProvider extends IdeCrossrefProposalProvider | |||
60 | return true; | 81 | return true; |
61 | } | 82 | } |
62 | 83 | ||
84 | protected boolean shouldBeVisible(IEObjectDescription candidate) { | ||
85 | var errorPredicate = candidate.getUserData(ProblemResourceDescriptionStrategy.ERROR_PREDICATE); | ||
86 | return !ProblemResourceDescriptionStrategy.ERROR_PREDICATE_TRUE.equals(errorPredicate); | ||
87 | } | ||
88 | |||
63 | protected EObject getCurrentValue(CrossReference crossRef, ContentAssistContext context) { | 89 | protected EObject getCurrentValue(CrossReference crossRef, ContentAssistContext context) { |
64 | var value = getCurrentValue(crossRef, context.getCurrentModel()); | 90 | var value = getCurrentValue(crossRef, context.getCurrentModel()); |
65 | if (value != null) { | 91 | if (value != null) { |
diff --git a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java index e8f97d51..ae8c70e0 100644 --- a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java +++ b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java | |||
@@ -16,6 +16,7 @@ import org.eclipse.xtext.nodemodel.INode; | |||
16 | import org.eclipse.xtext.nodemodel.util.NodeModelUtils; | 16 | import org.eclipse.xtext.nodemodel.util.NodeModelUtils; |
17 | import org.eclipse.xtext.service.OperationCanceledManager; | 17 | import org.eclipse.xtext.service.OperationCanceledManager; |
18 | import org.eclipse.xtext.util.CancelIndicator; | 18 | import org.eclipse.xtext.util.CancelIndicator; |
19 | import org.jetbrains.annotations.NotNull; | ||
19 | import tools.refinery.language.model.problem.*; | 20 | import tools.refinery.language.model.problem.*; |
20 | import tools.refinery.language.utils.ProblemDesugarer; | 21 | import tools.refinery.language.utils.ProblemDesugarer; |
21 | import tools.refinery.language.utils.ProblemUtil; | 22 | import tools.refinery.language.utils.ProblemUtil; |
@@ -94,9 +95,16 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli | |||
94 | } | 95 | } |
95 | 96 | ||
96 | protected String[] getHighlightClass(EObject eObject, EReference reference) { | 97 | protected String[] getHighlightClass(EObject eObject, EReference reference) { |
98 | boolean isError = ProblemUtil.isError(eObject); | ||
97 | if (ProblemUtil.isBuiltIn(eObject)) { | 99 | if (ProblemUtil.isBuiltIn(eObject)) { |
98 | return new String[] { BUILTIN_CLASS }; | 100 | var className = isError ? ERROR_CLASS : BUILTIN_CLASS; |
101 | return new String[] { className }; | ||
99 | } | 102 | } |
103 | return getUserDefinedElementHighlightClass(eObject, reference, isError); | ||
104 | } | ||
105 | |||
106 | @NotNull | ||
107 | private String[] getUserDefinedElementHighlightClass(EObject eObject, EReference reference, boolean isError) { | ||
100 | ImmutableList.Builder<String> classesBuilder = ImmutableList.builder(); | 108 | ImmutableList.Builder<String> classesBuilder = ImmutableList.builder(); |
101 | if (eObject instanceof ClassDeclaration classDeclaration && classDeclaration.isAbstract()) { | 109 | if (eObject instanceof ClassDeclaration classDeclaration && classDeclaration.isAbstract()) { |
102 | classesBuilder.add(ABSTRACT_CLASS); | 110 | classesBuilder.add(ABSTRACT_CLASS); |
@@ -105,8 +113,7 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli | |||
105 | && desugarer.isContainmentReference(referenceDeclaration)) { | 113 | && desugarer.isContainmentReference(referenceDeclaration)) { |
106 | classesBuilder.add(CONTAINMENT_CLASS); | 114 | classesBuilder.add(CONTAINMENT_CLASS); |
107 | } | 115 | } |
108 | if (eObject instanceof PredicateDefinition predicateDefinition | 116 | if (isError) { |
109 | && predicateDefinition.getKind() == PredicateKind.ERROR) { | ||
110 | classesBuilder.add(ERROR_CLASS); | 117 | classesBuilder.add(ERROR_CLASS); |
111 | } | 118 | } |
112 | if (eObject instanceof Node node) { | 119 | if (eObject instanceof Node node) { |