blob: a48e1e2d94d9ccaefe2aa810997f9e9bee097502 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2018 Willink Transformations and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* E.D.Willink - Initial API and implementation
*******************************************************************************/
package org.eclipse.ocl.pivot.internal.library.executor;
import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.CompleteInheritance;
import org.eclipse.ocl.pivot.Constraint;
import org.eclipse.ocl.pivot.InheritanceFragment;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.StandardLibrary;
import org.eclipse.ocl.pivot.TemplateParameter;
import org.eclipse.ocl.pivot.TemplateParameters;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.ids.IdManager;
import org.eclipse.ocl.pivot.ids.IdResolver;
import org.eclipse.ocl.pivot.ids.OperationId;
import org.eclipse.ocl.pivot.ids.TypeId;
import org.eclipse.ocl.pivot.internal.elements.AbstractExecutorClass;
import org.eclipse.ocl.pivot.oclstdlib.OCLstdlibTables;
import org.eclipse.ocl.pivot.utilities.ArrayIterable;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.TypeUtil;
import org.eclipse.ocl.pivot.values.OCLValue;
/**
* An ExecutorType defines a Type using a compact representation suitable for efficient
* execution and static construction.
*/
public abstract class ExecutorType extends AbstractExecutorClass implements ExecutorTypeArgument
{
/**
* Depth ordered inheritance fragments. OclAny at depth 0, OclSelf at depth size-1.
*/
private @NonNull ExecutorFragment @Nullable [] fragments = null;
/**
* The index in fragments at which inheritance fragments at a given depth start.
* depthIndexes[0] is always zero since OclAny is always at depth 0.
* depthIndexes[depthIndexes.length-2] is always depthIndexes.length-1 since OclSelf is always at depth depthIndexes.length-2.
* depthIndexes[depthIndexes.length-1] is always depthIndexes.length to provide an easy end stop.
*/
private int[] indexes = null;
protected final org.eclipse.ocl.pivot.@NonNull Package evaluationPackage;
private final @NonNull TemplateParameters typeParameters;
private /*@LazyNonNull*/ DomainProperties allProperties;
public ExecutorType(@NonNull String name, @NonNull ExecutorPackage evaluationPackage, int flags, @NonNull ExecutorTypeParameter @NonNull ... typeParameters) {
super(name, flags);
this.evaluationPackage = evaluationPackage;
this.typeParameters = TypeUtil.createTemplateParameters(typeParameters);
}
@Override
public boolean conformsTo(@NonNull StandardLibrary standardLibrary, @NonNull Type type) {
CompleteInheritance thatInheritance = type.getInheritance(standardLibrary);
if (this == thatInheritance) {
return true;
}
return thatInheritance.isSuperInheritanceOf(this);
}
@Override
public org.eclipse.ocl.pivot.Class flattenedType() {
return this;
}
@Override
public final @NonNull FragmentIterable getAllProperSuperFragments() {
@NonNull InheritanceFragment @NonNull [] fragments2 = ClassUtil.nonNullState(fragments);
return new FragmentIterable(fragments2, 0, fragments2.length-1);
}
@Override
public @NonNull FragmentIterable getAllSuperFragments() {
return new FragmentIterable(ClassUtil.nonNullState(fragments));
}
@Override
public @NonNull Type getCommonType(@NonNull IdResolver idResolver, @NonNull Type type) {
if (this == type) {
return this.getPivotClass();
}
CompleteInheritance firstInheritance = this;
CompleteInheritance secondInheritance = type.getInheritance(idResolver.getStandardLibrary());
CompleteInheritance commonInheritance = firstInheritance.getCommonInheritance(secondInheritance);
return commonInheritance.getPivotClass();
}
@Override
public int getDepth() {
return indexes.length-2;
}
@Override
public @NonNull Iterable<@NonNull InheritanceFragment> getFragments() {
return new ArrayIterable<@NonNull InheritanceFragment>(fragments);
}
@Override
public @NonNull ExecutorFragment getFragment(int fragmentNumber) {
return ClassUtil.nonNullState(fragments)[fragmentNumber];
}
@Override
public int getIndex(int fragmentNumber) {
return indexes[fragmentNumber];
}
@Override
public int getIndexes(){
return indexes.length;
}
@Override
public @NonNull CompleteInheritance getInheritance(@NonNull StandardLibrary standardLibrary) {
return this;
}
@Override
public @Nullable Operation getMemberOperation(@NonNull OperationId operationId) {
throw new UnsupportedOperationException(); // FIXME
}
@Override
public @Nullable Property getMemberProperty(@NonNull String name) {
DomainProperties allProperties2 = allProperties;
if (allProperties2 == null) {
allProperties = allProperties2 = new DomainProperties(this);
}
return allProperties2.getMemberProperty(name);
}
@Override
public @NonNull String getMetaTypeName() {
throw new UnsupportedOperationException();
}
@Override
public org.eclipse.ocl.pivot.@NonNull Class getNormalizedType(@NonNull StandardLibrary standardLibrary) {
return this;
}
@Override
public @NonNull List<Constraint> getOwnedInvariants() {
throw new UnsupportedOperationException(); // FIXME
}
@Override
public @NonNull List<Property> getOwnedProperties() {
return getSelfFragment().getLocalProperties();
}
@Override
public @NonNull List<Operation> getOwnedOperations() {
return getSelfFragment().getLocalOperations();
}
@Override
public org.eclipse.ocl.pivot.@NonNull Package getOwningPackage() {
return evaluationPackage;
}
@Override
public @NonNull List<Constraint> getOwnedConstraints() {
throw new UnsupportedOperationException(); // FIXME
}
@Override
public org.eclipse.ocl.pivot.@NonNull Class getPivotClass() {
return this;
}
@Override
public @NonNull ExecutorFragment getSelfFragment() {
return getFragment(ClassUtil.nonNullState(fragments).length-1);
}
public @NonNull StandardLibrary getStandardLibrary() {
return OCLstdlibTables.LIBRARY;
}
@Override
public @NonNull List<org.eclipse.ocl.pivot.Class> getSuperClasses() {
return getSelfFragment().getSuperClasses();
}
@Override
public final @NonNull FragmentIterable getSuperFragments(int depth) {
return new FragmentIterable(ClassUtil.nonNullState(fragments), indexes[depth], indexes[depth+1]);
}
// public @NonNull TypeId getTypeId() {
// throw new UnsupportedOperationException(); // FIXME
// }
@Override
public @NonNull TemplateParameters getTypeParameters() {
return typeParameters;
}
public void initFragments(@NonNull ExecutorFragment @NonNull [] fragments, int[] depthCounts) {
int[] indexes = new int[depthCounts.length+1];
indexes[0] = 0;
for (int i = 0; i < depthCounts.length; i++) {
indexes[i+1] = indexes[i] + depthCounts[i];
}
this.fragments = fragments;
this.indexes = indexes;
}
@Override
public org.eclipse.ocl.pivot.@NonNull Class isClass() {
return this;
}
@Override
public boolean isEqualTo(@NonNull StandardLibrary standardLibrary, @NonNull Type type) {
return this == type;
}
@Override
public boolean isEqualToUnspecializedType(@NonNull StandardLibrary standardLibrary, @NonNull Type type) {
return this == type;
}
@Override
public boolean isOrdered() {
return (flags & ORDERED) != 0;
}
@Override
public @Nullable TemplateParameter isTemplateParameter() {
return null;
}
@Override
public boolean isUnique() {
return (flags & UNIQUE) != 0;
}
@Override
public boolean oclEquals(@NonNull OCLValue thatValue) {
if (!(thatValue instanceof Type)) {
return false;
}
TypeId thisTypeId = getTypeId();
TypeId thatTypeId = ((Type)thatValue).getTypeId();
return thisTypeId.equals(thatTypeId);
}
@Override
public int oclHashCode() {
return getTypeId().hashCode();
}
@Override
public String toString() {
if (evaluationPackage.getPackageId() != IdManager.METAMODEL) {
return String.valueOf(evaluationPackage) + "::" + String.valueOf(name); //$NON-NLS-1$
}
else {
return String.valueOf(name);
}
}
}