aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-11-06 01:04:02 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-11-17 12:41:34 +0100
commit57c9a71b6004b9fc0ed6cc3c87f4d62141fc6d62 (patch)
tree5972c4da810817e3edbf9acfd858260fb8dbcc39
parentfeat: predicates as reference types (diff)
downloadrefinery-57c9a71b6004b9fc0ed6cc3c87f4d62141fc6d62.tar.gz
refinery-57c9a71b6004b9fc0ed6cc3c87f4d62141fc6d62.tar.zst
refinery-57c9a71b6004b9fc0ed6cc3c87f4d62141fc6d62.zip
refactor(language): opposite content assist
Only show references that may plausibly appear in an opposite declaration.
-rw-r--r--subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java34
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java15
2 files changed, 42 insertions, 7 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 8c787dfd..27e936a1 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
@@ -11,6 +11,7 @@ import org.eclipse.emf.ecore.EObject;
11import org.eclipse.emf.ecore.EReference; 11import org.eclipse.emf.ecore.EReference;
12import org.eclipse.emf.ecore.util.EcoreUtil; 12import org.eclipse.emf.ecore.util.EcoreUtil;
13import org.eclipse.xtext.CrossReference; 13import org.eclipse.xtext.CrossReference;
14import org.eclipse.xtext.EcoreUtil2;
14import org.eclipse.xtext.GrammarUtil; 15import org.eclipse.xtext.GrammarUtil;
15import org.eclipse.xtext.ide.editor.contentassist.ContentAssistContext; 16import org.eclipse.xtext.ide.editor.contentassist.ContentAssistContext;
16import org.eclipse.xtext.ide.editor.contentassist.IdeCrossrefProposalProvider; 17import org.eclipse.xtext.ide.editor.contentassist.IdeCrossrefProposalProvider;
@@ -105,14 +106,45 @@ public class ProblemCrossrefProposalProvider extends IdeCrossrefProposalProvider
105 return true; 106 return true;
106 } 107 }
107 108
109 var candidateEObjectOrProxy = candidate.getEObjectOrProxy();
110
111 if (eReference.equals(ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) &&
112 candidateEObjectOrProxy instanceof ReferenceDeclaration candidateReferenceDeclaration) {
113 return oppositeShouldBeVisible(candidateReferenceDeclaration, context);
114 }
115
108 var builtinSymbolsOption = desugarer.getBuiltinSymbols(context.getRootModel()); 116 var builtinSymbolsOption = desugarer.getBuiltinSymbols(context.getRootModel());
109 if (builtinSymbolsOption.isEmpty()) { 117 if (builtinSymbolsOption.isEmpty()) {
110 return true; 118 return true;
111 } 119 }
112 var builtinSymbols = builtinSymbolsOption.get(); 120 var builtinSymbols = builtinSymbolsOption.get();
113 121
114 var candidateEObjectOrProxy = candidate.getEObjectOrProxy(); 122 return builtinSymbolAwareShouldBeVisible(candidate, context, eReference, builtinSymbols,
123 candidateEObjectOrProxy);
124 }
125
126 private static boolean oppositeShouldBeVisible(ReferenceDeclaration candidateReferenceDeclaration,
127 ContentAssistContext context) {
128 var referenceDeclaration = EcoreUtil2.getContainerOfType(context.getCurrentModel(),
129 ReferenceDeclaration.class);
130 if (referenceDeclaration == null) {
131 return true;
132 }
133 var classDeclaration = EcoreUtil2.getContainerOfType(referenceDeclaration, ClassDeclaration.class);
134 if (classDeclaration == null) {
135 return true;
136 }
137 var oppositeType = candidateReferenceDeclaration.getReferenceType();
138 if (oppositeType == null) {
139 return true;
140 }
141 var resolvedOppositeType = EcoreUtil.resolve(oppositeType, candidateReferenceDeclaration);
142 return classDeclaration.equals(resolvedOppositeType);
143 }
115 144
145 private boolean builtinSymbolAwareShouldBeVisible(
146 IEObjectDescription candidate, ContentAssistContext context, EReference eReference,
147 BuiltinSymbols builtinSymbols, EObject candidateEObjectOrProxy) {
116 if (eReference.equals(ProblemPackage.Literals.REFERENCE_DECLARATION__REFERENCE_TYPE) && 148 if (eReference.equals(ProblemPackage.Literals.REFERENCE_DECLARATION__REFERENCE_TYPE) &&
117 context.getCurrentModel() instanceof ReferenceDeclaration referenceDeclaration && 149 context.getCurrentModel() instanceof ReferenceDeclaration referenceDeclaration &&
118 (referenceDeclaration.getKind() == ReferenceKind.CONTAINMENT || 150 (referenceDeclaration.getKind() == ReferenceKind.CONTAINMENT ||
diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java
index cf099aba..a4437ba6 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java
@@ -44,7 +44,7 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider {
44 return getVariableScope(context, scope); 44 return getVariableScope(context, scope);
45 } 45 }
46 if (reference == ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) { 46 if (reference == ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) {
47 return getOppositeScope(context, scope); 47 return getOppositeScope(context);
48 } 48 }
49 return scope; 49 return scope;
50 } 50 }
@@ -96,16 +96,19 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider {
96 } 96 }
97 } 97 }
98 98
99 protected IScope getOppositeScope(EObject context, IScope delegateScope) { 99 protected IScope getOppositeScope(EObject context) {
100 var referenceDeclaration = EcoreUtil2.getContainerOfType(context, ReferenceDeclaration.class); 100 var referenceDeclaration = EcoreUtil2.getContainerOfType(context, ReferenceDeclaration.class);
101 if (referenceDeclaration == null) { 101 if (referenceDeclaration == null) {
102 return delegateScope; 102 return IScope.NULLSCOPE;
103 } 103 }
104 var relation = referenceDeclaration.getReferenceType(); 104 var relation = referenceDeclaration.getReferenceType();
105 if (!(relation instanceof ClassDeclaration classDeclaration)) { 105 if (!(relation instanceof ClassDeclaration classDeclaration)) {
106 return delegateScope; 106 return IScope.NULLSCOPE;
107 } 107 }
108 var referenceDeclarations = desugarer.getAllReferenceDeclarations(classDeclaration); 108 var referenceDeclarations = classDeclaration.getFeatureDeclarations()
109 return Scopes.scopeFor(referenceDeclarations, delegateScope); 109 .stream()
110 .filter(ReferenceDeclaration.class::isInstance)
111 .toList();
112 return Scopes.scopeFor(referenceDeclarations);
110 } 113 }
111} 114}