diff options
author | Zoltan Ujhelyi | 2017-08-21 13:40:36 +0000 |
---|---|---|
committer | Zoltan Ujhelyi | 2017-08-24 10:42:32 +0000 |
commit | a129f223e8ba069da8573929a9725cb8d77717b1 (patch) | |
tree | 67acf2b4041ccc411ee238a3430f746eb3ac72c3 | |
parent | 48c447d2363b565d1290196038581576492a535c (diff) | |
download | org.eclipse.viatra-a129f223e8ba069da8573929a9725cb8d77717b1.tar.gz org.eclipse.viatra-a129f223e8ba069da8573929a9725cb8d77717b1.tar.xz org.eclipse.viatra-a129f223e8ba069da8573929a9725cb8d77717b1.zip |
[459482] Refactored scope provider to avoid declarative scope providers
Change-Id: I466bf696df5ac100593c576203d11bab8444ca87
Signed-off-by: Zoltan Ujhelyi <ujhelyiz@incquerylabs.com>
4 files changed, 92 insertions, 195 deletions
diff --git a/query/plugins/org.eclipse.viatra.query.patternlanguage.emf/src/org/eclipse/viatra/query/patternlanguage/emf/EMFPatternLanguageRuntimeModule.java b/query/plugins/org.eclipse.viatra.query.patternlanguage.emf/src/org/eclipse/viatra/query/patternlanguage/emf/EMFPatternLanguageRuntimeModule.java index 55d3c69e8..67dba07ea 100644 --- a/query/plugins/org.eclipse.viatra.query.patternlanguage.emf/src/org/eclipse/viatra/query/patternlanguage/emf/EMFPatternLanguageRuntimeModule.java +++ b/query/plugins/org.eclipse.viatra.query.patternlanguage.emf/src/org/eclipse/viatra/query/patternlanguage/emf/EMFPatternLanguageRuntimeModule.java @@ -33,7 +33,6 @@ import org.eclipse.viatra.query.patternlanguage.emf.util.IErrorFeedback; import org.eclipse.viatra.query.patternlanguage.emf.util.SimpleClassLoaderProvider; import org.eclipse.viatra.query.patternlanguage.emf.validation.EMFPatternLanguageJavaValidator; import org.eclipse.viatra.query.patternlanguage.emf.validation.EMFPatternLanguageSyntaxErrorMessageProvider; -import org.eclipse.viatra.query.patternlanguage.scoping.MyAbstractDeclarativeScopeProvider; import org.eclipse.viatra.query.patternlanguage.scoping.PatternLanguageResourceDescriptionStrategy; import org.eclipse.viatra.query.patternlanguage.typing.ITypeInferrer; import org.eclipse.viatra.query.patternlanguage.typing.ITypeSystem; @@ -53,6 +52,7 @@ import org.eclipse.xtext.serializer.tokens.ICrossReferenceSerializer; import org.eclipse.xtext.xbase.jvmmodel.IJvmModelInferrer; import org.eclipse.xtext.xbase.jvmmodel.ILogicalContainerProvider; import org.eclipse.xtext.xbase.jvmmodel.JvmModelAssociator; +import org.eclipse.xtext.xbase.scoping.batch.IBatchScopeProvider; import com.google.inject.Binder; import com.google.inject.Provides; @@ -77,8 +77,6 @@ public class EMFPatternLanguageRuntimeModule extends AbstractEMFPatternLanguageR @Override public void configureIScopeProviderDelegate(Binder binder) { binder.bind(IScopeProvider.class).annotatedWith(Names.named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)) - .to(EMFPatternLanguageDeclarativeScopeProvider.class); - binder.bind(IScopeProvider.class).annotatedWith(Names.named(MyAbstractDeclarativeScopeProvider.NAMED_DELEGATE)) .to(EMFPatternLanguageImportNamespaceProvider.class); // .to(XImportSectionNamespaceScopeProvider.class); Multibinder<IMetamodelProviderInstance> metamodelProviderBinder = Multibinder.newSetBinder(binder, IMetamodelProviderInstance.class); @@ -86,6 +84,13 @@ public class EMFPatternLanguageRuntimeModule extends AbstractEMFPatternLanguageR metamodelProviderBinder.addBinding().to(ResourceSetMetamodelProviderService.class); } + /** + * @since 1.7 + */ + public Class<? extends IBatchScopeProvider> bindIBatchScopeProvider() { + return EMFPatternLanguageDeclarativeScopeProvider.class; + } + @Override public Class<? extends IDefaultResourceDescriptionStrategy> bindIDefaultResourceDescriptionStrategy() { return PatternLanguageResourceDescriptionStrategy.class; diff --git a/query/plugins/org.eclipse.viatra.query.patternlanguage.emf/src/org/eclipse/viatra/query/patternlanguage/emf/scoping/EMFPatternLanguageDeclarativeScopeProvider.java b/query/plugins/org.eclipse.viatra.query.patternlanguage.emf/src/org/eclipse/viatra/query/patternlanguage/emf/scoping/EMFPatternLanguageDeclarativeScopeProvider.java index e8b5d048b..5c1cf4ee4 100644 --- a/query/plugins/org.eclipse.viatra.query.patternlanguage.emf/src/org/eclipse/viatra/query/patternlanguage/emf/scoping/EMFPatternLanguageDeclarativeScopeProvider.java +++ b/query/plugins/org.eclipse.viatra.query.patternlanguage.emf/src/org/eclipse/viatra/query/patternlanguage/emf/scoping/EMFPatternLanguageDeclarativeScopeProvider.java @@ -25,9 +25,11 @@ import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.viatra.query.patternlanguage.emf.EMFPatternLanguageScopeHelper; import org.eclipse.viatra.query.patternlanguage.emf.ResolutionException; import org.eclipse.viatra.query.patternlanguage.emf.eMFPatternLanguage.ClassType; +import org.eclipse.viatra.query.patternlanguage.emf.eMFPatternLanguage.EMFPatternLanguagePackage; import org.eclipse.viatra.query.patternlanguage.emf.eMFPatternLanguage.EnumValue; import org.eclipse.viatra.query.patternlanguage.emf.eMFPatternLanguage.PackageImport; import org.eclipse.viatra.query.patternlanguage.emf.eMFPatternLanguage.PatternModel; @@ -38,9 +40,9 @@ import org.eclipse.viatra.query.patternlanguage.patternLanguage.PathExpressionHe import org.eclipse.viatra.query.patternlanguage.patternLanguage.PathExpressionTail; import org.eclipse.viatra.query.patternlanguage.patternLanguage.Pattern; import org.eclipse.viatra.query.patternlanguage.patternLanguage.PatternBody; +import org.eclipse.viatra.query.patternlanguage.patternLanguage.PatternLanguagePackage; import org.eclipse.viatra.query.patternlanguage.patternLanguage.Type; import org.eclipse.viatra.query.patternlanguage.patternLanguage.util.PatternLanguageSwitch; -import org.eclipse.viatra.query.patternlanguage.scoping.MyAbstractDeclarativeScopeProvider; import org.eclipse.xtext.EcoreUtil2; import org.eclipse.xtext.naming.IQualifiedNameConverter; import org.eclipse.xtext.naming.QualifiedName; @@ -48,6 +50,7 @@ import org.eclipse.xtext.scoping.IScope; import org.eclipse.xtext.scoping.Scopes; import org.eclipse.xtext.scoping.impl.SimpleScope; import org.eclipse.xtext.util.SimpleAttributeResolver; +import org.eclipse.xtext.xbase.scoping.batch.XbaseBatchScopeProvider; import com.google.common.base.Function; import com.google.common.collect.Iterables; @@ -55,31 +58,78 @@ import com.google.common.collect.Lists; import com.google.inject.Inject; /** - * <p> - * An extended abstract declarative scope provider to facilitate the reusing of abstract declarative scope providers - * together with XBase scope provider. - * </p> - * <p> - * See <a - * href="http://www.eclipse.org/forums/index.php/mv/msg/219841/699521/#msg_699521">http://www.eclipse.org/forums/index - * .php/mv/msg/219841/699521/#msg_699521</a> for details. - * </p> + * This scope provider extends the Xbase scope provider with EMF metamodel access. * * @author Zoltan Ujhelyi - * + * @noreference This class is not intended to be referenced by clients. */ -public class EMFPatternLanguageDeclarativeScopeProvider extends MyAbstractDeclarativeScopeProvider { +@SuppressWarnings("restriction") +public class EMFPatternLanguageDeclarativeScopeProvider extends XbaseBatchScopeProvider { @Inject private IQualifiedNameConverter qualifiedNameConverter; @Inject private IMetamodelProvider metamodelProvider; + + @Override + public IScope getScope(EObject ctx, EReference ref) { + EClassifier refEType = ref.getEType(); + if (refEType instanceof EClass) { + EClass refType = (EClass) refEType; + + if (EcoreUtil2.isAssignableFrom(EcorePackage.Literals.EPACKAGE, refType)) { + PackageImport importDecl = EcoreUtil2.getContainerOfType(ctx, PackageImport.class); + if (importDecl == null) { + return IScope.NULLSCOPE; + } + return scope_EPackage(importDecl, ref); + } else if (EcoreUtil2.isAssignableFrom(EMFPatternLanguagePackage.Literals.PACKAGE_IMPORT, refType)) { + return scope_PackageImport(ctx, ref); + } else if (EcoreUtil2.isAssignableFrom(EcorePackage.Literals.ECLASSIFIER, refType)) { + ClassType containingClassDeclaration = EcoreUtil2.getContainerOfType(ctx, ClassType.class); + if (containingClassDeclaration != null) { + return scope_EClassifier(containingClassDeclaration, ref); + } else { + return scope_EClassifier(ctx, ref); + } + } else if (EcoreUtil2.isAssignableFrom(PatternLanguagePackage.Literals.VARIABLE, refType)) { + PatternBody containingBody = EcoreUtil2.getContainerOfType(ctx, PatternBody.class); + if (containingBody != null) { + return scope_Variable((PatternBody) ctx, ref); + } + AnnotationParameter containingAnnotationParameter = EcoreUtil2.getContainerOfType(ctx, + AnnotationParameter.class); + if (containingAnnotationParameter != null) { + return scope_Variable(containingAnnotationParameter, ref); + } + } else if (EcoreUtil2.isAssignableFrom(EcorePackage.Literals.ESTRUCTURAL_FEATURE, refType)) { + PathExpressionTail tail = EcoreUtil2.getContainerOfType(ctx, PathExpressionTail.class); + if (tail != null) { + return scope_EStructuralFeature(tail, ref); + } else { + PathExpressionHead head = EcoreUtil2.getContainerOfType(ctx, PathExpressionHead.class); + return scope_EStructuralFeature(head, ref); + } + } else if (EcoreUtil2.isAssignableFrom(EcorePackage.Literals.EENUM, refType)) { + EnumValue containingValue = EcoreUtil2.getContainerOfType(ctx, EnumValue.class); + if (containingValue != null) { + return scope_EEnum(containingValue, ref); + } + } else if (EcoreUtil2.isAssignableFrom(EcorePackage.Literals.EENUM_LITERAL, refType)) { + EnumValue containingValue = EcoreUtil2.getContainerOfType(ctx, EnumValue.class); + if (containingValue != null) { + return scope_EEnumLiteral(containingValue, ref); + } + } + } + return super.getScope(ctx, ref); + } - public IScope scope_EPackage(PackageImport ctx, EReference ref) { - return metamodelProvider.getAllMetamodelObjects(this.delegateGetScope(ctx, ref), ctx); + private IScope scope_EPackage(PackageImport ctx, EReference ref) { + return metamodelProvider.getAllMetamodelObjects(delegateGetScope(ctx, ref), ctx); } - public IScope scope_PackageImport(EObject ctx, EReference ref) { + private IScope scope_PackageImport(EObject ctx, EReference ref) { EObject root = getRootContainer(ctx); if (root instanceof PatternModel) { SimpleAttributeResolver<PackageImport, String> attributeResolver = SimpleAttributeResolver.<PackageImport, String>newResolver(String.class, "alias"); @@ -90,7 +140,7 @@ public class EMFPatternLanguageDeclarativeScopeProvider extends MyAbstractDeclar } } - public IScope scope_EClassifier(EObject ctx, EReference ref) { + private IScope scope_EClassifier(EObject ctx, EReference ref) { // The context is general as content assist might ask for different context types if (ctx instanceof ClassType) { return scope_EClassifier((ClassType)ctx, ref); @@ -98,7 +148,7 @@ public class EMFPatternLanguageDeclarativeScopeProvider extends MyAbstractDeclar return createUnqualifiedClassifierScope(ctx); } - public IScope scope_EClassifier(ClassType ctx, EReference ref) { + private IScope scope_EClassifier(ClassType ctx, EReference ref) { if (ctx.getMetamodel() != null && !ctx.getMetamodel().eIsProxy()) { return createClassifierScope(ctx.getMetamodel().getEPackage(), IScope.NULLSCOPE); } @@ -108,7 +158,7 @@ public class EMFPatternLanguageDeclarativeScopeProvider extends MyAbstractDeclar /** * @since 1.6 */ - public IScope scope_Variable(AnnotationParameter ctx, EReference ref) { + private IScope scope_Variable(AnnotationParameter ctx, EReference ref) { Pattern pattern = EcoreUtil2.getContainerOfType(ctx, Pattern.class); if (pattern != null) { return Scopes.scopeFor(pattern.getParameters()); @@ -116,7 +166,7 @@ public class EMFPatternLanguageDeclarativeScopeProvider extends MyAbstractDeclar return IScope.NULLSCOPE; } - public IScope scope_Variable(PatternBody ctx, EReference ref) { + private IScope scope_Variable(PatternBody ctx, EReference ref) { if (ctx != null && !ctx.eIsProxy()) { return Scopes.scopeFor(ctx.getVariables()); } @@ -147,16 +197,16 @@ public class EMFPatternLanguageDeclarativeScopeProvider extends MyAbstractDeclar return Scopes.scopeFor(ePackage.getEClassifiers(), outer); } - public IScope scope_EStructuralFeature(PathExpressionHead ctx, EReference ref) { + private IScope scope_EStructuralFeature(PathExpressionHead ctx, EReference ref) { // This is needed for content assist - in that case the ExpressionTail does not exists return expressionParentScopeProvider.doSwitch(ctx); } - public IScope scope_EStructuralFeature(PathExpressionTail ctx, EReference ref) { + private IScope scope_EStructuralFeature(PathExpressionTail ctx, EReference ref) { return expressionParentScopeProvider.doSwitch(ctx.eContainer()); } - public IScope scope_EEnum(EnumValue ctx, EReference ref) { + private IScope scope_EEnum(EnumValue ctx, EReference ref) { PatternModel model = (PatternModel) getRootContainer(ctx); final Collection<EEnum> enums = Lists.newArrayList(); for (PackageImport decl : EMFPatternLanguageHelper.getPackageImportsIterable(model)) { @@ -167,7 +217,7 @@ public class EMFPatternLanguageDeclarativeScopeProvider extends MyAbstractDeclar return Scopes.scopeFor(enums); } - public IScope scope_EEnumLiteral(EnumValue ctx, EReference ref) { + private IScope scope_EEnumLiteral(EnumValue ctx, EReference ref) { EEnum type; try { type = ctx.getEnumeration(); diff --git a/query/plugins/org.eclipse.viatra.query.patternlanguage/.settings/.api_filters b/query/plugins/org.eclipse.viatra.query.patternlanguage/.settings/.api_filters new file mode 100644 index 000000000..c46a94561 --- /dev/null +++ b/query/plugins/org.eclipse.viatra.query.patternlanguage/.settings/.api_filters @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<component id="org.eclipse.viatra.query.patternlanguage" version="2"> + <resource path="META-INF/MANIFEST.MF" type="org.eclipse.viatra.query.patternlanguage.scoping.MyAbstractDeclarativeScopeProvider"> + <filter comment="Internal API update" id="305324134"> + <message_arguments> + <message_argument value="org.eclipse.viatra.query.patternlanguage.scoping.MyAbstractDeclarativeScopeProvider"/> + <message_argument value="org.eclipse.viatra.query.patternlanguage_1.7.0"/> + </message_arguments> + </filter> + </resource> +</component> diff --git a/query/plugins/org.eclipse.viatra.query.patternlanguage/src/org/eclipse/viatra/query/patternlanguage/scoping/MyAbstractDeclarativeScopeProvider.java b/query/plugins/org.eclipse.viatra.query.patternlanguage/src/org/eclipse/viatra/query/patternlanguage/scoping/MyAbstractDeclarativeScopeProvider.java deleted file mode 100644 index a36aa63c6..000000000 --- a/query/plugins/org.eclipse.viatra.query.patternlanguage/src/org/eclipse/viatra/query/patternlanguage/scoping/MyAbstractDeclarativeScopeProvider.java +++ /dev/null @@ -1,169 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Zoltan Ujhelyi - initial API and implementation - *******************************************************************************/ -package org.eclipse.viatra.query.patternlanguage.scoping; - -import java.lang.reflect.Method; -import java.util.Collections; - -import org.apache.log4j.Logger; -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.xtext.scoping.IScope; -import org.eclipse.xtext.scoping.IScopeProvider; -import org.eclipse.xtext.scoping.impl.AbstractScopeProvider; -import org.eclipse.xtext.scoping.impl.IDelegatingScopeProvider; -import org.eclipse.xtext.util.PolymorphicDispatcher; - -import com.google.common.base.Predicate; -import com.google.inject.Inject; -import com.google.inject.name.Named; - -/** - * <p> - * An extended abstract declarative scope provider to facilitate the reusing of - * abstract declarative scope providers together with XBase scope provider. - * </p> - * <p> - * See <a href= - * "http://www.eclipse.org/forums/index.php/mv/msg/219841/699521/#msg_699521" - * >http://www.eclipse.org/forums/index - * .php/mv/msg/219841/699521/#msg_699521</a> for details. - * </p> - * - * @author Zoltan Ujhelyi - * - */ -public abstract class MyAbstractDeclarativeScopeProvider extends AbstractScopeProvider implements IDelegatingScopeProvider{ - - public static final String NAMED_DELEGATE = "org.eclipse.xtext.scoping.impl.MyAbstractDeclarativeScopeProvider.delegate"; - // public static final String NAMED_DELEGATE2 = - // "org.eclipse.xtext.scoping.impl.MyAbstractDeclarativeScopeProvider.delegate2"; - public static final String NAMED_ERROR_HANDLER = "org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.errorHandler"; - - public final Logger logger = Logger.getLogger(getClass()); - - @Inject - @Named(NAMED_DELEGATE) - private IScopeProvider delegate; - - protected IScope delegateGetScope(EObject context, EReference reference) { - return delegate.getScope(context, reference); - } - - public void setDelegate(IScopeProvider delegate) { - this.delegate = delegate; - } - - @Override - public IScopeProvider getDelegate() { - return delegate; - } - - @Inject(optional = true) - @Named(NAMED_ERROR_HANDLER) - private PolymorphicDispatcher.ErrorHandler<IScope> errorHandler = new PolymorphicDispatcher.NullErrorHandler<IScope>(); - - protected Predicate<Method> getPredicate(EObject context, EClass type) { - String methodName = "scope_" + type.getName(); - //System.out.println(methodName + " ctx " + context.eClass().getName()); - return PolymorphicDispatcher.Predicates.forName(methodName, 2); - } - - protected Predicate<Method> getPredicate(EObject context, - EReference reference) { - String methodName = - (reference == null || reference.getEContainingClass() == null) - ? - "no_such_scope" - : - "scope_" - + reference.getEContainingClass().getName() + "_" - + reference.getName(); - //System.out.println(methodName + " ctx " + context.eClass().getName()); - return PolymorphicDispatcher.Predicates.forName(methodName, 2); - } - - public IScope getScope(EObject context, EReference reference) { - IScope scope = polymorphicFindScopeForReferenceName(context, reference); - if (scope == null) { - scope = polymorphicFindScopeForClassName(context, reference); - if (scope == null) { - scope = delegateGetScope(context, reference); - } - } - return scope; - } - - protected IScope polymorphicFindScopeForClassName(EObject context, - EReference reference) { - IScope scope = null; - PolymorphicDispatcher<IScope> dispatcher = new PolymorphicDispatcher<IScope>( - Collections.singletonList(this), getPredicate(context, - reference.getEReferenceType()), errorHandler) { - @Override - protected IScope handleNoSuchMethod(Object... params) { - if (PolymorphicDispatcher.NullErrorHandler.class - .equals(errorHandler.getClass())) { - return null; - } - return super.handleNoSuchMethod(params); - } - }; - EObject current = context; - while (scope == null && current != null) { - scope = dispatcher.invoke(current, reference); - current = current.eContainer(); - } - current = context; - while (scope == null && current != null) { - scope = dispatcher.invoke(current, reference.getEReferenceType()); - if (scope != null) { - logger.warn("scope_<EClass>(EObject,EClass) is deprecated. Use scope_<EClass>(EObject,EReference) instead."); - } - current = current.eContainer(); - } - return scope; - } - - protected IScope polymorphicFindScopeForReferenceName(EObject context, - EReference reference) { - Predicate<Method> predicate = getPredicate(context, reference); - PolymorphicDispatcher<IScope> dispatcher = new PolymorphicDispatcher<IScope>( - Collections.singletonList(this), predicate, errorHandler) { - @Override - protected IScope handleNoSuchMethod(Object... params) { - if (PolymorphicDispatcher.NullErrorHandler.class - .equals(errorHandler.getClass())) { - return null; - } - return super.handleNoSuchMethod(params); - } - }; - EObject current = context; - IScope scope = null; - while (scope == null && current != null) { - scope = dispatcher.invoke(current, reference); - current = current.eContainer(); - } - return scope; - } - - public void setErrorHandler( - PolymorphicDispatcher.ErrorHandler<IScope> errorHandler) { - this.errorHandler = errorHandler; - } - - public PolymorphicDispatcher.ErrorHandler<IScope> getErrorHandler() { - return errorHandler; - } - -} |