/** Returns the type binding for a specific interface of a specific type. */ public static ITypeBinding findInterface(ITypeBinding implementingType, String qualifiedName) { if (implementingType.isInterface() && implementingType.getErasure().getQualifiedName().equals(qualifiedName)) { return implementingType; } for (ITypeBinding interfaze : getAllInterfaces(implementingType)) { if (interfaze.getErasure().getQualifiedName().equals(qualifiedName)) { return interfaze; } } return null; }
public TypeName(ITypeBinding binding, boolean varargs) { this.varargs = varargs; ITypeBinding inner = binding; if (varargs) { dimensions = 1; } else { int dims = 0; while (inner.isArray()) { inner = inner.getComponentType(); dims += 1; } dimensions = dims; } if (inner.isParameterizedType()) { inner = inner.getErasure(); } ITypeBinding parent = inner; int nesting = 0; while (parent.isNested()) { nesting++; parent = parent.getDeclaringClass(); } nestingLevel = nesting; primitive = inner.isPrimitive(); baseQualifiedName = adaptQualifiedName(inner.getQualifiedName()); baseBinaryName = inner.getBinaryName(); shortName = buildShortName(); qualifiedName = buildQualifiedName(); binaryName = buildBinaryName(); }
public URI getFullURI(ITypeBinding typeBinding) { // The URIs for primitive types are cached and indexed by their one character key // representation. // if (typeBinding.isPrimitive()) { return PRIMITIVE_URIS[typeBinding.getKey().charAt(0) - 'B']; } if (typeBinding.isClass() || typeBinding.isInterface() || typeBinding.isAnnotation() || typeBinding.isEnum()) { ITypeBinding declaringClass = typeBinding.getDeclaringClass(); if (declaringClass == null) { // This special case handling for common case of top level types that avoids creating a // builder. // String qualifiedName = typeBinding.getErasure().getQualifiedName(); URI uri = COMMON_URIS.get(qualifiedName); if (uri != null) { return uri; } uri = OBJECTS_URI.appendSegment(qualifiedName); return uri.appendFragment(uri.lastSegment()); } SegmentSequence.Builder builder = SegmentSequence.newBuilder(""); URI uri = getFullURI(declaringClass, builder); builder.append("$"); builder.append(typeBinding.getName()); return uri.appendFragment(builder.toString()); } SegmentSequence.Builder builder = SegmentSequence.newBuilder(""); URI uri = getFullURI(typeBinding, builder); return uri.appendFragment(builder.toString()); }
private static boolean typeImplementsInterfaceDirectly(ITypeBinding type, String interfaceName) { for (ITypeBinding implementedInterface : type.getInterfaces()) { if (interfaceName.equals(implementedInterface.getErasure().getQualifiedName())) { return true; } } return false; }
protected void createResourceURIForClass(ITypeBinding typeBinding, StringBuilder uriBuilder) { ITypeBinding declaringClass = typeBinding.getDeclaringClass(); if (declaringClass != null) { createResourceURIForClass(declaringClass, uriBuilder); } else { createResourceURIForClassImpl2(typeBinding.getErasure().getQualifiedName(), uriBuilder); } }
/** @since 2.4 */ protected URI getFullURI(ITypeBinding typeBinding, SegmentSequence.Builder builder) { if (typeBinding.isPrimitive()) { builder.append(PRIMITIVE_URIS[typeBinding.getKey().charAt(0) - 'B'].fragment()); return PRIMITIVES_URI; } if (typeBinding.isClass() || typeBinding.isInterface() || typeBinding.isAnnotation() || typeBinding.isEnum()) { ITypeBinding declaringClass = typeBinding.getDeclaringClass(); if (declaringClass != null) { URI uri = getFullURI(declaringClass, builder); builder.append("$"); builder.append(typeBinding.getName()); return uri; } String qualifiedName = typeBinding.getErasure().getQualifiedName(); URI uri = COMMON_URIS.get(qualifiedName); if (uri == null) { uri = OBJECTS_URI.appendSegment(qualifiedName); } builder.append(uri.lastSegment()); return uri; } if (typeBinding.isArray()) { URI uri = getFullURI(typeBinding.getComponentType(), builder); builder.append("[]"); return uri; } if (typeBinding.isTypeVariable()) { ITypeBinding declaringClass = typeBinding.getDeclaringClass(); if (declaringClass != null) { URI uri = getFullURI(declaringClass, builder); builder.append("/"); builder.append(typeBinding.getName()); return uri; } IMethodBinding declaringMethod = typeBinding.getDeclaringMethod(); URI uri = getFullURI(declaringMethod.getDeclaringClass(), builder); builder.append("."); builder.append(declaringMethod.getName()); builder.append("("); ITypeBinding[] parameterTypes = declaringMethod.getParameterTypes(); for (int i = 0; i < parameterTypes.length; i++) { if (i != 0) { builder.append(","); } getQualifiedName(parameterTypes[i], builder); } builder.append(")"); builder.append("/"); builder.append(typeBinding.getName()); return uri; } throw new IllegalStateException("Unexpected type: " + typeBinding); }
private ITypeBinding getDeclaredReturnType(IMethodBinding method, ITypeBinding receiverType) { IMethodBinding actualDeclaration = getFirstDeclaration(getObjCMethodSignature(method), receiverType); if (actualDeclaration == null) { actualDeclaration = method.getMethodDeclaration(); } ITypeBinding returnType = actualDeclaration.getReturnType(); if (returnType.isTypeVariable()) { return typeEnv.resolveIOSType("id"); } return returnType.getErasure(); }
public static String bestNameableType(ITypeBinding type) { { String result_ = fqTypeName(type); if (result_ != null) return removeTypeParam(result_); } if (type.isCapture() || type.isWildcardType() || type.isTypeVariable()) { return bestNameableType(type.getErasure()); } // Find an interface or superclass being implemented. // For anonymous class, there can only be one. BUT for // local class, things are super f-ed up... if (type.isAnonymous()) { // any interfaces? if (type.getInterfaces().length > 0) { String result = fqTypeName(type.getInterfaces()[0]); assert (result != null); return removeTypeParam(result); } else { String result = fqTypeName(type.getSuperclass()); assert (result != null); return removeTypeParam(result); } } if (type.isLocal()) { // We can only make sense of this is there is just one // superclass+inferface. if (type.getInterfaces().length == 0) { // EASY! String result = fqTypeName(type.getSuperclass()); assert (result != null); return removeTypeParam(result); } else { // Well, maybe superclass is object? if (type.getSuperclass().getQualifiedName().equals(Object.class.getName())) { String result = fqTypeName(type.getInterfaces()[0]); assert (result != null); return removeTypeParam(result); } else { // Otherwise, return the superclass, I guess, but print a warning: String result = fqTypeName(type.getSuperclass()); assert (result != null); System.err.println("Local class has multiple supertypes..." + type.getBinaryName()); return removeTypeParam(result); } } } return Utilities.impossible(); }
/** @since 2.4 */ protected SegmentSequence.Builder getQualifiedName( ITypeBinding binding, SegmentSequence.Builder builder) { if (binding.isParameterizedType()) { getQualifiedName(binding.getErasure(), builder); } else if (binding.isArray()) { getQualifiedName(binding.getComponentType(), builder).append("[]"); } else if (binding.isTopLevel() || binding.isTypeVariable() || binding.isPrimitive()) { builder.append(binding.getQualifiedName()); } else { getQualifiedName(binding.getDeclaringClass(), builder).append('$').append(binding.getName()); } return builder; }
/** @since 2.4 */ public StringBuilder getQualifiedName(ITypeBinding binding, StringBuilder stringBuilder) { if (binding.isParameterizedType()) { getQualifiedName(binding.getErasure(), stringBuilder); } else if (binding.isArray()) { getQualifiedName(binding.getComponentType(), stringBuilder).append("[]"); } else if (binding.isTopLevel() || binding.isTypeVariable() || binding.isPrimitive()) { stringBuilder.append(binding.getQualifiedName()); } else { getQualifiedName(binding.getDeclaringClass(), stringBuilder) .append('$') .append(binding.getName()); } return stringBuilder; }
public static boolean typeIsAssignableFrom(ITypeBinding typeBinding, Class<?> specifiedClass) { String className = specifiedClass.getCanonicalName(); while (typeBinding != null) { if (className.equals(typeBinding.getErasure().getQualifiedName())) { return true; } if (typeImplementsInterfaceDirectly(typeBinding, className)) { return true; } typeBinding = typeBinding.getSuperclass(); } return false; }
public String getQualifiedName(ITypeBinding binding) { if (binding.isParameterizedType()) { return getQualifiedName(binding.getErasure()); } if (binding.isArray()) { return getQualifiedName(binding.getComponentType(), new StringBuilder()) .append("[]") .toString(); } if (binding.isTopLevel() || binding.isTypeVariable() || binding.isPrimitive()) return binding.getQualifiedName(); return getQualifiedName(binding.getDeclaringClass(), new StringBuilder()) .append('$') .append(binding.getName()) .toString(); }
@Override public void endVisit(CastExpression node) { ITypeBinding type = node.getType().getTypeBinding(); Expression expr = node.getExpression(); ITypeBinding exprType = expr.getTypeBinding(); // TODO(kirbs): Implement correct conversion of Java 8 intersection types to Objective-C. if (node.getType().isIntersectionType() && !Options.isJava8Translator()) { // Technically we can't currently get here, but as we add support and change flags in the // future this should alert us to implement intersection types. assert false : "not implemented yet"; } if (BindingUtil.isFloatingPoint(exprType)) { assert type.isPrimitive(); // Java wouldn't allow a cast from primitive to non-primitive. switch (type.getBinaryName().charAt(0)) { case 'J': node.replaceWith(rewriteFloatToIntegralCast(type, expr, "JreFpToLong", type)); return; case 'C': node.replaceWith(rewriteFloatToIntegralCast(type, expr, "JreFpToChar", type)); return; case 'B': case 'S': case 'I': node.replaceWith( rewriteFloatToIntegralCast(type, expr, "JreFpToInt", typeEnv.resolveJavaType("int"))); return; } // else fall-through. } // Lean on Java's type-checking. if (!type.isPrimitive() && exprType.isAssignmentCompatible(type.getErasure())) { node.replaceWith(TreeUtil.remove(expr)); return; } FunctionInvocation castCheck = createCastCheck(type, expr); if (castCheck != null) { node.setExpression(castCheck); } }
/** * Get a method's signature for dead code elimination purposes. * * <p>Since DeadCodeEliminator runs before InnerClassExtractor, inner class constructors do not * yet have the parameter for capturing outer class, and therefore we need this special case. */ public static String getProGuardSignature(IMethodBinding binding) { StringBuilder sb = new StringBuilder("("); // If the method is an inner class constructor, prepend the outer class type. if (binding.isConstructor()) { ITypeBinding declClass = binding.getDeclaringClass(); ITypeBinding outerClass = declClass.getDeclaringClass(); if (outerClass != null && !declClass.isInterface() && !declClass.isAnnotation() && !Modifier.isStatic(declClass.getModifiers())) { appendParameterSignature(outerClass.getErasure(), sb); } } appendParametersSignature(binding, sb); sb.append(')'); appendReturnTypeSignature(binding, sb); return sb.toString(); }
protected Import getReference(ITypeBinding binding) { if (!binding.isTypeVariable() && !binding.isPrimitive() && !binding.isAnnotation() // Don't import IOS types, other than the IOS array types, // since they have header files. && (binding instanceof IOSArrayTypeBinding || !(binding instanceof IOSTypeBinding))) { binding = Types.mapType(binding); String typeName = NameTable.getFullName(binding); boolean isInterface = binding.isInterface(); while (!binding.isTopLevel()) { binding = binding.getDeclaringClass(); } return getReference(typeName, binding.getErasure().getQualifiedName(), isInterface); } else if (binding.isTypeVariable()) { ITypeBinding[] typeBounds = binding.getTypeBounds(); if (typeBounds.length > 0 && !Types.isJavaObjectType(typeBounds[0])) { return getReference(typeBounds[0]); } } return NULL_IMPORT; }
private FunctionInvocation createCastCheck(ITypeBinding type, Expression expr) { type = type.getErasure(); ITypeBinding idType = typeEnv.resolveIOSType("id"); FunctionInvocation invocation = null; if ((type.isInterface() && !type.isAnnotation()) || (type.isArray() && !type.getComponentType().isPrimitive())) { FunctionBinding binding = new FunctionBinding("cast_check", idType, null); binding.addParameters(idType, typeEnv.getIOSClass()); invocation = new FunctionInvocation(binding, idType); invocation.getArguments().add(TreeUtil.remove(expr)); invocation.getArguments().add(new TypeLiteral(type, typeEnv)); } else if (type.isClass() || type.isArray() || type.isAnnotation() || type.isEnum()) { FunctionBinding binding = new FunctionBinding("cast_chk", idType, null); binding.addParameters(idType, idType); invocation = new FunctionInvocation(binding, idType); invocation.getArguments().add(TreeUtil.remove(expr)); IOSMethodBinding classBinding = IOSMethodBinding.newMethod("class", Modifier.STATIC, idType, type); MethodInvocation classInvocation = new MethodInvocation(classBinding, new SimpleName(type)); invocation.getArguments().add(classInvocation); } return invocation; }
/** * Create an instance based on a JDT type. * * <p>The location, context and warnings parameters are used for raising warnings when the type * bindings cannot be resolved. */ public TypeName( Type t, boolean varargs, String location, String context, Set<DocumentationWarning> warnings) { this.varargs = varargs; // Try to resolve the binding. ITypeBinding binding = t.resolveBinding(); // If binding was resolved, then use it to extract the names. if (binding != null) { ITypeBinding inner = binding; if (varargs) { dimensions = 1; } else { int dims = 0; while (inner.isArray()) { inner = inner.getComponentType(); dims += 1; } dimensions = dims; } if (inner.isParameterizedType()) { inner = inner.getErasure(); } ITypeBinding parent = inner; int nesting = 0; while (parent.isNested()) { nesting++; parent = parent.getDeclaringClass(); } nestingLevel = nesting; primitive = inner.isPrimitive(); baseQualifiedName = adaptQualifiedName(inner.getQualifiedName()); baseBinaryName = inner.getBinaryName(); } // If the binding was not resolved, then use the type name anyway. // This may not be accurate, but is better than nothing. // Also raise a warning in this case. else { String rawName = t.toString(); int idx = rawName.indexOf("["); if (idx >= 0) { baseQualifiedName = rawName.substring(0, idx); String dimPart = rawName.substring(idx); dimensions = dimPart.length() / 2; } else { baseQualifiedName = rawName; dimensions = 0; } nestingLevel = 0; baseBinaryName = baseQualifiedName; primitive = t.isPrimitiveType(); DocumentationWarning dw = new DocumentationWarning( WarningType.UnresolvedBinding, location, "Cannot resolve binding for " + context + " type: '" + baseQualifiedName + "'."); warnings.add(dw); } shortName = buildShortName(); qualifiedName = buildQualifiedName(); binaryName = buildBinaryName(); }
private static void appendParametersSignature(IMethodBinding binding, StringBuilder sb) { for (ITypeBinding parameter : binding.getParameterTypes()) { appendParameterSignature(parameter.getErasure(), sb); } }