/* * Created on Nov 3, 2005 */ package x10.wala.translator; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import polyglot.types.ClassType; import polyglot.types.JavaArrayType; import polyglot.types.JavaPrimitiveType; import polyglot.types.ObjectType; import polyglot.types.Type; import polyglot.types.TypeSystem; import x10.types.ConstrainedType; import x10.types.MacroType; import x10.types.ParameterType; import x10.types.VoidType; import x10.types.X10ClassType; import x10.wala.translator.X10toCAstTranslator.PolyglotJavaParametricType; import x10.wala.translator.X10toCAstTranslator.PolyglotJavaType; import com.ibm.wala.cast.java.types.JavaPrimitiveTypeMap; import com.ibm.wala.cast.tree.CAstType; import com.ibm.wala.cast.tree.impl.CAstTypeDictionaryImpl; import com.ibm.wala.util.debug.Assertions; public class X10TypeDictionary extends CAstTypeDictionaryImpl { private final class PolyglotJavaArrayType implements CAstType.Array { private final Type fEltPolyglotType; private final CAstType fEltCAstType; private PolyglotJavaArrayType(JavaArrayType arrayType) { super(); fEltPolyglotType = arrayType.base(); fEltCAstType = getCAstTypeFor(fEltPolyglotType); } public int getNumDimensions() { return 1; // always 1 for Java } public CAstType getElementType() { return fEltCAstType; } public String getName() { return "[" + fEltCAstType.getName(); } @SuppressWarnings("unchecked") public Collection getSupertypes() { if (fEltPolyglotType.isJavaPrimitive()) return Collections.singleton(getCAstTypeFor(fTypeSystem.Any())); Assertions.productionAssertion(fEltPolyglotType.isReference(), "Non-primitive, non-reference array element type!"); ObjectType baseRefType = (ObjectType) fEltPolyglotType; Collection<CAstType> supers = new ArrayList<CAstType>(); for (Iterator superIter = baseRefType.interfaces().iterator(); superIter.hasNext(); ) { supers.add(getCAstTypeFor(superIter.next())); } if (baseRefType instanceof ClassType) { ClassType baseClassType = (ClassType) baseRefType; if (baseClassType.superClass() != null) supers.add(getCAstTypeFor(baseRefType.superClass())); } return supers; } } protected final TypeSystem fTypeSystem; protected final X10toCAstTranslator fTranslator; public X10TypeDictionary(TypeSystem typeSystem, X10toCAstTranslator translator) { fTypeSystem = typeSystem; fTranslator = translator; } public CAstType SUPER_getCAstTypeFor(Object astType) { CAstType type = super.getCAstTypeFor(astType); // Handle the case where we haven't seen an AST decl for some type before // processing a reference. This can certainly happen with classes in byte- // code libraries, for which we never see an AST decl. // In this case, just create a new type and return that. if (type == null) { final Type polyglotType = (Type) astType; if (polyglotType.isClass()) type = fTranslator.new PolyglotJavaType((ClassType) astType, this, fTypeSystem); else if (polyglotType.isJavaPrimitive()) { type = JavaPrimitiveTypeMap.lookupType(((JavaPrimitiveType) polyglotType).name().toString()); } else if (polyglotType instanceof VoidType) { type = JavaPrimitiveTypeMap.VoidType; } else if (polyglotType.isArray()) { type = new PolyglotJavaArrayType((JavaArrayType) polyglotType); } else Assertions.UNREACHABLE("getCAstTypeFor() passed type that is not primitive, array, or class?"); super.map(astType, type); } return type; } public CAstType getCAstTypeFor(Object astType) { if (astType instanceof ConstrainedType) { return getCAstTypeFor(((ConstrainedType) astType).baseType().get()); } if (astType instanceof MacroType) { return getCAstTypeFor(((MacroType) astType).definedType()); } if (astType instanceof X10ClassType && ((X10ClassType) astType).typeArguments() != null && ((X10ClassType) astType).typeArguments().size() > 0) { X10ClassType classType = (X10ClassType) astType; Type baseType = classType.def().asType(); List<Type> typeArgs = classType.typeArguments(); PolyglotJavaParametricType result = ((X10toCAstTranslator) fTranslator).new PolyglotJavaParametricType((ClassType) baseType, typeArgs, this, fTypeSystem); super.map(astType, result); return result; } if (astType instanceof JavaPrimitiveType) { JavaPrimitiveType primitiveType = (JavaPrimitiveType) astType; String javaPrimitiveName = X10IdentityMapper.getJavaPrimitiveTypeFor(primitiveType.fullName().toString()); final CAstType castType = JavaPrimitiveTypeMap.lookupType(javaPrimitiveName); super.map(astType, castType); return castType; } if (astType instanceof ParameterType) { final ParameterType parameterType = (ParameterType) astType; final CAstType castType = new CAstType() { private Collection<CAstType> justObject = new HashSet<CAstType>(); public String getName() { return parameterType.name().toString(); } public Collection getSupertypes() { return justObject; } }; super.map(astType, castType); return castType; } return SUPER_getCAstTypeFor(astType); } }