blob: 18b354d94882a5d77547d73fe5e36f23b3e1f53f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 itemis AG (http://www.itemis.eu) 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
*******************************************************************************/
package org.eclipse.osbp.ecview.dsl.extensions;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.common.types.JvmAnyTypeReference;
import org.eclipse.xtext.common.types.JvmArrayType;
import org.eclipse.xtext.common.types.JvmConstraintOwner;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmDelegateTypeReference;
import org.eclipse.xtext.common.types.JvmGenericArrayTypeReference;
import org.eclipse.xtext.common.types.JvmLowerBound;
import org.eclipse.xtext.common.types.JvmMultiTypeReference;
import org.eclipse.xtext.common.types.JvmParameterizedTypeReference;
import org.eclipse.xtext.common.types.JvmPrimitiveType;
import org.eclipse.xtext.common.types.JvmSpecializedTypeReference;
import org.eclipse.xtext.common.types.JvmType;
import org.eclipse.xtext.common.types.JvmTypeConstraint;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.TypesFactory;
import org.eclipse.xtext.common.types.util.TypeReferences;
import org.eclipse.xtext.common.types.util.TypesSwitch;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import com.google.inject.Singleton;
// TODO: Auto-generated Javadoc
/**
* The Class SuperTypeCollector.
*
* @author Sebastian Zarnekow - Initial contribution and API
* @author Sven Efftinge
*/
@Deprecated
@Singleton
@SuppressWarnings("restriction")
public class SuperTypeCollector {
/**
* The Interface SuperTypeAcceptor.
*/
public interface SuperTypeAcceptor {
/**
* Accept.
*
* @param superType
* a found super type
* @param distance
* the distance to the starting type. StringBuilder has a
* distance 1 to AbstractStringBuilder, distance 1 and 2 to
* CharSequence and distance 2 to Appendable.
* @return true, if successful
*/
boolean accept(JvmTypeReference superType, int distance);
}
/** The factory. */
@Inject(optional=true)
private TypesFactory factory = TypesFactory.eINSTANCE;
/** The type references. */
@Inject
private TypeReferences typeReferences;
/**
* New ref.
*
* @param type
* the type
* @return the jvm type reference
*/
protected JvmTypeReference newRef(JvmType type) {
if (type instanceof JvmArrayType) {
JvmTypeReference componentType = newRef(((JvmArrayType) type).getComponentType());
JvmGenericArrayTypeReference reference = factory.createJvmGenericArrayTypeReference();
reference.setComponentType(componentType);
return reference;
} else {
JvmParameterizedTypeReference reference = factory.createJvmParameterizedTypeReference();
reference.setType(type);
return reference;
}
}
/**
* Collect super types.
*
* @param type
* the type
* @return the sets the
*/
public Set<JvmTypeReference> collectSuperTypes(JvmType type) {
return collectSuperTypes(newRef(type));
}
/**
* Collect super types.
*
* @param type
* the type
* @return the sets the
*/
public Set<JvmTypeReference> collectSuperTypes(JvmTypeReference type) {
final Set<JvmTypeReference> result = Sets.newLinkedHashSet();
final Set<JvmType> rawTypes = Sets.newHashSet();
doCollectSupertypeData(type, new SuperTypeAcceptor() {
public boolean accept(JvmTypeReference superType, int distance) {
JvmType rawType = superType.getType();
if (rawType != null && !rawType.eIsProxy() && rawTypes.add(superType.getType())) {
result.add(superType);
return true;
}
return false;
}
});
return result;
}
/**
* Collect super types.
*
* @param type
* the type
* @param acceptor
* the acceptor
*/
public void collectSuperTypes(JvmTypeReference type, SuperTypeAcceptor acceptor) {
doCollectSupertypeData(type, acceptor);
}
/**
* Collect super type names.
*
* @param type
* the type
* @return the sets the
*/
public Set<String> collectSuperTypeNames(JvmType type) {
return collectSuperTypeNames(newRef(type));
}
/**
* Collect super types as raw types.
*
* @param type
* the type
* @return the sets the
*/
public Set<JvmType> collectSuperTypesAsRawTypes(JvmTypeReference type) {
final Set<JvmType> result = Sets.newLinkedHashSet();
doCollectSupertypeData(type, new SuperTypeAcceptor() {
public boolean accept(JvmTypeReference superType, int distance) {
JvmType rawType = superType.getType();
if (rawType != null && !rawType.eIsProxy()) {
boolean notYetSeen = result.add(superType.getType());
return notYetSeen;
}
return false;
}
});
return result;
}
/**
* Collect super type names.
*
* @param type
* the type
* @return the sets the
*/
public Set<String> collectSuperTypeNames(JvmTypeReference type) {
final Set<String> result = Sets.newLinkedHashSet();
doCollectSupertypeData(type, new SuperTypeAcceptor() {
public boolean accept(JvmTypeReference superType, int distance) {
String name = getSuperTypeName(superType);
if (name != null)
return result.add(name);
return false;
}
public String getSuperTypeName(JvmTypeReference typeReference) {
if (typeReference instanceof JvmParameterizedTypeReference) {
JvmType rawType = typeReference.getType();
if (rawType != null && !rawType.eIsProxy()) {
return rawType.getIdentifier();
}
return null;
} else {
return typeReference.getIdentifier();
}
}
});
return result;
}
/**
* Do collect supertype data.
*
* @param type
* the type
* @param acceptor
* the acceptor
*/
public void doCollectSupertypeData(JvmTypeReference type, SuperTypeAcceptor acceptor) {
if (type != null) {
Implementation implementation = new Implementation(acceptor, typeReferences);
implementation.doSwitch(type);
}
}
/**
* The Class Implementation.
*/
@Deprecated
static class Implementation extends TypesSwitch<Boolean> {
/** The collecting. */
private boolean collecting = false;
/** The acceptor. */
private SuperTypeAcceptor acceptor;
/** The level. */
private int level;
/** The references. */
private final TypeReferences references;
/**
* Instantiates a new implementation.
*
* @param acceptor
* the acceptor
* @param references
* the references
*/
Implementation(SuperTypeAcceptor acceptor, TypeReferences references) {
this.acceptor = acceptor;
this.references = references;
this.level = 0;
}
/* (non-Javadoc)
* @see org.eclipse.emf.ecore.util.Switch#doSwitch(org.eclipse.emf.ecore.EObject)
*/
@Override
public Boolean doSwitch(EObject theEObject) {
if (theEObject == null)
return Boolean.FALSE;
return super.doSwitch(theEObject);
}
/* (non-Javadoc)
* @see org.eclipse.xtext.common.types.util.TypesSwitch#caseJvmTypeReference(org.eclipse.xtext.common.types.JvmTypeReference)
*/
@Override
public Boolean caseJvmTypeReference(JvmTypeReference object) {
if (!object.eIsProxy()) {
if (!collecting || acceptor.accept(object, level)) {
collecting = true;
if (object.getType() != null)
doSwitch(object.getType());
}
}
return Boolean.FALSE;
}
/* (non-Javadoc)
* @see org.eclipse.xtext.common.types.util.TypesSwitch#caseJvmGenericArrayTypeReference(org.eclipse.xtext.common.types.JvmGenericArrayTypeReference)
*/
@Override
public Boolean caseJvmGenericArrayTypeReference(JvmGenericArrayTypeReference object) {
if (!object.eIsProxy()) {
level++;
final SuperTypeAcceptor original = acceptor;
try {
final boolean[] outerCollecting = { collecting };
acceptor = new SuperTypeAcceptor() {
public boolean accept(JvmTypeReference superType, int distance) {
JvmTypeReference arraySuperType = references.createArrayType(superType);
boolean result = !outerCollecting[0];
if (!outerCollecting[0] || (result = original.accept(arraySuperType, distance))) {
outerCollecting[0] = true;
}
if (references.is(superType, Object.class)) {
outerCollecting[0] = true;
result = original.accept(superType, distance + 1) || result;
result = original.accept(references.getTypeForName(Serializable.class, superType.getType()), distance + 1) || result;
result = original.accept(references.getTypeForName(Cloneable.class, superType.getType()), distance + 1) || result;
}
return result;
}
};
if (object.getComponentType() != null) {
collecting = true;
doSwitch(object.getComponentType());
}
} finally {
acceptor = original;
}
JvmArrayType rawArrayType = object.getType();
if (rawArrayType != null) {
JvmType rawType = rawArrayType.getComponentType();
while(rawType instanceof JvmArrayType) {
rawType = ((JvmArrayType) rawType).getComponentType();
}
if (rawType instanceof JvmPrimitiveType) {
collecting = true;
doSwitch(references.getTypeForName(Serializable.class, rawType));
doSwitch(references.getTypeForName(Cloneable.class, rawType));
}
}
level--;
}
return Boolean.FALSE;
}
/* (non-Javadoc)
* @see org.eclipse.xtext.common.types.util.TypesSwitch#caseJvmMultiTypeReference(org.eclipse.xtext.common.types.JvmMultiTypeReference)
*/
@Override
public Boolean caseJvmMultiTypeReference(JvmMultiTypeReference object) {
if (!object.eIsProxy()) {
collecting = true;
level++;
for(JvmTypeReference reference: object.getReferences()) {
doSwitch(reference);
}
level--;
}
return Boolean.FALSE;
}
/* (non-Javadoc)
* @see org.eclipse.xtext.common.types.util.TypesSwitch#caseJvmDelegateTypeReference(org.eclipse.xtext.common.types.JvmDelegateTypeReference)
*/
@Override
public Boolean caseJvmDelegateTypeReference(JvmDelegateTypeReference object) {
if (!object.eIsProxy()) {
collecting = true;
doSwitch(object.getDelegate());
}
return Boolean.FALSE;
}
/* (non-Javadoc)
* @see org.eclipse.xtext.common.types.util.TypesSwitch#caseJvmSpecializedTypeReference(org.eclipse.xtext.common.types.JvmSpecializedTypeReference)
*/
@Override
public Boolean caseJvmSpecializedTypeReference(JvmSpecializedTypeReference object) {
if (!object.eIsProxy()) {
collecting = true;
level++;
JvmTypeReference equivalent = object.getEquivalent();
if (equivalent != null)
doSwitch(equivalent);
level--;
}
return Boolean.FALSE;
}
/* (non-Javadoc)
* @see org.eclipse.xtext.common.types.util.TypesSwitch#caseJvmAnyTypeReference(org.eclipse.xtext.common.types.JvmAnyTypeReference)
*/
@Override
public Boolean caseJvmAnyTypeReference(JvmAnyTypeReference object) {
return Boolean.FALSE;
}
/* (non-Javadoc)
* @see org.eclipse.xtext.common.types.util.TypesSwitch#caseJvmDeclaredType(org.eclipse.xtext.common.types.JvmDeclaredType)
*/
@Override
public Boolean caseJvmDeclaredType(JvmDeclaredType object) {
if (!object.eIsProxy()) {
level++;
for (JvmTypeReference superType : object.getSuperTypes()) {
doSwitch(superType);
}
level--;
}
return Boolean.FALSE;
}
/* (non-Javadoc)
* @see org.eclipse.xtext.common.types.util.TypesSwitch#caseJvmTypeConstraint(org.eclipse.xtext.common.types.JvmTypeConstraint)
*/
@Override
public Boolean caseJvmTypeConstraint(JvmTypeConstraint object) {
if (object.getTypeReference() != null)
return doSwitch(object.getTypeReference());
return Boolean.FALSE;
}
/* (non-Javadoc)
* @see org.eclipse.xtext.common.types.util.TypesSwitch#caseJvmConstraintOwner(org.eclipse.xtext.common.types.JvmConstraintOwner)
*/
@Override
public Boolean caseJvmConstraintOwner(JvmConstraintOwner object) {
if (!object.eIsProxy()) {
List<JvmTypeConstraint> constraints = object.getConstraints();
boolean boundProcessed = false;
if (!constraints.isEmpty()) {
for(JvmTypeConstraint constraint: constraints) {
if (constraint instanceof JvmLowerBound) {
doSwitch(constraint);
boundProcessed = true;
}
}
if (!boundProcessed) {
for(JvmTypeConstraint constraint: constraints) {
doSwitch(constraint);
boundProcessed = true;
}
}
}
if (!boundProcessed) {
JvmType objectType = references.findDeclaredType(Object.class, object);
if (objectType != null)
doSwitch(references.createTypeRef(objectType));
}
}
return Boolean.FALSE;
}
}
/**
* Checks if is super type.
*
* @param subType
* the sub type
* @param superType
* the super type
* @return true, if is super type
*/
public boolean isSuperType(JvmDeclaredType subType, JvmDeclaredType superType) {
if (subType==null || superType == null)
return false;
return collectSuperTypesAsRawTypes(newRef(subType)).contains(superType);
}
}