diff options
author | Ed Willink | 2017-01-21 13:22:04 +0000 |
---|---|---|
committer | Ed Willink | 2017-01-22 17:54:57 +0000 |
commit | e21fb2b39c797983872c3776d12010a617d496e7 (patch) | |
tree | 8fe70f12cc91529618245d2ac1e57a4d9e21aec3 | |
parent | ce925e1f477a80084bea171625ec58c16e001e98 (diff) | |
download | org.eclipse.ocl-e21fb2b39c797983872c3776d12010a617d496e7.tar.gz org.eclipse.ocl-e21fb2b39c797983872c3776d12010a617d496e7.tar.xz org.eclipse.ocl-e21fb2b39c797983872c3776d12010a617d496e7.zip |
[495621] Support parsing OCL in a user context
6 files changed, 112 insertions, 24 deletions
diff --git a/plugins/org.eclipse.ocl.pivot/src/org/eclipse/ocl/pivot/internal/context/AbstractParserContext.java b/plugins/org.eclipse.ocl.pivot/src/org/eclipse/ocl/pivot/internal/context/AbstractParserContext.java index d011cc492c..41867e7b5f 100644 --- a/plugins/org.eclipse.ocl.pivot/src/org/eclipse/ocl/pivot/internal/context/AbstractParserContext.java +++ b/plugins/org.eclipse.ocl.pivot/src/org/eclipse/ocl/pivot/internal/context/AbstractParserContext.java @@ -32,6 +32,8 @@ import org.eclipse.ocl.pivot.Type; import org.eclipse.ocl.pivot.internal.manager.PivotMetamodelManager; import org.eclipse.ocl.pivot.internal.messages.PivotMessagesInternal; import org.eclipse.ocl.pivot.internal.resource.EnvironmentFactoryAdapter; +import org.eclipse.ocl.pivot.internal.scoping.EnvironmentView; +import org.eclipse.ocl.pivot.internal.scoping.ScopeView; import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal; import org.eclipse.ocl.pivot.resource.CSResource; import org.eclipse.ocl.pivot.utilities.ClassUtil; @@ -43,7 +45,7 @@ import org.eclipse.ocl.pivot.utilities.PivotUtil; import org.eclipse.ocl.pivot.utilities.Pivotable; import org.eclipse.ocl.pivot.utilities.StringUtil; -public abstract class AbstractParserContext /*extends AdapterImpl*/ implements ParserContext +public abstract class AbstractParserContext /*extends AdapterImpl*/ implements ParserContext.ParserContextExtension { protected final @NonNull EnvironmentFactoryInternal environmentFactory; protected final @NonNull URI uri; @@ -59,6 +61,14 @@ public abstract class AbstractParserContext /*extends AdapterImpl*/ implements P } } + /** + * @since 1.3 + */ + @Override + public @Nullable ScopeView computeLookup(@NonNull EObject target, @NonNull EnvironmentView environmentView, @NonNull ScopeView scopeView) { + return null; + } + @Override public @NonNull CSResource createBaseResource(@NonNull String expression) throws IOException, ParserException { InputStream inputStream = new URIConverter.ReadableInputStream(expression, "UTF-8"); @@ -138,9 +148,9 @@ public abstract class AbstractParserContext /*extends AdapterImpl*/ implements P @Override public void initialize(@NonNull Base2ASConversion conversion, @NonNull ExpressionInOCL expression) { -// List<String> language = expression.getLanguage(); -// language.clear(); -// language.add(PivotConstants.OCL_LANGUAGE); + // List<String> language = expression.getLanguage(); + // language.clear(); + // language.add(PivotConstants.OCL_LANGUAGE); } @Override @@ -156,7 +166,7 @@ public abstract class AbstractParserContext /*extends AdapterImpl*/ implements P expressionInOCL.setBody(expression); return expressionInOCL; } catch (IOException e) { -// throw new ParserException("Failed to load expression", e); + // throw new ParserException("Failed to load expression", e); @NonNull ExpressionInOCL specification = PivotFactory.eINSTANCE.createExpressionInOCL(); OCLExpression invalidValueBody = getMetamodelManager().createInvalidExpression(); PivotUtil.setBody(specification, invalidValueBody, null); @@ -172,7 +182,7 @@ public abstract class AbstractParserContext /*extends AdapterImpl*/ implements P } } } - + @Override public void setRootElement(@Nullable Element rootElement) { this.rootElement = rootElement; diff --git a/plugins/org.eclipse.ocl.pivot/src/org/eclipse/ocl/pivot/internal/scoping/AbstractAttribution.java b/plugins/org.eclipse.ocl.pivot/src/org/eclipse/ocl/pivot/internal/scoping/AbstractAttribution.java index 0bc9649b51..6bd8552327 100644 --- a/plugins/org.eclipse.ocl.pivot/src/org/eclipse/ocl/pivot/internal/scoping/AbstractAttribution.java +++ b/plugins/org.eclipse.ocl.pivot/src/org/eclipse/ocl/pivot/internal/scoping/AbstractAttribution.java @@ -12,6 +12,7 @@ package org.eclipse.ocl.pivot.internal.scoping; import org.eclipse.emf.ecore.EObject; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; /** * Ann AbstractAttribution provides the basic behaviour for a family of derived @@ -19,9 +20,9 @@ import org.eclipse.jdt.annotation.NonNull; * CS elements. */ public abstract class AbstractAttribution implements Attribution -{ +{ @Override - public ScopeView computeLookup(@NonNull EObject target, @NonNull EnvironmentView environmentView, @NonNull ScopeView scopeView) { + public @Nullable ScopeView computeLookup(@NonNull EObject target, @NonNull EnvironmentView environmentView, @NonNull ScopeView scopeView) { return scopeView.getParent(); } } diff --git a/plugins/org.eclipse.ocl.pivot/src/org/eclipse/ocl/pivot/utilities/ParserContext.java b/plugins/org.eclipse.ocl.pivot/src/org/eclipse/ocl/pivot/utilities/ParserContext.java index ad5131c6c0..627ccc1b03 100644 --- a/plugins/org.eclipse.ocl.pivot/src/org/eclipse/ocl/pivot/utilities/ParserContext.java +++ b/plugins/org.eclipse.ocl.pivot/src/org/eclipse/ocl/pivot/utilities/ParserContext.java @@ -19,11 +19,13 @@ import org.eclipse.ocl.pivot.Element; import org.eclipse.ocl.pivot.ExpressionInOCL; import org.eclipse.ocl.pivot.Type; import org.eclipse.ocl.pivot.internal.context.Base2ASConversion; +import org.eclipse.ocl.pivot.internal.scoping.EnvironmentView; +import org.eclipse.ocl.pivot.internal.scoping.ScopeView; import org.eclipse.ocl.pivot.resource.CSResource; /** * A ParserContext captures the context in which source text is parsed. - * + * * A derived context is constructed with the relevant context, then createBaseResource * creates a Concrete Syntax resource for a Concrete Syntax expression string. Then parse creates * a corresponding Abstract Syntax ExpressionInOCL. initialize is invoked during the parse to @@ -32,17 +34,42 @@ import org.eclipse.ocl.pivot.resource.CSResource; public interface ParserContext // extends Adapter { /** + * @since 1.3 + */ + public interface ParserContextExtension extends ParserContext + { + /** + * Add the local lookup contributions to a view of an Environment. + * <p> + * The EnvironmentView contains the lookup matching criteria such as a specific name and + * accumulates candidate results. + * <p> + * The input ScopeView identifies the CS node and the containment of the CS child from which + * the lookup is made allowing derived implementations to present the alternative environments + * specified as the <i>Inherited Attributes</i> in the OCL Specification. + * <p> + * The returned ScopeView identifies an outer scope in which the lookup may be continued if the + * local candidate results are not suitable. + * + * @param environmentView the EnvironmentView to compute + * @param scopeView the access selectivity to be applied by the lookup + * @return an outer ScopeView in which to continue the lookup, or null if none + */ + @Nullable ScopeView computeLookup(@NonNull EObject target, @NonNull EnvironmentView environmentView, @NonNull ScopeView scopeView); + } + + /** * Create a Concrete Syntax resource containing the parsed expression. - * + * * Semantic errors may be found at the Resource.errors * and may be converted to ParseExceptions by invoking * PivitUtil.checkResourceErrors. - * + * * @throws IOException if resource loading fails - * @throws ParserException + * @throws ParserException */ @NonNull CSResource createBaseResource(@NonNull String expression) throws IOException, ParserException; - + /** * Return the type of the self variable. */ @@ -50,7 +77,7 @@ public interface ParserContext // extends Adapter /** * Extract an Abstract Syntax ExpressionInOCL fronm a Concrete Syntax resource. - * + * * @throws ParserException if parsing fails */ @Nullable ExpressionInOCL getExpression(@NonNull CSResource resource) throws ParserException; @@ -70,7 +97,7 @@ public interface ParserContext // extends Adapter * a contextvariable for the self type, parameter and result variables. */ void initialize(@NonNull Base2ASConversion conversion, @NonNull ExpressionInOCL expression); - + /** * Create an Abstract Syntax ExpressionInOCL containing the parsed expression on behalf of a potential owner. * <p> @@ -79,10 +106,10 @@ public interface ParserContext // extends Adapter * an operation body may specify the operation as the owner * <p> * The owner should be non-null but a null value is tolerated for deprecated compatibility. - * + * * @throws ParserException if parsing fails */ @NonNull ExpressionInOCL parse(@Nullable EObject owner, @NonNull String expression) throws ParserException; - + void setRootElement(@Nullable Element rootElement); } diff --git a/plugins/org.eclipse.ocl.xtext.base/src/org/eclipse/ocl/xtext/base/attributes/PivotableElementCSAttribution.java b/plugins/org.eclipse.ocl.xtext.base/src/org/eclipse/ocl/xtext/base/attributes/PivotableElementCSAttribution.java index cbfdd4c0be..43ce985e19 100644 --- a/plugins/org.eclipse.ocl.xtext.base/src/org/eclipse/ocl/xtext/base/attributes/PivotableElementCSAttribution.java +++ b/plugins/org.eclipse.ocl.xtext.base/src/org/eclipse/ocl/xtext/base/attributes/PivotableElementCSAttribution.java @@ -12,6 +12,7 @@ package org.eclipse.ocl.xtext.base.attributes; import org.eclipse.emf.ecore.EObject; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.pivot.Element; import org.eclipse.ocl.pivot.InvalidType; import org.eclipse.ocl.pivot.internal.scoping.AbstractAttribution; @@ -25,10 +26,10 @@ public class PivotableElementCSAttribution extends AbstractAttribution public static final PivotableElementCSAttribution INSTANCE = new PivotableElementCSAttribution(); @Override - public ScopeView computeLookup(@NonNull EObject target, @NonNull EnvironmentView environmentView, @NonNull ScopeView scopeView) { + public @Nullable ScopeView computeLookup(@NonNull EObject target, @NonNull EnvironmentView environmentView, @NonNull ScopeView scopeView) { Element pivot = PivotUtil.getPivot(Element.class, (PivotableElementCS)target); if ((pivot != null) && (pivot.eResource() != null) && !(pivot instanceof InvalidType)) { - environmentView.computeLookups(pivot, null); //PivotUtil.getPivot(Element.class, scopeView.getChild()); + environmentView.computeLookups(pivot, null); //PivotUtil.getPivot(Element.class, scopeView.getChild()); } return scopeView.getParent(); } diff --git a/plugins/org.eclipse.ocl.xtext.essentialocl/src/org/eclipse/ocl/xtext/essentialocl/attributes/ContextCSAttribution.java b/plugins/org.eclipse.ocl.xtext.essentialocl/src/org/eclipse/ocl/xtext/essentialocl/attributes/ContextCSAttribution.java new file mode 100644 index 0000000000..8e9609966e --- /dev/null +++ b/plugins/org.eclipse.ocl.xtext.essentialocl/src/org/eclipse/ocl/xtext/essentialocl/attributes/ContextCSAttribution.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2017 Willink Transformations and others. + * 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: + * E.D.Willink - initial API and implementation + *******************************************************************************/ +package org.eclipse.ocl.xtext.essentialocl.attributes; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.ocl.pivot.internal.scoping.EnvironmentView; +import org.eclipse.ocl.pivot.internal.scoping.ScopeView; +import org.eclipse.ocl.pivot.utilities.ParserContext; +import org.eclipse.ocl.xtext.base.attributes.PivotableElementCSAttribution; +import org.eclipse.ocl.xtext.base.utilities.BaseCSResource; + +public class ContextCSAttribution extends PivotableElementCSAttribution +{ + public static final ContextCSAttribution INSTANCE = new ContextCSAttribution(); + + @Override + public @Nullable ScopeView computeLookup(@NonNull EObject target, @NonNull EnvironmentView environmentView, @NonNull ScopeView scopeView) { + ScopeView computeLookup = super.computeLookup(target, environmentView, scopeView); + // + // Last, last alternative. If nothing found give the ParserContext an opportunity to help out. + // + // This may be used by for instance UMLX2QVTr to parse an OCL text snippet within its local ContextCS and then + // search further to th ancestry of the model in which the OCL text snippet belongs. + // + if (!environmentView.hasFinalResult() && ((computeLookup == null) || (computeLookup.getTarget() == null))) { + Resource eResource = target.eResource(); + if (eResource instanceof BaseCSResource) { + ParserContext parserContext = ((BaseCSResource)eResource).getParserContext(); + if (parserContext instanceof ParserContext.ParserContextExtension) { + return ((ParserContext.ParserContextExtension)parserContext).computeLookup(target, environmentView, scopeView); + } + } + } + return computeLookup; + } +} diff --git a/plugins/org.eclipse.ocl.xtext.essentialocl/src/org/eclipse/ocl/xtext/essentialocl/scoping/EssentialOCLScoping.java b/plugins/org.eclipse.ocl.xtext.essentialocl/src/org/eclipse/ocl/xtext/essentialocl/scoping/EssentialOCLScoping.java index a647029952..a0b979b8f8 100644 --- a/plugins/org.eclipse.ocl.xtext.essentialocl/src/org/eclipse/ocl/xtext/essentialocl/scoping/EssentialOCLScoping.java +++ b/plugins/org.eclipse.ocl.xtext.essentialocl/src/org/eclipse/ocl/xtext/essentialocl/scoping/EssentialOCLScoping.java @@ -38,6 +38,7 @@ import org.eclipse.ocl.xtext.basecs.PathElementCS; import org.eclipse.ocl.xtext.basecs.PathNameCS; import org.eclipse.ocl.xtext.basecs.SpecificationCS; import org.eclipse.ocl.xtext.basecs.TypedTypeRefCS; +import org.eclipse.ocl.xtext.essentialocl.attributes.ContextCSAttribution; import org.eclipse.ocl.xtext.essentialocl.attributes.LetExpCSAttribution; import org.eclipse.ocl.xtext.essentialocl.attributes.LetVariableCSAttribution; import org.eclipse.ocl.xtext.essentialocl.attributes.NavigatingArgCSAttribution; @@ -57,9 +58,10 @@ import org.eclipse.ocl.xtext.essentialoclcs.RoundBracketedClauseCS; import org.eclipse.ocl.xtext.essentialoclcs.TypeNameExpCS; public class EssentialOCLScoping -{ +{ public static void init() { Map<EClassifier, Attribution> registry = Attribution.REGISTRY; + registry.put(EssentialOCLCSPackage.Literals.CONTEXT_CS, ContextCSAttribution.INSTANCE); registry.put(EssentialOCLCSPackage.Literals.LET_EXP_CS, LetExpCSAttribution.INSTANCE); registry.put(EssentialOCLCSPackage.Literals.LET_VARIABLE_CS, LetVariableCSAttribution.INSTANCE); // Needed for let deeply nested in Iterator/CollectionLiteral registry.put(EssentialOCLCSPackage.Literals.NAVIGATING_ARG_CS, NavigatingArgCSAttribution.INSTANCE); @@ -67,13 +69,13 @@ public class EssentialOCLScoping registry.put(EssentialOCLCSPackage.Literals.SHADOW_PART_CS, ShadowPartCSAttribution.INSTANCE); CS2AS.addUnresolvedProxyMessageProvider(new PathElementCSUnresolvedProxyMessageProvider()); } - + private static final class PathElementCSUnresolvedProxyMessageProvider extends AbstractUnresolvedProxyMessageProvider { private PathElementCSUnresolvedProxyMessageProvider() { super(BaseCSPackage.Literals.PATH_ELEMENT_CS__REFERRED_ELEMENT); } - + @Override public String getMessage(@NonNull EObject eObject, @NonNull String linkText) { PathElementCS csPathElement = (PathElementCS) eObject; @@ -202,7 +204,7 @@ public class EssentialOCLScoping } return messageText; } - + public String getOperationArguments(@NonNull RoundBracketedClauseCS csRoundBracketedClause) { List<NavigatingArgCS> arguments = csRoundBracketedClause.getOwnedArguments(); StringBuilder s = new StringBuilder(); @@ -221,5 +223,5 @@ public class EssentialOCLScoping } return s.toString(); } - } + } } |