From 57c9a71b6004b9fc0ed6cc3c87f4d62141fc6d62 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Mon, 6 Nov 2023 01:04:02 +0100 Subject: refactor(language): opposite content assist Only show references that may plausibly appear in an opposite declaration. --- .../ProblemCrossrefProposalProvider.java | 34 +++++++++++++++++++++- .../language/scoping/ProblemScopeProvider.java | 15 ++++++---- 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; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.xtext.CrossReference; +import org.eclipse.xtext.EcoreUtil2; import org.eclipse.xtext.GrammarUtil; import org.eclipse.xtext.ide.editor.contentassist.ContentAssistContext; import org.eclipse.xtext.ide.editor.contentassist.IdeCrossrefProposalProvider; @@ -105,14 +106,45 @@ public class ProblemCrossrefProposalProvider extends IdeCrossrefProposalProvider return true; } + var candidateEObjectOrProxy = candidate.getEObjectOrProxy(); + + if (eReference.equals(ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) && + candidateEObjectOrProxy instanceof ReferenceDeclaration candidateReferenceDeclaration) { + return oppositeShouldBeVisible(candidateReferenceDeclaration, context); + } + var builtinSymbolsOption = desugarer.getBuiltinSymbols(context.getRootModel()); if (builtinSymbolsOption.isEmpty()) { return true; } var builtinSymbols = builtinSymbolsOption.get(); - var candidateEObjectOrProxy = candidate.getEObjectOrProxy(); + return builtinSymbolAwareShouldBeVisible(candidate, context, eReference, builtinSymbols, + candidateEObjectOrProxy); + } + + private static boolean oppositeShouldBeVisible(ReferenceDeclaration candidateReferenceDeclaration, + ContentAssistContext context) { + var referenceDeclaration = EcoreUtil2.getContainerOfType(context.getCurrentModel(), + ReferenceDeclaration.class); + if (referenceDeclaration == null) { + return true; + } + var classDeclaration = EcoreUtil2.getContainerOfType(referenceDeclaration, ClassDeclaration.class); + if (classDeclaration == null) { + return true; + } + var oppositeType = candidateReferenceDeclaration.getReferenceType(); + if (oppositeType == null) { + return true; + } + var resolvedOppositeType = EcoreUtil.resolve(oppositeType, candidateReferenceDeclaration); + return classDeclaration.equals(resolvedOppositeType); + } + private boolean builtinSymbolAwareShouldBeVisible( + IEObjectDescription candidate, ContentAssistContext context, EReference eReference, + BuiltinSymbols builtinSymbols, EObject candidateEObjectOrProxy) { if (eReference.equals(ProblemPackage.Literals.REFERENCE_DECLARATION__REFERENCE_TYPE) && context.getCurrentModel() instanceof ReferenceDeclaration referenceDeclaration && (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 { return getVariableScope(context, scope); } if (reference == ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) { - return getOppositeScope(context, scope); + return getOppositeScope(context); } return scope; } @@ -96,16 +96,19 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider { } } - protected IScope getOppositeScope(EObject context, IScope delegateScope) { + protected IScope getOppositeScope(EObject context) { var referenceDeclaration = EcoreUtil2.getContainerOfType(context, ReferenceDeclaration.class); if (referenceDeclaration == null) { - return delegateScope; + return IScope.NULLSCOPE; } var relation = referenceDeclaration.getReferenceType(); if (!(relation instanceof ClassDeclaration classDeclaration)) { - return delegateScope; + return IScope.NULLSCOPE; } - var referenceDeclarations = desugarer.getAllReferenceDeclarations(classDeclaration); - return Scopes.scopeFor(referenceDeclarations, delegateScope); + var referenceDeclarations = classDeclaration.getFeatureDeclarations() + .stream() + .filter(ReferenceDeclaration.class::isInstance) + .toList(); + return Scopes.scopeFor(referenceDeclarations); } } -- cgit v1.2.3-54-g00ecf