blob: 0a54f22fff7bcf0554a73c1cb1c2c20ba6d62d9d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015, 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.qvtd.pivot.qvtcore.analysis;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.Annotation;
import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.CompleteClass;
import org.eclipse.ocl.pivot.CompleteModel;
import org.eclipse.ocl.pivot.CompletePackage;
import org.eclipse.ocl.pivot.DataType;
import org.eclipse.ocl.pivot.Detail;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.NullLiteralExp;
import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.OperationCallExp;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.StandardLibrary;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.ids.OperationId;
import org.eclipse.ocl.pivot.internal.complete.StandardLibraryInternal;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.EnvironmentFactory;
import org.eclipse.ocl.pivot.utilities.LabelUtil;
import org.eclipse.ocl.pivot.utilities.NameUtil;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.qvtd.pivot.qvtbase.Domain;
import org.eclipse.qvtd.pivot.qvtbase.QVTbaseFactory;
import org.eclipse.qvtd.pivot.qvtbase.Rule;
import org.eclipse.qvtd.pivot.qvtbase.Transformation;
import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseUtil;
import org.eclipse.qvtd.pivot.qvtcore.Area;
import org.eclipse.qvtd.pivot.qvtcore.CoreDomain;
import org.eclipse.qvtd.pivot.qvtcore.Mapping;
import org.eclipse.qvtd.pivot.qvtcore.PropertyAssignment;
import org.eclipse.qvtd.pivot.qvtcore.util.QVTcoreVisitor;
import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreUtil;
public class RootDomainUsageAnalysis extends AbstractDomainUsageAnalysis implements QVTcoreVisitor<org.eclipse.qvtd.pivot.qvtcore.analysis.DomainUsage>, DomainUsageAnalysis.Root
{
protected abstract class AbstractDomainUsage implements DomainUsage.Internal
{
protected final int bitMask;
protected AbstractDomainUsage(int bitMask) {
this.bitMask = bitMask;
}
@Override
public int compareTo(DomainUsage.Internal o) {
return getMask() - o.getMask();
}
@Override
public int getMask() {
return bitMask;
}
@Override
public @Nullable TypedModel getTypedModel() throws IllegalStateException {
return getTypedModel(null);
}
@Override
public @Nullable TypedModel getTypedModel(@Nullable Element context) throws IllegalStateException {
int residue = bitMask;
for (int i = 0; residue != 0; i++) {
int bit = 1 << i;
if ((residue & bit) != 0) {
residue &= ~bit;
if (residue == 0) {
return RootDomainUsageAnalysis.this.getTypedModel(i);
}
if (!(context instanceof NullLiteralExp)) {
System.err.println("Ambiguous TypedModel: " + this + " for " + LabelUtil.getLabel(context));
}
// throw new IllegalStateException("Ambiguous TypedModel: " + this);
return RootDomainUsageAnalysis.this.getTypedModel(i);
}
}
return null;
}
@Override
public @NonNull Iterable<@NonNull TypedModel> getTypedModels() {
List<@NonNull TypedModel> typedModels = new ArrayList<>();
int residue = bitMask;
for (int i = 0; residue != 0; i++) {
int bit = 1 << i;
if ((residue & bit) != 0) {
residue &= ~bit;
typedModels.add(RootDomainUsageAnalysis.this.getTypedModel(i));
}
}
return typedModels;
}
@Override
public boolean isCheckable() {
return isInput();
}
@Override
public boolean isEnforceable() {
return isOutput();
}
@Override
public boolean isInput() {
return (bitMask & inputUsage.bitMask) != 0;
}
@Override
public boolean isMiddle() {
return (bitMask & middleUsage.bitMask) != 0;
}
@Override
public boolean isNone() {
return bitMask == 0;
}
@Override
public boolean isOutput() {
return (bitMask & outputUsage.bitMask) != 0;
}
@Override
public boolean isPrimitive() {
return (bitMask & PRIMITIVE_USAGE_BIT_MASK) != 0;
}
protected String toString(@NonNull String prefix) {
StringBuilder s = new StringBuilder();
s.append(prefix);
boolean first = true;
for (int i = 0; i < bit2typedModel.size(); i++) {
int iMask = 1 << i;
if ((bitMask & iMask) != 0) {
if (!first) {
s.append("|");
}
String name = bit2typedModel.get(i).getName();
s.append(name != null ? name : "$middle$");
first = false;
}
}
if (first) {
s.append("$none$");
}
return s.toString();
}
}
/**
* A DomainUsageConstant identifies a specific domain result from the DomainUsageAnalysis of an OCL AST node.
*/
protected class DomainUsageConstant extends AbstractDomainUsage
{
protected DomainUsageConstant(int bitMask) {
super(bitMask);
}
@Override
public void addUsedBy(@NonNull Element element) {}
@Override
public @NonNull DomainUsage cloneVariable() {
return this;
}
@Override
public @Nullable Iterable<Element> getElements() {
return null;
}
@Override
public boolean isConstant() {
return true;
}
@Override
public String toString() {
return toString("«constant»");
}
public @NonNull DomainUsageConstant union(@NonNull DomainUsageConstant usage) {
return RootDomainUsageAnalysis.this.getConstantUsage(bitMask | usage.bitMask);
}
}
/**
* A DomainUsageVariable identifies a constrained domain result from the DomainUsageAnalysis of an OCL AST node.
*/
protected class DomainUsageVariable extends AbstractDomainUsage
{
protected final @NonNull List<Element> usedBy = new ArrayList<>();
protected DomainUsageVariable(int bitMask) {
super(bitMask);
assert bitMask != 0;
}
@Override
public void addUsedBy(@NonNull Element element) {
usedBy.add(element);
}
@Override
public @NonNull DomainUsage cloneVariable() {
return new DomainUsageVariable(bitMask);
}
@Override
public @Nullable Iterable<Element> getElements() {
return usedBy;
}
@Override
public boolean isConstant() {
return false;
}
@Override
public String toString() {
return toString("«variable»");
}
}
/**
* A Nested DomainUsageAnalysis is used for a nested context such as an operation which is analyzed without
* regard to its invocation parameters. The invoking context is responsible for 'specializing' the generic
* domain analysis to suit the invocations.
*/
protected class Nested extends AbstractDomainUsageAnalysis
{
protected Nested() {
super(RootDomainUsageAnalysis.this.getEnvironmentFactory());
}
@Override
protected @NonNull RootDomainUsageAnalysis getRootAnalysis() {
return RootDomainUsageAnalysis.this;
}
}
/**
* No TypedModels is used by control infrastructure such as MappingLoops.
*/
private static final @NonNull Integer NONE_USAGE_BIT_MASK = 0;
/**
* The first bit is reserved for the primitive TypedModel that is used by DataTypes.
*/
private static final @NonNull Integer PRIMITIVE_USAGE_BIT_MASK = 1;
protected final @NonNull StandardLibrary standardLibrary;
/**
* The model name to typed model bit mapping.
*/
protected final @NonNull Map<@Nullable String, @NonNull Integer> name2bit = new HashMap<>();
/**
* The bit number to typed model 'mapping'.
*/
protected final @NonNull List<@NonNull TypedModel> bit2typedModel = new ArrayList<>();
/**
* Map from Integer to all in-use Constant Usages
*/
private final @NonNull Map<@NonNull Integer, @NonNull DomainUsageConstant> constantUsages = new HashMap<>();
/**
* Map from Integer to all single TypedModel Constant Usages
*/
private final @NonNull Map<@NonNull Integer, @NonNull DomainUsageConstant> validUsages = new HashMap<>();
/**
* The TypedModels that are not primitive and not checkable and not enforceable.
*/
private DomainUsageConstant middleUsage = null;
/**
* The TypedModels that are not enforceable.
*/
private DomainUsageConstant inputUsage = null;
/**
* The TypedModels that are enforceable.
*/
private DomainUsageConstant outputUsage = null;
/**
* The domains in which each class may be used.
*/
protected final @NonNull Map<org.eclipse.ocl.pivot.@NonNull Class, @NonNull DomainUsageConstant> class2usage = new HashMap<>();
/**
* The domains in which the containing class of a property may be used.
*/
protected final @NonNull Map<@NonNull Property, org.eclipse.qvtd.pivot.qvtcore.analysis.DomainUsage> property2containingClassUsage = new HashMap<>();
/**
* The nested analyses for declared operations.
*/
protected final @NonNull Map<@NonNull Operation, DomainUsageAnalysis.@NonNull Internal> operation2analysis = new HashMap<>();
private final @NonNull TypedModel primitiveTypeModel = QVTbaseFactory.eINSTANCE.createTypedModel();
private /*@LazyNonNull*/ OperationId oclAnyEqualsOperationId;
private /*@LazyNonNull*/ OperationId oclAnyNotEqualsOperationId;
private /*@LazyNonNull*/ OperationId oclElementOclContainerId;
private /*@LazyNonNull*/ OperationId oclElementOclContentsId;
private /*@LazyNonNull*/ Property oclElementOclContainerProperty;
private /*@LazyNonNull*/ Property oclElementOclContentsProperty;
/**
* The properties of the input models that are assigned by mappings and which cannot therefore
* be trusted to be loaded from the input models.
*/
private final @NonNull Set<@NonNull Property> dirtyProperties = new HashSet<>();
private final @NonNull Set<@NonNull EReference> dirtyEReferences = new HashSet<>();
protected RootDomainUsageAnalysis(@NonNull EnvironmentFactory environmentFactory) {
super(environmentFactory);
this.standardLibrary = context.getStandardLibrary();
primitiveTypeModel.setName("$primitive$");
add(primitiveTypeModel);
validUsages.put(NONE_USAGE_BIT_MASK, getConstantUsage(NONE_USAGE_BIT_MASK));
validUsages.put(PRIMITIVE_USAGE_BIT_MASK, getConstantUsage(PRIMITIVE_USAGE_BIT_MASK));
setUsage(primitiveTypeModel, getPrimitiveUsage());
}
protected int add(@NonNull TypedModel typedModel) {
int nextBit = bit2typedModel.size();
bit2typedModel.add(typedModel);
name2bit.put(typedModel.getName(), nextBit);
return nextBit;
}
public @NonNull DomainUsageAnalysis analyzeOperation(@NonNull Operation object) {
DomainUsageAnalysis.Internal analysis = operation2analysis.get(object);
if (analysis == null) {
analysis = createNestedAnalysis();
operation2analysis.put(object, analysis);
DomainUsage usage = analysis.visit(object);
setUsage(object, usage);
}
return analysis;
}
protected void analyzePropertyAssignments(@NonNull Transformation transformation) {
for (TreeIterator<EObject> tit = transformation.eAllContents(); tit.hasNext(); ) {
EObject eObject = tit.next();
if (eObject instanceof PropertyAssignment) {
PropertyAssignment propertyAssignment = (PropertyAssignment)eObject;
// if ("s.name := sn".equals(eObject.toString())) {
// eObject.toString();
// }
OCLExpression slotExpression = propertyAssignment.getSlotExpression();
assert slotExpression != null;
DomainUsage domainUsage = getUsage(PivotUtil.getType(slotExpression));
if (!domainUsage.isOutput() && !domainUsage.isMiddle()) {
Property targetProperty = ClassUtil.nonNullState(propertyAssignment.getTargetProperty());
// System.out.println("Dirty " + targetProperty + " for " + eObject);
dirtyProperties.add(targetProperty);
EObject eProperty = targetProperty.getESObject();
if (eProperty instanceof EReference) {
dirtyEReferences.add((EReference) eProperty);
}
}
}
}
for (@NonNull Property dirtyProperty : dirtyProperties) {
if (!dirtyProperty.isIsTransient()) {
System.err.println("Dirty " + dirtyProperty + " is not transient");
}
if (dirtyProperty.isIsReadOnly()) {
System.err.println("Dirty " + dirtyProperty + " is readonly");
}
if (dirtyProperty.isIsRequired()) {
System.err.println("Dirty " + dirtyProperty + " is required");
}
}
}
public @NonNull Map<Element, DomainUsage> analyzeTransformation(@NonNull Transformation transformation) {
int unenforceableMask = 0;
int enforceableMask = 0;
CompleteModel completeModel = context.getCompleteModel();
for (@NonNull TypedModel typedModel : ClassUtil.nullFree(transformation.getModelParameter())) {
if (typedModel == primitiveTypeModel) {
continue;
}
int nextBit = add(typedModel);
int bitMask = 1 << nextBit;
@NonNull DomainUsageConstant typedModelUsage = getConstantUsage(bitMask);
validUsages.put(bitMask, typedModelUsage);
boolean isEnforceable = false;
boolean isUnenforceable = false;
for (Rule rule : transformation.getRule()) {
for (Domain domain : rule.getDomain()) {
if (domain.getTypedModel() == typedModel) {
if (domain.isIsEnforceable()) {
isEnforceable = true;
}
else {
isUnenforceable = true;
}
}
}
}
if (isEnforceable) {
enforceableMask |= bitMask;
}
if (isUnenforceable) {
unenforceableMask |= bitMask;
}
setUsage(typedModel, typedModelUsage);
Variable ownedContext = typedModel.getOwnedContext();
if (ownedContext != null) {
setUsage(ownedContext, typedModelUsage);
}
Set<@NonNull CompleteClass> completeClasses = new HashSet<>();
// TODO There is an issue with extending transformations, because just classes extended by the
// the extending metamodel are tracked. Following code tries to workaround this issue. Also take into account
// that pivot/ocl are filtered. This might be an issue, when the transformations involve the own pivot metamodel
// (e.g. the CS2AS transformation for QVTo, Pivot-based QVTo AS extends Pivot metamodel).
// Set<Package> allPackages = QVTbaseUtil.getAllUsedPackages(typedModel);
// Deque<Package> pckQueue = new LinkedList<Package>(); // To track new discovered packages
// pckQueue.addAll(allPackages);
// while (!pckQueue.isEmpty()) {
// Package asPackage = pckQueue.pop();
for (org.eclipse.ocl.pivot.@NonNull Package asPackage : QVTbaseUtil.getAllUsedPackages(typedModel)) {
CompletePackage completePackage = completeModel.getCompletePackage(asPackage);
for (@NonNull CompleteClass completeClass : ClassUtil.nullFree(completePackage.getOwnedCompleteClasses())) {
for (@NonNull CompleteClass superCompleteClass : completeClass.getSuperCompleteClasses()) {
completeClasses.add(superCompleteClass);
}
}
}
for (@NonNull CompleteClass completeClass : completeClasses) {
for (org.eclipse.ocl.pivot.@NonNull Class asClass : ClassUtil.nullFree(completeClass.getPartialClasses())) {
DomainUsageConstant oldUsage = class2usage.get(asClass);
DomainUsageConstant classUsage = typedModelUsage;
if ((asClass instanceof DataType) && !(asClass instanceof CollectionType)) { // FIXME use a visitor ? perhaps CollectionTypes are not evidence of usage
classUsage = getPrimitiveUsage();
}
DomainUsageConstant newUsage = oldUsage != null ? classUsage.union(oldUsage) : classUsage;
class2usage.put(asClass, newUsage);
}
}
}
for (org.eclipse.ocl.pivot.@NonNull Class asClass : class2usage.keySet()) {
DomainUsage newUsage = class2usage.get(asClass);
assert newUsage != null;
for (@NonNull Property property : ClassUtil.nullFree(asClass.getOwnedProperties())) {
property2containingClassUsage.put(property, newUsage);
DomainUsage referredTypeUsage = getAnnotatedUsage(property);
if (referredTypeUsage == null) {
referredTypeUsage = visit(property.getType());
}
// System.out.println(property + " => " + referredTypeUsage);
// property2referredTypeUsage.put(property, referredTypeUsage);
}
}
class2usage.put(((StandardLibraryInternal)standardLibrary).getOclTypeType(), getAnyUsage()); // Needed by oclIsKindOf() etc
inputUsage = getConstantUsage(getAnyMask() & unenforceableMask);
outputUsage = getConstantUsage(getAnyMask() & enforceableMask);
middleUsage = getConstantUsage(getAnyMask() & ~unenforceableMask & ~enforceableMask & ~PRIMITIVE_USAGE_BIT_MASK);
Variable ownedContext = transformation.getOwnedContext();
if (ownedContext != null) {
setUsage(ownedContext, getAnyUsage());
}
analyzePropertyAssignments(transformation);
visit(transformation);
return element2usage;
}
@Override
public @Nullable DomainUsage basicGetUsage(@Nullable Element element) {
DomainUsage usage = super.basicGetUsage(element);
if (usage != null) {
return usage;
}
Operation operation = PivotUtil.getContainingOperation(element);
if (operation == null) {
return null;
}
DomainUsageAnalysis analyzeOperation = analyzeOperation(operation);
usage = analyzeOperation.basicGetUsage(element);
return usage;
}
protected @NonNull Nested createNestedAnalysis() {
return new Nested();
}
public @NonNull DomainUsage createVariableUsage(int intersectionMask) {
return new DomainUsageVariable(intersectionMask);
}
@Override // FIXME BUG 487257 Revise this
protected @NonNull DomainUsage getAllInstancesUsage(@NonNull OperationCallExp asCallExp, @NonNull DomainUsage sourceUsage) {
if (asCallExp.getOwnedSource().getTypeValue() instanceof DataType) {
return getPrimitiveUsage();
}
Area area = QVTcoreUtil.getContainingArea(asCallExp);
if (area instanceof CoreDomain) {
DomainUsage areaUsage = getUsage(area);
return intersection(sourceUsage, areaUsage);
}
else if (area instanceof Mapping) {
DomainUsage inputUsage = getNoneUsage();
for (Domain domain : ((Mapping)area).getDomain()) {
if (!domain.isIsEnforceable()) {
inputUsage = union(inputUsage, getUsage(domain));
}
}
if (inputUsage != getNoneUsage()) {
return intersection(sourceUsage, inputUsage);
}
else { // Att root so no domains, use input
return intersection(sourceUsage, getInputUsage());
}
}
else {
return sourceUsage;
}
}
public @NonNull DomainUsageAnalysis getAnalysis(@NonNull Operation operation) {
DomainUsageAnalysis analysis = operation2analysis.get(operation);
if (analysis == null) {
analysis = analyzeOperation(operation);
}
return analysis;
}
protected @Nullable DomainUsage getAnnotatedUsage(@NonNull Property property) {
DomainUsage referredTypeUsage = null;
for (Element annotation : property.getOwnedAnnotations()) {
if (annotation instanceof Annotation) {
Annotation annotation2 = (Annotation)annotation;
if (DomainUsage.QVT_DOMAINS_ANNOTATION_SOURCE.equals(annotation2.getName())) {
for (Detail detail : annotation2.getOwnedDetails()) {
if (DomainUsage.QVT_DOMAINS_ANNOTATION_REFERRED_DOMAIN.equals(detail.getName())) {
int mask = 0;
for (String value : detail.getValues()) {
Integer bit = name2bit.get(value.trim());
if (bit != null) {
mask |= 1 << bit;
}
}
referredTypeUsage = getValidUsage(mask);
}
}
}
}
}
return referredTypeUsage;
}
protected int getAnyMask() {
return (1 << bit2typedModel.size()) - 1;
}
public @NonNull DomainUsageConstant getAnyUsage() {
return getConstantUsage(getAnyMask());
}
/**
* @deprecated use getInputUsage();
*/
@Deprecated
public @NonNull DomainUsage getCheckableUsage() {
return getInputUsage();
}
@Override
public @NonNull DomainUsageConstant getConstantUsage(int bitMask) {
DomainUsageConstant usage = constantUsages.get(bitMask);
if (usage == null) {
usage = new DomainUsageConstant(bitMask);
constantUsages.put(bitMask, usage);
}
return usage;
}
/**
* @deprecated use getOutputUsage();
*/
@Deprecated
public @NonNull DomainUsage getEnforceableUsage() {
return getOutputUsage();
}
public @NonNull DomainUsage getInputUsage() {
return ClassUtil.nonNullState(inputUsage);
}
public @NonNull DomainUsage getMiddleUsage() {
return ClassUtil.nonNullState(middleUsage);
}
public @NonNull DomainUsage getNoneUsage() {
DomainUsageConstant noneUsage = constantUsages.get(NONE_USAGE_BIT_MASK);
assert noneUsage != null;
return noneUsage;
}
public @NonNull DomainUsage getOutputUsage() {
return ClassUtil.nonNullState(outputUsage);
}
// public @NonNull TypedModel getPrimitiveTypeModel() {
// return primitiveTypeModel;
// }
public @NonNull OperationId getOclContainerId() {
OperationId oclElementOclContainerId2 = oclElementOclContainerId;
if (oclElementOclContainerId2 == null) {
org.eclipse.ocl.pivot.Class oclElementType = standardLibrary.getOclElementType();
Operation operation = NameUtil.getNameable(oclElementType.getOwnedOperations(), "oclContainer");
assert operation != null;
oclElementOclContainerId = oclElementOclContainerId2 = operation.getOperationId();
}
return oclElementOclContainerId2;
}
public @NonNull Property getOclContainerProperty() {
Property oclElementOclContainerProperty2 = oclElementOclContainerProperty;
if (oclElementOclContainerProperty2 == null) {
org.eclipse.ocl.pivot.Class oclElementType = standardLibrary.getOclElementType();
oclElementOclContainerProperty2 = NameUtil.getNameable(oclElementType.getOwnedProperties(), "oclContainer");
assert oclElementOclContainerProperty2 != null;
oclElementOclContainerProperty = oclElementOclContainerProperty2;
}
return oclElementOclContainerProperty2;
}
public @NonNull OperationId getOclContentsId() {
OperationId oclElementOclContentsId2 = oclElementOclContentsId;
if (oclElementOclContentsId2 == null) {
org.eclipse.ocl.pivot.Class oclElementType = standardLibrary.getOclElementType();
Operation operation = NameUtil.getNameable(oclElementType.getOwnedOperations(), "oclContents");
assert operation != null;
oclElementOclContentsId = oclElementOclContentsId2 = operation.getOperationId();
}
return oclElementOclContentsId2;
}
public @NonNull Property getOclContentsProperty() {
Property oclElementOclContentsProperty2 = oclElementOclContentsProperty;
if (oclElementOclContentsProperty2 == null) {
org.eclipse.ocl.pivot.Class oclElementType = standardLibrary.getOclElementType();
oclElementOclContentsProperty2 = NameUtil.getNameable(oclElementType.getOwnedProperties(), "oclContents");
assert oclElementOclContentsProperty2 != null;
oclElementOclContentsProperty = oclElementOclContentsProperty2;
}
return oclElementOclContentsProperty2;
}
public @NonNull OperationId getOclAnyEqualsOperationId() {
OperationId oclAnyEqualsOperationId2 = oclAnyEqualsOperationId;
if (oclAnyEqualsOperationId2 == null) {
org.eclipse.ocl.pivot.Class oclAnyType = standardLibrary.getOclAnyType();
Operation operation = NameUtil.getNameable(oclAnyType.getOwnedOperations(), "=");
assert operation != null;
oclAnyEqualsOperationId = oclAnyEqualsOperationId2 = operation.getOperationId();
}
return oclAnyEqualsOperationId2;
}
public @NonNull OperationId getOclAnyNotEqualsOperationId() {
OperationId oclAnyNotEqualsOperationId2 = oclAnyNotEqualsOperationId;
if (oclAnyNotEqualsOperationId2 == null) {
org.eclipse.ocl.pivot.Class oclAnyType = standardLibrary.getOclAnyType();
Operation operation = NameUtil.getNameable(oclAnyType.getOwnedOperations(), "<>");
assert operation != null;
oclAnyNotEqualsOperationId = oclAnyNotEqualsOperationId2 = operation.getOperationId();
}
return oclAnyNotEqualsOperationId2;
}
public @NonNull TypedModel getPrimitiveTypeModel() {
return primitiveTypeModel;
}
public @NonNull DomainUsageConstant getPrimitiveUsage() {
DomainUsageConstant primitiveUsage = constantUsages.get(PRIMITIVE_USAGE_BIT_MASK);
assert primitiveUsage != null;
return primitiveUsage;
}
@Override
protected @NonNull RootDomainUsageAnalysis getRootAnalysis() {
return this;
}
public @NonNull TypedModel getTypedModel(int i) {
return bit2typedModel.get(i);
}
/* @Override
public @Nullable DomainUsage getUsage(@Nullable EObject element) {
DomainUsage domainUsage = super.getUsage(element);
if ((domainUsage == null) && (element instanceof Property)) {
domainUsage = property2referredTypeUsage.get(element);
}
return domainUsage;
} */
@Override
public @NonNull DomainUsage getUsage(@NonNull Element element) {
Operation operation = PivotUtil.getContainingOperation(element);
if (operation != null) {
DomainUsageAnalysis analyzeOperation = analyzeOperation(operation);
return ClassUtil.nonNullState(analyzeOperation.getUsage(element));
}
else {
return super.getUsage(element);
}
}
/**
* Return a corresponding non-null usage if bitMask identifies a single domain.
*/
public @Nullable DomainUsageConstant getValidUsage(int bitMask) {
return validUsages.get(bitMask);
}
/**
* Return either a constant usage if usage is for a single domain,
* else re-use a variable usgae else or create
* a variable usage for the multiple domains.
*/
public @NonNull DomainUsage getValidOrVariableUsage(@NonNull DomainUsage usage) {
int bitMask = ((DomainUsage.Internal)usage).getMask();
DomainUsage validUsage = getValidUsage(bitMask);
if (validUsage != null) {
return validUsage;
}
else if (!usage.isConstant()) {
return usage;
}
else {
return createVariableUsage(bitMask);
}
}
/**
* Return true if a mapping may assign this property in an input model.
*/
public boolean isDirty(@NonNull EReference eReference) {
return dirtyEReferences.contains(eReference);
}
/**
* Return true if a mapping may assign this property in an input model.
*/
public boolean isDirty(@NonNull Property property) {
return property.isIsTransient() || dirtyProperties.contains(property);
}
// private boolean isPivotMMPackage(Package p) {
// String pURI = p.getURI();
// return PivotPackage.eNS_URI.equals(pURI) ||
// OCLstdlib.STDLIB_URI.equals(pURI);
// }
}