diff options
Diffstat (limited to 'jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/TypeUtil.java')
-rw-r--r-- | jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/TypeUtil.java | 597 |
1 files changed, 0 insertions, 597 deletions
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/TypeUtil.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/TypeUtil.java deleted file mode 100644 index 8a465d8d3..000000000 --- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/TypeUtil.java +++ /dev/null @@ -1,597 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 Oracle Corporation. - * 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: - * Cameron Bateman/Oracle - initial API and implementation - * - ********************************************************************************/ - -package org.eclipse.jst.jsf.common.util; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jdt.core.IField; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.ITypeParameter; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.core.Signature; -import org.eclipse.jst.jsf.common.JSFCommonPlugin; -import org.eclipse.jst.jsf.common.internal.types.TypeConstants; -import org.eclipse.jst.jsf.common.internal.types.TypeInfoCache; - -/** - * Utility for handling IType's and type signatures - * - * Class is static and cannot be extended or instantiated. - * - * @author cbateman - * - */ -public final class TypeUtil -{ - static IType resolveType(final IType owningType, final String typeSignature) - { - // if type signature is already resolved then simply look it up - if (typeSignature.charAt(0) == Signature.C_RESOLVED - || (Signature.getTypeSignatureKind(typeSignature) == Signature.BASE_TYPE_SIGNATURE) - || (Signature.getTypeSignatureKind(typeSignature) == Signature.ARRAY_TYPE_SIGNATURE - && Signature.getElementType(typeSignature).charAt(0) == Signature.C_RESOLVED)) - { - IType type = null; - - try - { - type = owningType.getJavaProject(). - findType(getFullyQualifiedName(typeSignature)); - } - catch (JavaModelException jme) - { - // do nothing; return type == null; - } - - return type; - } - - - return resolveTypeRelative(owningType, typeSignature); - } - - /** - * Fully equivalent to: - * - * #resolveTypeSignature(owningType, typeSignature, true) - * - * If resolved, type signature has generic type parameters erased (absent). - * - * @param owningType - * @param typeSignature - * @return the resolved type signature for typeSignature in owningType or - * typeSignature unchanged if cannot resolve. - */ - public static String resolveTypeSignature(final IType owningType, final String typeSignature) - { - return resolveTypeSignature(owningType, typeSignature, true); - } - - /** - * Resolve typeSignature in the context of owningType. This method will return - * a type erased signture if eraseTypeParameters == true and will attempt to - * resolve and include parameters if eraseTypeParamters == false - * - * NOTE: special rules apply to the way unresolved type parameters and wildcards - * are resolved: - * - * 1) If a fully unresolved type parameter is found, then it will be replaced with Ljava.lang.Object; - * - * i.e. List<T> -> Ljava.util.List<Ljava.lang.Object;>; for any unresolved T. - * - * 2) Any bounded wildcard will be replaced by the bound: - * - * i.e. List<? extends String> -> Ljava.util.List<Ljava.lang.String;>; - * i.e. List<? super String> -> Ljava.util.List<Ljava.lang.String;>; - * - * Note limitation here: bounds that use 'super' will take the "best case" scenario that the list - * type is of that type. - * - * 3) The unbounded wildcard will be replaced by Ljava.lang.Object; - * - * i.e. List<?> -> Ljava.util.List<Ljava.lang.Object;>; - * - * - * The reason for this substition is to return the most accurate reasonable approximation - * of the type within what is known by owningType - * - * @param owningType - * @param typeSignature - * @param eraseTypeParameters if set to false, type parameters are resolved included - * in the signature - * @return the resolved type signature for typeSignature in owningType or - * typeSignature unchanged if cannot resolve. - */ - public static String resolveTypeSignature(final IType owningType, final String typeSignature, boolean eraseTypeParameters) - { - final int sigKind = Signature.getTypeSignatureKind(typeSignature); - - switch (sigKind) - { - case Signature.BASE_TYPE_SIGNATURE: - return typeSignature; - - case Signature.ARRAY_TYPE_SIGNATURE: - { - final String elementType = Signature.getElementType(typeSignature); - - if (Signature.getTypeSignatureKind(elementType) == Signature.BASE_TYPE_SIGNATURE) - { - return typeSignature; - } - - final String resolvedElementType = resolveSignatureRelative(owningType, elementType, eraseTypeParameters); - String resultType = ""; //$NON-NLS-1$ - for (int i = 0; i < Signature.getArrayCount(typeSignature);i++) - { - resultType+=Signature.C_ARRAY; - } - - return resultType+resolvedElementType; - } - - case Signature.TYPE_VARIABLE_SIGNATURE: - return resolveSignatureRelative(owningType, typeSignature, eraseTypeParameters); - - case Signature.CLASS_TYPE_SIGNATURE: - return resolveSignatureRelative(owningType, typeSignature, eraseTypeParameters); - - case Signature.WILDCARD_TYPE_SIGNATURE: - // strip the wildcard and try again. Too bad Signature doesn't seem to have a method - // for this - if (typeSignature.charAt(0) == Signature.C_STAR) - { - return TypeConstants.TYPE_JAVAOBJECT; - } - return resolveTypeSignature(owningType, typeSignature.substring(1), eraseTypeParameters); - - case Signature.CAPTURE_TYPE_SIGNATURE: - // strip the capture and try again - return resolveTypeSignature(owningType, Signature.removeCapture(typeSignature), eraseTypeParameters); -// case Signature.TYPE_VARIABLE_SIGNATURE: -// resolveSignatureRelative(owningType, typeSignature, eraseTypeParameters); - - default: - return typeSignature; - } - } - - /** - * @param owningType -- type relative to which typeSignature will be resolved - * @param typeSignature -- non-array type signature - * @return the resolved type signature if possible or typeSignature if not - */ - private static String resolveSignatureRelative(final IType owningType, final String typeSignature, final boolean eraseTypeParameters) - { - // if already fully resolved, return the input - if (typeSignature.charAt(0) == Signature.C_RESOLVED) - { - return typeSignature; - } - - List<String> typeParameters = new ArrayList<String>(); - - IType resolvedType = resolveTypeRelative(owningType, typeSignature); - - if (resolvedType != null) - { - if (!eraseTypeParameters) - { - // ensure that type parameters are resolved recursively - for (String typeParam : Signature.getTypeArguments(typeSignature)) - { - typeParam = Signature.removeCapture(typeParam); - // check and remove bound wildcarding (extends/super/?) - if (Signature.getTypeSignatureKind(typeParam) == Signature.WILDCARD_TYPE_SIGNATURE) - { - // convert ? to Object, strip extends/super - if (typeParam.charAt(0) == Signature.C_STAR) - { - typeParam = TypeConstants.TYPE_JAVAOBJECT; - } - else - { - typeParam = typeParam.substring(1); - } - } - final String resolvedParameter = - resolveSignatureRelative( - // use the enclosing type, - // *not* the resolved type because - // we need to resolve in that context - owningType, - typeParam, eraseTypeParameters); - typeParameters.add(resolvedParameter); - } - } - - final String resolvedTypeSignature = - Signature.createTypeSignature - (resolvedType.getFullyQualifiedName(), true); - - - if (typeParameters.size() > 0 && !eraseTypeParameters) - { - StringBuffer sb = new StringBuffer(resolvedTypeSignature); - - if (sb.charAt(sb.length()-1) == ';') - { - sb = sb.delete(sb.length()-1, sb.length()); - } - - sb.append("<"); //$NON-NLS-1$ - for(String param : typeParameters) - { - //System.out.println("type param: "+resolvedType.getTypeParameter(param)); - sb.append(param); - } - - // replace the dangling ',' with the closing ">" - sb.append(">;"); //$NON-NLS-1$ - return sb.toString(); - } - - return resolvedTypeSignature; - } - - if (Signature.getTypeSignatureKind(typeSignature) == - Signature.CLASS_TYPE_SIGNATURE - || Signature.getTypeSignatureKind(typeSignature) - == Signature.TYPE_VARIABLE_SIGNATURE) - { - // if we are unable to resolve, check to see if the owning type has - // a parameter by this name - ITypeParameter typeParam = owningType.getTypeParameter(Signature.getSignatureSimpleName(typeSignature)); - - // if we have a type parameter and it hasn't been resolved to a type, - // then assume it is a method template placeholder (i.e. T in ArrayList). - // at runtime these unresolved parameter variables are effectively - // turned into Object's. For example, think List.add(E o). At runtime, - // E will behave exactly like java.lang.Object in that signature - if (typeParam.exists()) - { - return TypeConstants.TYPE_JAVAOBJECT; - } - - // TODO: is there a better way to handle a failure to resolve - // than just garbage out? - //JSFCommonPlugin.log(new Exception("Failed to resolve type: "+typeSignature), "Failed to resolve type: "+typeSignature); //$NON-NLS-1$ //$NON-NLS-2$ - } - - return typeSignature; - } - - private static IType resolveTypeRelative(final IType owningType, final String typeSignature) - { - final String fullName = getFullyQualifiedName(typeSignature); - - IType resolvedType = null; - - try - { - // TODO: this call is only supported on sourceTypes! - String[][] resolved = owningType.resolveType(fullName); - - if (resolved != null && resolved.length > 0) - { - resolvedType = owningType.getJavaProject().findType(resolved[0][0], resolved[0][1]); - } - else - { - resolvedType = resolveInParents(owningType, fullName); - } - } - catch (JavaModelException jme) - { - // do nothing; newType == null - } - - return resolvedType; - } - - /** - * @param type - * @return a type signature for a type - */ - public static String getSignature(IType type) - { - final String fullyQualifiedName = type.getFullyQualifiedName(); - return Signature.createTypeSignature(fullyQualifiedName, true); - } - - - /** - * @param owner - * @param unresolvedSignature - * @return the resolved method signature for unresolvedSignature in owner - */ - public static String resolveMethodSignature(final IType owner, - final String unresolvedSignature) - { - - final String unresolvedSignatureNormalized = - unresolvedSignature.replaceAll("/", "."); //$NON-NLS-1$ //$NON-NLS-2$ - - // get the list of parameters - final String[] parameters = - Signature.getParameterTypes(unresolvedSignatureNormalized); - - for (int i = 0; i < parameters.length; i++) - { - // try to full resolve the type - parameters[i] = resolveTypeSignature(owner, parameters[i]); - } - - // resolve return type - final String resolvedReturn = - resolveTypeSignature(owner, - Signature.getReturnType(unresolvedSignatureNormalized)); - - return Signature.createMethodSignature(parameters, resolvedReturn); - } - - /** - * @param typeSignature - * @return a fully qualified Java class name from a type signature - * i.e. Ljava.lang.String; -> java.lang.String - */ - public static String getFullyQualifiedName(final String typeSignature) - { - final String packageName = Signature.getSignatureQualifier(typeSignature); - final String typeName = Signature.getSignatureSimpleName(typeSignature); - return "".equals(packageName) ? typeName : packageName + "." + typeName; //$NON-NLS-1$//$NON-NLS-2$ - } - - private static IType resolveInParents(IType childType, String fullyQualifiedName) - throws JavaModelException - { - IType resolvedType = null; - - final TypeInfoCache typeInfoCache = TypeInfoCache.getInstance(); - IType[] superTypes = typeInfoCache.getCachedSupertypes(childType); - if (superTypes == null) { - superTypes = typeInfoCache.cacheSupertypesFor(childType); - } - - String[][] resolved; - - LOOP_UNTIL_FIRST_MATCH: - for (int i = 0; i < superTypes.length; i++) - { - final IType type = superTypes[i]; - - resolved = type.resolveType(fullyQualifiedName); - - if (resolved != null && resolved.length > 0) - { - resolvedType = childType.getJavaProject().findType(resolved[0][0], resolved[0][1]); - break LOOP_UNTIL_FIRST_MATCH; - } - } - - return resolvedType; - } - - /** - * Attempts to get a Java IType for a fully qualified signature. Note that - * generic type arguments are generally ignored by JDT when doing such - * look ups. - * - * @param javaProject the project context inside which to resolve the type - * @param fullyResolvedTypeSignature a fully resolved type signature - * @return the IType if resolved, null otherwise - */ - public static IType resolveType(final IJavaProject javaProject, final String fullyResolvedTypeSignature) - { - String fullyQualifiedName = getFullyQualifiedName(fullyResolvedTypeSignature); - fullyQualifiedName = Signature.getTypeErasure(fullyQualifiedName); - try { - return javaProject.findType(fullyQualifiedName); - } catch (JavaModelException e) { - // accessible problem - JSFCommonPlugin.log(e); - return null; - } - } - - /** - * @param type - * @param typeParamSignature -- must be a Type Variable Signature - * @param typeArguments - * @return the signature for the type argument in typeArguments that matches the - * named typeParamSignature in type. - * @throws IllegalArgumentException if typeParamSignature is not valid - * - * For example, given type for java.util.Map, typeParamSignature == "V" and - * typeArguments = {Ljava.util.String;, Lcom.test.Blah;}, the result would be - * the typeArgument that matches "V", which is "Lcom.test.Blah;} - * - * returns null if the match cannot be found. - */ - public static String matchTypeParameterToArgument(final IType type, final String typeParamSignature, final List<String> typeArguments) - { - if (Signature.getTypeSignatureKind(typeParamSignature) != Signature.TYPE_VARIABLE_SIGNATURE) - { - throw new IllegalArgumentException(); - } - - try - { - ITypeParameter[] typeParams = type.getTypeParameters(); - - for (int pos = 0; pos < typeParams.length; pos++) - { - if (typeParams[pos].getElementName().equals(Signature.getSignatureSimpleName(typeParamSignature))) - { - if (pos < typeArguments.size()) - { - // TODO: should typeArguments.size ever != typeParams.length? - return typeArguments.get(pos); - } - } - } - } - catch (JavaModelException e) - { - JSFCommonPlugin.log(e); - } - - return null; - } - - /** - * @param type - * @param fieldName - * @return true if fieldName is a member of type. Note that if type is java.lang.Enum - * then this will always return true since we cannot know what fields the instance has (it could be any enum) - */ - public static boolean isEnumMember(final IType type, final String fieldName) - { - try - { - if (type == null || !isEnumType(type)) - { - throw new IllegalArgumentException("type must be non-null and isEnum()==true"); //$NON-NLS-1$ - } - - if (fieldName == null) - { - throw new IllegalArgumentException("fieldName must be non-null"); //$NON-NLS-1$ - } - - // if type is the java.lang.Enum, always true - if (TypeConstants.TYPE_ENUM_BASE.equals(Signature.createTypeSignature(type.getFullyQualifiedName(), true))) - { - return true; - } - - final IField field = type.getField(fieldName); - - if (field.exists() && field.isEnumConstant()) - { - return true; - } - } - catch (JavaModelException jme) - { - // fall through and return false - } - - return false; - } - - /** - * @param typeSig1 the type signature of the first enum. Must be non-null, fully resolved enum type. - * @param typeSig2 the type signature of the second enum. Must be non-null, fully resolved enum type. - * - * @return true if typeSig1.compareTo(typeSig2) is a legal operation (won't throw a CCE) - */ - public static boolean isEnumsCompareCompatible(final String typeSig1, final String typeSig2) - { - if (typeSig1 == null || typeSig2 == null) - { - throw new IllegalArgumentException("args must not be null"); //$NON-NLS-1$ - } - - if (Signature.getTypeSignatureKind(typeSig1) != Signature.CLASS_TYPE_SIGNATURE - || Signature.getTypeSignatureKind(typeSig2) != Signature.CLASS_TYPE_SIGNATURE) - { - throw new IllegalArgumentException("args must be resolved class types"); //$NON-NLS-1$ - } - - // if one or the other is the raw enum type, then they *may* be comparable; we don't know - if (TypeConstants.TYPE_ENUM_BASE.equals(typeSig1) - || TypeConstants.TYPE_ENUM_BASE.equals(typeSig2)) - { - return true; - } - - // TODO: support the case of enum base type with generic type argument - - // only comparable if is the same class - return typeSig1.equals(typeSig2); - } - - /** - * @param typeSig1 the type signature of the first enum. Must be non-null, fully resolved enum type. - * @param typeSig2 the type signature of the second enum. Must be non-null, fully resolved enum type. - * @return true if instances typeSig1 and typeSig2 can never be equal due - * their being definitively different enum types - */ - public static boolean canNeverBeEqual(final String typeSig1, final String typeSig2) - { - if (typeSig1 == null || typeSig2 == null) - { - throw new IllegalArgumentException("args must not be null"); //$NON-NLS-1$ - } - - if (Signature.getTypeSignatureKind(typeSig1) != Signature.CLASS_TYPE_SIGNATURE - || Signature.getTypeSignatureKind(typeSig2) != Signature.CLASS_TYPE_SIGNATURE) - { - throw new IllegalArgumentException("args must be resolved class types"); //$NON-NLS-1$ - } - - // if either one is the base enum type, then we can't be sure - if (TypeConstants.TYPE_ENUM_BASE.equals(typeSig1) - || TypeConstants.TYPE_ENUM_BASE.equals(typeSig2)) - { - return false; - } - - // if they are definitely not the same enum types, then their values - // can never be equal - return !typeSig1.equals(typeSig2); - } - - - /** - * NOTE: we diverge from IType.isEnum() because we also return true if the base type - * is a java.lang.Enum since we consider this to be "any enumeration type" whereas JDT considers - * it merely a class since it doesn't use an "enum" keyword declaration. - * @param type - * @return true if type is an enum type or is java.lang.Enum - */ - static boolean isEnumType(IType type) - { - if (type == null) - { - return false; - } - - // check if it's the enumeration base type - if (TypeConstants.TYPE_ENUM_BASE.equals(Signature.createTypeSignature(type.getFullyQualifiedName(), true))) - { - return true; - } - - try - { - return type.isEnum(); - } - catch (JavaModelException jme) - { - // log and fallthrough to return false - JSFCommonPlugin.log(jme, "Problem resolving isEnum"); //$NON-NLS-1$ - } - - // if unresolved assume false - return false; - } - - private TypeUtil() - { - // no external instantiation - } -} |