Example usage for org.eclipse.jdt.internal.compiler.lookup TypeBinding dimensions

List of usage examples for org.eclipse.jdt.internal.compiler.lookup TypeBinding dimensions

Introduction

In this page you can find the example usage for org.eclipse.jdt.internal.compiler.lookup TypeBinding dimensions.

Prototype

public int dimensions() 

Source Link

Usage

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator.java

License:Open Source License

/**
  * This method may wrap a type as an explicitly anchored role type if appropriate.
  *//from   ww w.  j a  va 2 s  .  c  o m
  * If wrapping is not applicable, return the typeToWrap unmodified.
  *
  * @param scope (NON-NULL) defines the scope determining tthis if applicable.
  * @param anchorExpr (NON-NULL)
  * @param typeToWrap
  * @param typedNode position for error reporting (NON-NULL if problemReporter != null)
  * @return RoleTypeBinding or ArrayBinding or TypeBinding(original) or null
  */
public static TypeBinding maybeWrapQualifiedRoleType(final Scope scope, final Expression anchorExpr,
        TypeBinding typeToWrap, final ASTNode typedNode) {
    /* invocations:
     * QualifiedAllocationExpression.resolveType()   rec.new R()      R
     * FieldReference.resolveType()               rec.r         type(r)
     * maybeWrapQualifiedRoleType(MessageSend,BlockScope)
     *      for MessageSend.resolveType()             rec.m()       returnType(m)
     */

    if (typeToWrap == null)
        return null;

    if (TSuperHelper.isMarkerInterface(typeToWrap))
        return typeToWrap;

    TypeBinding originalType = typeToWrap;

    // consider arrays:
    int dimensions = typeToWrap.dimensions();
    typeToWrap = typeToWrap.leafComponentType();

    // easy problems first:
    if (!(typeToWrap instanceof ReferenceBinding) || typeToWrap.isEnum())
        return originalType;
    ReferenceBinding refBinding = (ReferenceBinding) typeToWrap;

    if (scope instanceof BlockScope && avoidWrapRoleType((BlockScope) scope, anchorExpr))
        return originalType;

    if (refBinding instanceof CaptureBinding)
        return ((CaptureBinding) refBinding).maybeWrapQualifiedRoleType(scope, anchorExpr, typedNode,
                originalType);

    TypeBinding wrappedRoleType = internalWrapQualifiedRoleType(scope, anchorExpr, originalType, typedNode,
            refBinding, dimensions);
    return wrappedRoleType.maybeWrapRoleType(typedNode, new TypeArgumentUpdater() {
        public TypeBinding updateArg(ReferenceBinding arg) {
            if (arg instanceof WildcardBinding)
                return ((WildcardBinding) arg).maybeWrapQualifiedRoleType(scope, anchorExpr, typedNode);
            return arg;
        }
    });
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator.java

License:Open Source License

/**
 * Version to use by MessageSend.//from w w w. jav a  2  s .c om
 * May specialize role type to revert signature weakening.
 *
 * @param send retrieve all relevant information from this message send.
 * @param scope
 * @return wrapped type or original or null
 */
public static TypeBinding maybeWrapQualifiedRoleType(MessageSend send, BlockScope scope) {
    Expression receiver = send.receiver;

    TypeBinding returnType = send.binding.returnType;

    if (returnType == null || !(returnType.leafComponentType() instanceof ReferenceBinding)
            || returnType.leafComponentType().isEnum())
        return returnType;

    int dimensions = returnType.dimensions();
    ReferenceBinding refReturn = (ReferenceBinding) returnType.leafComponentType();

    // don't try externalized non-public role if compatibility can be established with plain types:
    if (send.expectedType != null && !(send.expectedType instanceof DependentTypeBinding))
        if (refReturn.isRole() && !refReturn.isPublic() && returnType.isCompatibleWith(send.expectedType))
            return returnType;

    boolean isCalloutGet = CharOperation.prefixEquals(IOTConstants.OT_GETFIELD, send.selector);
    //        // FIXME(SH): test with field of role type
    {
        AbstractMethodDeclaration referenceMethod = scope.methodScope().referenceMethod();
        if (referenceMethod != null)
            isCalloutGet &= (referenceMethod.isMappingWrapper.callout());
    }
    if (!isCalloutGet) {
        if (refReturn instanceof WeakenedTypeBinding) {
            WeakenedTypeBinding weakenedReturn = (WeakenedTypeBinding) refReturn;
            if (dimensions > 0)
                throw new InternalCompilerError("array not yet supported in this position"); //$NON-NLS-1$
            ReferenceBinding strongType = weakenedReturn.getStrongType();
            if (TypeBinding.notEquals(strongType.getRealType(), weakenedReturn.weakenedType)) {
                if (send.expectedType == null
                        || !weakenedReturn.weakenedType.isCompatibleWith(send.expectedType))
                    send.valueCast = strongType;
            }
            TypeBinding instantiated = maybeWrapQualifiedRoleType(scope, send.receiver, strongType, send);
            return instantiated;
        }
        if (refReturn instanceof RoleTypeBinding) {
            RoleTypeBinding roleReturn = (RoleTypeBinding) refReturn;
            if (roleReturn._argumentPosition > -1
                    && send.binding.original() == roleReturn._declaringMethod.getMethod()) {
                ReferenceBinding roleEnclosing = roleReturn.enclosingType();

                // anchored to argument, instantiate directly:
                Expression anchorExpr = send.arguments[roleReturn._argumentPosition];
                TypeBinding anchorType = anchorExpr.resolvedType;

                ITeamAnchor anchor = null;
                if (anchorType.isRole()
                        && ((ReferenceBinding) anchorType).isCompatibleViaLowering(roleEnclosing)) {
                    // see 1.1.31-otjld-stacked-teams-1 f.
                    if (anchorExpr.isThis())
                        anchor = ((ReferenceBinding) anchorType).getField(IOTConstants._OT_BASE, true);
                    else
                        return returnType; // cannot improve, error will be reported upstream                   
                } else {
                    if (anchorType.isRole())
                        anchorType = ((ReferenceBinding) anchorType).getRealClass(); // ignore role-ness of team anchor
                    if (!anchorType.isCompatibleWith(roleEnclosing))
                        return returnType; // cannot improve, anchor doesn't match expected team.
                    anchor = (ITeamAnchor) ((NameReference) anchorExpr).binding;
                }
                return anchor.getRoleTypeBinding(roleReturn, returnType.dimensions());
            }

            // retrieve existing information:
            ITeamAnchor anchor = roleReturn._teamAnchor;
            ReferenceBinding receiverType = (ReferenceBinding) send.actualReceiverType;
            if (anchor instanceof TThisBinding // not yet instantiated
                    && (receiverType.isTeam() || receiverType.isRole())) {
                roleReturn = (RoleTypeBinding) TeamModel.strengthenRoleType(receiverType, roleReturn);
                if (dimensions > 0)
                    returnType = roleReturn.getArrayType(dimensions);
                else
                    returnType = roleReturn;
            }
            if (avoidWrapRoleType(scope, receiver))
                // don't use synthetic _OT$role as additional anchor
                return returnType;
        }
    } else {
        if (send.arguments != null && send.arguments.length > 0) { // no arguments if accessed field is static
                                                                   // for wrapping types of a field access method, fake a _OT$base receiver
                                                                   // (although method is actually static)
                                                                   // see also comment in FieldAccessSpec.createMethod().
            receiver = new SingleNameReference(IOTConstants._OT_BASE, 0);
            receiver.resolve(scope);
        }
    }
    return maybeWrapQualifiedRoleType(scope, receiver, returnType, send);
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator.java

License:Open Source License

public static TypeBinding maybeWrapUnqualifiedRoleType(final Scope scope, final ReferenceBinding site,
        TypeBinding typeToWrap, final ASTNode typedNode, ProblemReporter problemReporter) {
    assert (!(site == null));
    if (typeToWrap == null)
        return null;
    if (!typeToWrap.isValidBinding())
        return typeToWrap; // don't tamper with already broken type

    if (TSuperHelper.isMarkerInterface(typeToWrap))
        return typeToWrap;

    final TypeBinding originalType = typeToWrap;

    // consider arrays:
    int dimensions = typeToWrap.dimensions();
    typeToWrap = typeToWrap.leafComponentType();

    // consider parameterized:
    TypeBinding[] arguments = null;//www  . j  a v  a 2s .  c o  m
    if (typeToWrap.isParameterizedType())
        arguments = ((ParameterizedTypeBinding) typeToWrap).arguments;

    // easy problems first:
    if (!(typeToWrap instanceof ReferenceBinding) || typeToWrap.isEnum())
        return originalType;

    if (typeToWrap instanceof UnresolvedReferenceBinding) {
        // defer wrapping until resolve():
        final UnresolvedReferenceBinding rawUnresolved = (UnresolvedReferenceBinding) typeToWrap;
        final ProblemReporter originalReporter = problemReporter;
        return new UnresolvedReferenceBinding(rawUnresolved.compoundName, rawUnresolved.getPackage()) {
            @Override
            public ReferenceBinding resolve(LookupEnvironment environment, boolean convertGenericToRawType) {
                ReferenceBinding type = rawUnresolved.resolve(environment, convertGenericToRawType);
                return (ReferenceBinding) maybeWrapUnqualifiedRoleType(scope, site, type, typedNode,
                        originalReporter);
            }

            @Override
            public boolean hasTypeAnnotations() {
                return rawUnresolved.hasTypeAnnotations();
            }

            @Override
            public boolean hasNullTypeAnnotations() {
                return rawUnresolved.hasNullTypeAnnotations();
            }

            @Override
            public AnnotationBinding[] getAnnotations() {
                return rawUnresolved.getAnnotations();
            }

            {
                this.tagBits = rawUnresolved.tagBits;
            }
        };
    }
    if (typeToWrap instanceof IntersectionTypeBinding18) { // FIXME (recurse?)
        return originalType;
    }
    ReferenceBinding refBinding = (ReferenceBinding) typeToWrap;
    if (!refBinding.isDirectRole()) {
        final ProblemReporter reporter = problemReporter;
        return originalType.maybeWrapRoleType(typedNode, new TypeArgumentUpdater() {
            public TypeBinding updateArg(ReferenceBinding arg) {
                return maybeWrapUnqualifiedRoleType(scope, site, arg, typedNode, reporter);
            }
        });
    }

    // already wrapped:
    if (typeToWrap instanceof RoleTypeBinding) {
        RoleTypeBinding roleType = (RoleTypeBinding) typeToWrap;
        if (!(roleType._teamAnchor instanceof TThisBinding)) {
            return originalType; // cannot improve
        } else {
            // do handle tthis RoleTypeBindings, too, because we might need to
            // set a new anchor
            // (but don't report errors, if this type is already acceptable).
            if (TeamModel.findEnclosingTeamContainingRole(site, roleType) != null)
                problemReporter = null;
        }
    }

    VariableBinding variableBinding = null;
    ReferenceBinding teamBinding = TeamModel.findEnclosingTeamContainingRole(site, refBinding);
    if (teamBinding != null)
        variableBinding = TThisBinding.getTThisForRole(refBinding, teamBinding);
    if (variableBinding == null)
        variableBinding = cannotWrapType(refBinding, problemReporter, typedNode);

    // handle problems (reported ones and yet unreported ones):
    assert (variableBinding != null);
    if (variableBinding == RoleTypeBinding.NoAnchor) {
        return originalType;
    } else if (!variableBinding.isFinal()) {
        if (problemReporter != null)
            problemReporter.anchorPathNotFinal(null, variableBinding, refBinding.sourceName()); // TODO
        return null;
    } else if (!(variableBinding instanceof TThisBinding) && !refBinding.isPublic()) {
        if (problemReporter != null)
            problemReporter.externalizingNonPublicRole(typedNode, refBinding);
        return null;
    }

    // delegate to the principal function:
    return getAnchoredType(scope, typedNode, variableBinding, refBinding, arguments, dimensions);
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator.java

License:Open Source License

private static TypeBinding maybeWrapSignatureType(TypeBinding type, MethodScope scope, ASTNode typedNode,
        ITeamAnchor defaultAnchor) {//from w w w . j a va 2s. c o m
    if (defaultAnchor != null && !type.leafComponentType().isBaseType()
            && defaultAnchor.isTeamContainingRole((ReferenceBinding) type.leafComponentType())) {
        return defaultAnchor.getDependentTypeBinding((ReferenceBinding) type.leafComponentType(), 0, // typeParamPosition 
                Binding.NO_PARAMETERS, type.dimensions());
    } else {
        return maybeWrapUnqualifiedRoleType(type, scope, typedNode);
    }
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator.java

License:Open Source License

/**
  * Given a raw role type and an anchor path create the corresponding RoleTypeBinding.
  * PRE: the type is not anchored to a parameter.
  *//from   w ww  .ja va 2  s  . co m
 * @param typeToWrap  wrap this role type
 * @param anchorName  a char[] encoded anchor path ('.' separated, inner classes '$' separated).
 * @param site        look here for first field as anchor
 * @param environment used for lookup of a static prefix (types), if given.
 */
public static TypeBinding wrapTypeWithAnchorFromName(TypeBinding typeToWrap, char[] anchorName,
        ReferenceBinding site, LookupEnvironment environment) {
    ReferenceBinding leafType = (ReferenceBinding) typeToWrap.leafComponentType();
    if (leafType.isRawType())
        leafType = ((ParameterizedTypeBinding) leafType).genericType();
    if (!DependentTypeBinding.mayTakeValueParam(leafType)) {
        assert false : "this method should only be called for types requiring an anchor"; //$NON-NLS-1$
        return typeToWrap; // TODO (SH): check why we came here in the first place!!
    }
    // FIXME (SH): also check roles from an unrelated team
    //             (= is the role compatible to the anchor?)

    char[][] tokens = CharOperation.splitOn('.', anchorName);
    char[][] prefixTokens = tokens;
    TypeBinding typePrefix = null;
    while (prefixTokens.length > 0) {
        typePrefix = environment.askForType(prefixTokens);
        if (typePrefix != null)
            break;
        prefixTokens = CharOperation.subarray(prefixTokens, 0, prefixTokens.length - 1);
    }
    ReferenceBinding currentType = site;
    int idx = 0;
    if (typePrefix != null) {
        idx = prefixTokens.length;
        currentType = (ReferenceBinding) typePrefix;
    }
    ITeamAnchor currentVar = TypeAnalyzer.findField(currentType, tokens[idx++], /*don't check static*/false,
            /*outer*/true);
    for (int i = idx; i < tokens.length; i++) {
        if (currentVar == null) {
            environment.problemReporter
                    .abortDueToInternalError("Type anchor in class file " + new String(site.readableName()) //$NON-NLS-1$
                            + " unresolvable path component: " + new String(tokens[i - 1])); //$NON-NLS-1$
            return null;
        }
        ITeamAnchor next = currentVar.getFieldOfType(tokens[i], /*don't check static*/false, /*outer*/true);
        currentVar = next.setPathPrefix(currentVar);
    }
    if (!currentVar.isTeam()) {
        environment.problemReporter.abortDueToInternalError("Type anchor in class file " //$NON-NLS-1$
                + new String(site.readableName()) + " does not resolve to a team: " + new String(anchorName)); //$NON-NLS-1$
        return null;
    }
    TypeBinding[] typeArguments = typeToWrap.isParameterizedType()
            ? ((ParameterizedTypeBinding) typeToWrap).arguments
            : null;
    return currentVar.getDependentTypeBinding(leafType, -1/*no argpos*/, typeArguments,
            typeToWrap.dimensions());
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator.java

License:Open Source License

/** 
 * Decompose a given type into atomic types (taking into account arrays and type arguments)
 * perform a given type substitution for each atomic type and 
 * re-assemble to a type of the same shape as the given type. 
 * @param original      the given type to be substituted
 * @param environment   for creation of parameterized types and array types
 * @param substitution  what to perform on each atomic dependent type
 * @return either null (after an error should have been reported) or the original type or a legal substitution
 *///from  w  w  w  .j a  va  2 s.com
public static TypeBinding deepSubstitute(TypeBinding original, LookupEnvironment environment,
        IDependentTypeSubstitution substitution) {
    TypeBinding type = original;
    int dimensions = type.dimensions();
    type = type.leafComponentType();

    TypeBinding[] typeArguments = null;
    boolean hasInstantiated = false;
    if (type.isParameterizedType()) {
        ParameterizedTypeBinding ptb = (ParameterizedTypeBinding) type;
        if (ptb.arguments != null) {
            typeArguments = new TypeBinding[ptb.arguments.length];
            for (int j = 0; j < ptb.arguments.length; j++) {
                TypeBinding givenTypeArgument = ptb.arguments[j];
                typeArguments[j] = deepSubstitute(givenTypeArgument, environment, substitution);
                if (typeArguments[j] == null)
                    typeArguments[j] = givenTypeArgument;
                else if (typeArguments[j] != givenTypeArgument) //$IDENTITY-COMPARISON$
                    hasInstantiated = true;
            }
            if (hasInstantiated)
                type = ptb.genericType();
            else
                typeArguments = null;
        }
    }

    if (type instanceof DependentTypeBinding) {
        TypeBinding substituted = substitution.substitute((DependentTypeBinding) type, typeArguments,
                dimensions);
        if (substituted != type) // includes substituted == null //$IDENTITY-COMPARISON$
            return substituted;
    }
    if (hasInstantiated) {
        TypeBinding parameterized = environment.createParameterizedType((ReferenceBinding) type, typeArguments,
                original.enclosingType());
        if (dimensions == 0)
            return parameterized;
        return environment.createArrayType(parameterized, dimensions);
    }
    return original;
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.TypeAnalyzer.java

License:Open Source License

/**
 * Answer, whether two type are the same, when regarding a class and an
 * interface part of a role as identical.
 *//*from w  ww  .j av a  2 s.c  o m*/
public static boolean isSameType(ReferenceBinding site, TypeBinding t1, TypeBinding t2) {
    if (TypeBinding.equalsEquals(t1, t2))
        return true;
    if (t1 == null || t2 == null)
        return false;
    if (t1.isArrayType()) {
        if (!t2.isArrayType() || (t1.dimensions() != t2.dimensions()))
            return false;
        t1 = t1.leafComponentType();
        t2 = t2.leafComponentType();
    } else if (t2.isArrayType()) {
        return false;
    }

    if (t1.isBaseType())
        return TypeBinding.equalsEquals(t1, t2);
    if (t2.isBaseType())
        return false;
    ReferenceBinding r1 = (ReferenceBinding) t1;
    ReferenceBinding r2 = (ReferenceBinding) t2;
    if (r1.isDirectRole() && r2.isDirectRole()) {
        r2 = (ReferenceBinding) TeamModel.strengthenRoleType(site, r2);
        return TypeBinding.equalsEquals(r1.roleModel.getInterfacePartBinding(),
                r2.roleModel.getInterfacePartBinding());
    }
    return false;
}

From source file:org.eclipse.recommenders.utils.rcp.CompilerBindings.java

License:Open Source License

/**
 * TODO nested anonymous types are not resolved correctly. JDT uses line numbers for inner types instead of $1,..,$n
 */// w  ww. j  a  va  2s.  co  m
public static Optional<ITypeName> toTypeName(@Nullable TypeBinding binding) {
    // XXX generics fail
    if (binding == null) {
        return absent();
    }
    //
    final boolean boundParameterizedType = binding.isBoundParameterizedType();
    final boolean parameterizedType = binding.isParameterizedType();

    // if (binding.isBoundParameterizedType()) {
    // return null;
    // }

    if (binding.isArrayType()) {
        final int dimensions = binding.dimensions();
        final TypeBinding leafComponentType = binding.leafComponentType();
        final String arrayDimensions = StringUtils.repeat("[", dimensions);
        final Optional<ITypeName> typeName = toTypeName(leafComponentType);
        if (!typeName.isPresent()) {
            return absent();
        }
        final ITypeName res = VmTypeName.get(arrayDimensions + typeName.get().getIdentifier());
        return fromNullable(res);
    }
    // TODO: handling of generics is bogus!
    if (binding instanceof TypeVariableBinding) {
        final TypeVariableBinding generic = (TypeVariableBinding) binding;
        if (generic.declaringElement instanceof TypeBinding) {
            // XXX: for this?
            binding = (TypeBinding) generic.declaringElement;
        } else if (generic.superclass != null) {
            // example Tuple<T1 extends List, T2 extends Number) --> for
            // generic.superclass (T2)=Number
            // we replace the generic by its superclass
            binding = generic.superclass;
        }
    }

    String signature = String.valueOf(binding.genericTypeSignature());
    // if (binding instanceof BinaryTypeBinding) {
    // signature = StringUtils.substringBeforeLast(signature, ";");
    // }

    if (signature.length() == 1) {
        // no handling needed. primitives always look the same.
    } else if (signature.endsWith(";")) {
        signature = StringUtils.substringBeforeLast(signature, ";");
    } else {
        signature = "L" + SignatureUtil.stripSignatureToFQN(signature);
    }
    final ITypeName res = VmTypeName.get(signature);
    return fromNullable(res);
}

From source file:spoon.support.compiler.jdt.ReferenceBuilder.java

License:Open Source License

/**
 * @param resolveGeneric if true then it never returns CtTypeParameterReference, but it's superClass instead
 *///from  www. j  a v  a 2 s  .c  o  m
<T> CtTypeReference<T> getTypeReference(TypeBinding binding, boolean resolveGeneric) {
    if (binding == null) {
        return null;
    }

    CtTypeReference<?> ref;

    if (binding instanceof RawTypeBinding) {
        ref = getTypeReference(((ParameterizedTypeBinding) binding).genericType());
    } else if (binding instanceof ParameterizedTypeBinding) {
        if (binding.actualType() != null && binding.actualType() instanceof LocalTypeBinding) {
            // When we define a nested class in a method and when the enclosing class of this method
            // is a parameterized type binding, JDT give a ParameterizedTypeBinding for the nested class
            // and hide the real class in actualType().
            ref = getTypeReference(binding.actualType());
        } else {
            ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
            this.exploringParameterizedBindings.put(binding, ref);
            if (binding.isAnonymousType()) {
                ref.setSimpleName("");
            } else {
                ref.setSimpleName(String.valueOf(binding.sourceName()));
                if (binding.enclosingType() != null) {
                    ref.setDeclaringType(getTypeReference(binding.enclosingType()));
                } else {
                    ref.setPackage(getPackageReference(binding.getPackage()));
                }
            }
        }
        if (binding.actualType() instanceof MissingTypeBinding) {
            ref = getTypeReference(binding.actualType());
        }

        if (((ParameterizedTypeBinding) binding).arguments != null) {
            for (TypeBinding b : ((ParameterizedTypeBinding) binding).arguments) {
                if (bindingCache.containsKey(b)) {
                    ref.addActualTypeArgument(getCtCircularTypeReference(b));
                } else {
                    if (!this.exploringParameterizedBindings.containsKey(b)) {
                        this.exploringParameterizedBindings.put(b, null);
                        CtTypeReference typeRefB = getTypeReference(b);
                        this.exploringParameterizedBindings.put(b, typeRefB);
                        ref.addActualTypeArgument(typeRefB);
                    } else {
                        CtTypeReference typeRefB = this.exploringParameterizedBindings.get(b);
                        if (typeRefB != null) {
                            ref.addActualTypeArgument(typeRefB.clone());
                        }
                    }
                }
            }
        }
    } else if (binding instanceof MissingTypeBinding) {
        ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
        ref.setSimpleName(new String(binding.sourceName()));
        ref.setPackage(getPackageReference(binding.getPackage()));
        if (!this.jdtTreeBuilder.getContextBuilder().ignoreComputeImports) {
            final CtReference declaring = this.getDeclaringReferenceFromImports(binding.sourceName());
            if (declaring instanceof CtPackageReference) {
                ref.setPackage((CtPackageReference) declaring);
            } else if (declaring instanceof CtTypeReference) {
                ref.setDeclaringType((CtTypeReference) declaring);
            }
        }
    } else if (binding instanceof BinaryTypeBinding) {
        ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
        if (binding.enclosingType() != null) {
            ref.setDeclaringType(getTypeReference(binding.enclosingType()));
        } else {
            ref.setPackage(getPackageReference(binding.getPackage()));
        }
        ref.setSimpleName(new String(binding.sourceName()));
    } else if (binding instanceof TypeVariableBinding) {
        boolean oldBounds = bounds;

        if (binding instanceof CaptureBinding) {
            ref = this.jdtTreeBuilder.getFactory().Core().createWildcardReference();
            bounds = true;
        } else {
            TypeVariableBinding typeParamBinding = (TypeVariableBinding) binding;
            if (resolveGeneric) {
                //it is called e.g. by ExecutableReference, which must not use CtParameterTypeReference
                //but it needs it's bounding type instead
                ReferenceBinding superClass = typeParamBinding.superclass;
                ReferenceBinding[] superInterfaces = typeParamBinding.superInterfaces();

                CtTypeReference refSuperClass = null;

                // if the type parameter has a super class other than java.lang.Object, we get it
                // superClass.superclass() is null if it's java.lang.Object
                if (superClass != null && !(superClass.superclass() == null)) {

                    // this case could happen with Enum<E extends Enum<E>> for example:
                    // in that case we only want to have E -> Enum -> E
                    // to conserve the same behavior as JavaReflectionTreeBuilder
                    if (!(superClass instanceof ParameterizedTypeBinding)
                            || !this.exploringParameterizedBindings.containsKey(superClass)) {
                        refSuperClass = this.getTypeReference(superClass, resolveGeneric);
                    }

                    // if the type parameter has a super interface, then we'll get it too, as a superclass
                    // type parameter can only extends an interface or a class, so we don't make the distinction
                    // in Spoon. Moreover we can only have one extends in a type parameter.
                } else if (superInterfaces != null && superInterfaces.length == 1) {
                    refSuperClass = this.getTypeReference(superInterfaces[0], resolveGeneric);
                }
                if (refSuperClass == null) {
                    refSuperClass = this.jdtTreeBuilder.getFactory().Type().getDefaultBoundingType();
                }
                ref = refSuperClass.clone();
            } else {
                ref = this.jdtTreeBuilder.getFactory().Core().createTypeParameterReference();
                ref.setSimpleName(new String(binding.sourceName()));
            }
        }
        TypeVariableBinding b = (TypeVariableBinding) binding;
        if (bounds) {
            if (b instanceof CaptureBinding && ((CaptureBinding) b).wildcard != null) {
                bounds = oldBounds;
                return getTypeReference(((CaptureBinding) b).wildcard, resolveGeneric);
            } else if (b.superclass != null && b.firstBound == b.superclass) {
                bounds = false;
                bindingCache.put(binding, ref);
                if (ref instanceof CtWildcardReference) {
                    ((CtWildcardReference) ref).setBoundingType(getTypeReference(b.superclass, resolveGeneric));
                }
                bounds = oldBounds;
            }
        }
        if (bounds && b.superInterfaces != null && b.superInterfaces != Binding.NO_SUPERINTERFACES) {
            bindingCache.put(binding, ref);
            List<CtTypeReference<?>> bounds = new ArrayList<>();
            CtTypeParameterReference typeParameterReference = (CtTypeParameterReference) ref;
            if (!(typeParameterReference.isDefaultBoundingType())) { // if it's object we can ignore it
                bounds.add(typeParameterReference.getBoundingType());
            }
            for (ReferenceBinding superInterface : b.superInterfaces) {
                bounds.add(getTypeReference(superInterface, resolveGeneric));
            }
            if (ref instanceof CtWildcardReference) {
                ((CtWildcardReference) ref).setBoundingType(this.jdtTreeBuilder.getFactory().Type()
                        .createIntersectionTypeReferenceWithBounds(bounds));
            }
        }
        if (binding instanceof CaptureBinding) {
            bounds = false;
        }
    } else if (binding instanceof BaseTypeBinding) {
        String name = new String(binding.sourceName());
        //always create new TypeReference, because clonning from a cache clones invalid SourcePosition
        ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
        ref.setSimpleName(name);
    } else if (binding instanceof WildcardBinding) {
        WildcardBinding wildcardBinding = (WildcardBinding) binding;
        CtWildcardReference wref = this.jdtTreeBuilder.getFactory().Core().createWildcardReference();
        ref = wref;

        if (wildcardBinding.boundKind == Wildcard.SUPER) {
            wref.setUpper(false);
        }

        if (wildcardBinding.bound != null) {
            if (bindingCache.containsKey(wildcardBinding.bound)) {
                wref.setBoundingType(getCtCircularTypeReference(wildcardBinding.bound));
            } else {
                wref.setBoundingType(getTypeReference(((WildcardBinding) binding).bound));
            }
        }
    } else if (binding instanceof LocalTypeBinding) {
        ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
        if (binding.isAnonymousType()) {
            ref.setSimpleName(JDTTreeBuilderHelper
                    .computeAnonymousName(((SourceTypeBinding) binding).constantPoolName()));
            ref.setDeclaringType(getTypeReference(binding.enclosingType()));
        } else {
            ref.setSimpleName(new String(binding.sourceName()));
            if (((LocalTypeBinding) binding).enclosingMethod == null && binding.enclosingType() != null
                    && binding.enclosingType() instanceof LocalTypeBinding) {
                ref.setDeclaringType(getTypeReference(binding.enclosingType()));
            } else if (binding.enclosingMethod() != null) {
                ref.setSimpleName(JDTTreeBuilderHelper
                        .computeAnonymousName(((SourceTypeBinding) binding).constantPoolName()));
                ref.setDeclaringType(getTypeReference(binding.enclosingType()));
            }
        }
    } else if (binding instanceof SourceTypeBinding) {
        ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
        if (binding.isAnonymousType()) {
            ref.setSimpleName(JDTTreeBuilderHelper
                    .computeAnonymousName(((SourceTypeBinding) binding).constantPoolName()));
            ref.setDeclaringType(getTypeReference(binding.enclosingType()));
        } else {
            ref.setSimpleName(new String(binding.sourceName()));
            if (binding.enclosingType() != null) {
                ref.setDeclaringType(getTypeReference(binding.enclosingType()));
            } else {
                ref.setPackage(getPackageReference(binding.getPackage()));
            }
        }
    } else if (binding instanceof ArrayBinding) {
        CtArrayTypeReference<Object> arrayref;
        arrayref = this.jdtTreeBuilder.getFactory().Core().createArrayTypeReference();
        ref = arrayref;
        for (int i = 1; i < binding.dimensions(); i++) {
            CtArrayTypeReference<Object> tmp = this.jdtTreeBuilder.getFactory().Core()
                    .createArrayTypeReference();
            arrayref.setComponentType(tmp);
            arrayref = tmp;
        }
        arrayref.setComponentType(getTypeReference(binding.leafComponentType(), resolveGeneric));
    } else if (binding instanceof PolyTypeBinding) {
        // JDT can't resolve the type of this binding and we only have a string.
        // In this case, we return a type Object because we can't know more about it.
        ref = this.jdtTreeBuilder.getFactory().Type().objectType();
    } else if (binding instanceof ProblemReferenceBinding) {
        // Spoon is able to analyze also without the classpath
        ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
        char[] readableName = binding.readableName();
        StringBuilder sb = new StringBuilder();
        for (int i = readableName.length - 1; i >= 0; i--) {
            char c = readableName[i];
            if (c == '.') {
                break;
            }
            sb.append(c);
        }
        sb.reverse();
        ref.setSimpleName(sb.toString());
        final CtReference declaring = this.getDeclaringReferenceFromImports(binding.sourceName());
        setPackageOrDeclaringType(ref, declaring);
    } else if (binding instanceof JDTTreeBuilder.SpoonReferenceBinding) {
        ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
        ref.setSimpleName(new String(binding.sourceName()));
        ref.setDeclaringType(getTypeReference(binding.enclosingType()));
    } else if (binding instanceof IntersectionTypeBinding18) {
        List<CtTypeReference<?>> bounds = new ArrayList<>();
        for (ReferenceBinding superInterface : binding.getIntersectingTypes()) {
            bounds.add(getTypeReference(superInterface));
        }
        ref = this.jdtTreeBuilder.getFactory().Type().createIntersectionTypeReferenceWithBounds(bounds);
    } else {
        throw new RuntimeException("Unknown TypeBinding: " + binding.getClass() + " " + binding);
    }
    bindingCache.remove(binding);
    this.exploringParameterizedBindings.remove(binding);
    return (CtTypeReference<T>) ref;
}

From source file:spoon.test.prettyprinter.testclasses.ComplexClass.java

License:Open Source License

@SuppressWarnings("unchecked")
<T> CtTypeReference<T> getTypeReference(TypeBinding binding) {
    if (binding == null) {
        return null;
    }/*from ww  w .ja v  a  2  s .  c o m*/

    CtTypeReference<?> ref = null;

    if (binding instanceof RawTypeBinding) {
        ref = getTypeReference(((ParameterizedTypeBinding) binding).genericType());
    } else if (binding instanceof ParameterizedTypeBinding) {
        if (binding.actualType() != null && binding.actualType() instanceof LocalTypeBinding) {
            // When we define a nested class in a method and when the enclosing class of this method
            // is a parameterized type binding, JDT give a ParameterizedTypeBinding for the nested class
            // and hide the real class in actualType().
            ref = getTypeReference(binding.actualType());
        } else {
            ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
            this.exploringParameterizedBindings.put(binding, ref);
            if (binding.isAnonymousType()) {
                ref.setSimpleName("");
            } else {
                ref.setSimpleName(String.valueOf(binding.sourceName()));
                if (binding.enclosingType() != null) {
                    ref.setDeclaringType(getTypeReference(binding.enclosingType()));
                } else {
                    ref.setPackage(getPackageReference(binding.getPackage()));
                }
            }
        }
        if (binding.actualType() instanceof MissingTypeBinding) {
            ref = getTypeReference(binding.actualType());
        }

        if (((ParameterizedTypeBinding) binding).arguments != null) {
            for (TypeBinding b : ((ParameterizedTypeBinding) binding).arguments) {
                if (bindingCache.containsKey(b)) {
                    ref.addActualTypeArgument(getCtCircularTypeReference(b));
                } else {
                    if (!this.exploringParameterizedBindings.containsKey(b)) {
                        this.exploringParameterizedBindings.put(b, null);
                        CtTypeReference typeRefB = getTypeReference(b);
                        this.exploringParameterizedBindings.put(b, typeRefB);
                        ref.addActualTypeArgument(typeRefB);
                    } else {
                        CtTypeReference typeRefB = this.exploringParameterizedBindings.get(b);
                        if (typeRefB != null) {
                            ref.addActualTypeArgument(typeRefB.clone());
                        }
                    }
                }
            }
        }
    } else if (binding instanceof MissingTypeBinding) {
        ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
        ref.setSimpleName(new String(binding.sourceName()));
        ref.setPackage(getPackageReference(binding.getPackage()));
        if (!this.jdtTreeBuilder.getContextBuilder().ignoreComputeImports) {
            final CtReference declaring = this.getDeclaringReferenceFromImports(binding.sourceName());
            if (declaring instanceof CtPackageReference) {
                ref.setPackage((CtPackageReference) declaring);
            } else if (declaring instanceof CtTypeReference) {
                ref.setDeclaringType((CtTypeReference) declaring);
            }
        }
    } else if (binding instanceof BinaryTypeBinding) {
        ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
        if (binding.enclosingType() != null) {
            ref.setDeclaringType(getTypeReference(binding.enclosingType()));
        } else {
            ref.setPackage(getPackageReference(binding.getPackage()));
        }
        ref.setSimpleName(new String(binding.sourceName()));
    } else if (binding instanceof TypeVariableBinding) {
        boolean oldBounds = bounds;

        if (binding instanceof CaptureBinding) {
            ref = this.jdtTreeBuilder.getFactory().Core().createWildcardReference();
            bounds = true;
        } else {
            TypeVariableBinding typeParamBinding = (TypeVariableBinding) binding;
            ReferenceBinding superClass = typeParamBinding.superclass;
            ReferenceBinding[] superInterfaces = typeParamBinding.superInterfaces();

            CtTypeReference refSuperClass = null;

            // if the type parameter has a super class other than java.lang.Object, we get it
            // superClass.superclass() is null if it's java.lang.Object
            if (superClass != null && !(superClass.superclass() == null)) {

                // this case could happen with Enum<E extends Enum<E>> for example:
                // in that case we only want to have E -> Enum -> E
                // to conserve the same behavior as JavaReflectionTreeBuilder
                if (!(superClass instanceof ParameterizedTypeBinding)
                        || !this.exploringParameterizedBindings.containsKey(superClass)) {
                    refSuperClass = this.getTypeReference(superClass);
                }

                // if the type parameter has a super interface, then we'll get it too, as a superclass
                // type parameter can only extends an interface or a class, so we don't make the distinction
                // in Spoon. Moreover we can only have one extends in a type parameter.
            } else if (superInterfaces != null && superInterfaces.length == 1) {
                refSuperClass = this.getTypeReference(superInterfaces[0]);
            }

            ref = this.jdtTreeBuilder.getFactory().Core().createTypeParameterReference();
            ref.setSimpleName(new String(binding.sourceName()));

            if (refSuperClass != null) {
                ((CtTypeParameterReference) ref).addBound(refSuperClass);
            }
        }
        TypeVariableBinding b = (TypeVariableBinding) binding;
        if (bounds) {
            if (b instanceof CaptureBinding && ((CaptureBinding) b).wildcard != null) {
                bounds = oldBounds;
                return getTypeReference(((CaptureBinding) b).wildcard);
            } else if (b.superclass != null && b.firstBound == b.superclass) {
                bounds = false;
                bindingCache.put(binding, ref);
                ((CtTypeParameterReference) ref).setBoundingType(getTypeReference(b.superclass));
                bounds = oldBounds;
            }
        }
        if (bounds && b.superInterfaces != null && b.superInterfaces != Binding.NO_SUPERINTERFACES) {
            bounds = false;
            bindingCache.put(binding, ref);
            List<CtTypeReference<?>> bounds = new ArrayList<>();
            CtTypeParameterReference typeParameterReference = (CtTypeParameterReference) ref;
            if (!(typeParameterReference.isDefaultBoundingType())) { // if it's object we can ignore it
                bounds.add(typeParameterReference.getBoundingType());
            }
            for (ReferenceBinding superInterface : b.superInterfaces) {
                bounds.add(getTypeReference(superInterface));
            }
            ((CtTypeParameterReference) ref).setBoundingType(
                    this.jdtTreeBuilder.getFactory().Type().createIntersectionTypeReferenceWithBounds(bounds));
        }
        if (binding instanceof CaptureBinding) {
            bounds = false;
        }
    } else if (binding instanceof BaseTypeBinding) {
        String name = new String(binding.sourceName());
        //always create new TypeReference, because clonning from a cache clones invalid SourcePosition
        ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
        ref.setSimpleName(name);
    } else if (binding instanceof WildcardBinding) {
        WildcardBinding wildcardBinding = (WildcardBinding) binding;
        ref = this.jdtTreeBuilder.getFactory().Core().createWildcardReference();

        if (wildcardBinding.boundKind == Wildcard.SUPER && ref instanceof CtTypeParameterReference) {
            ((CtTypeParameterReference) ref).setUpper(false);
        }

        if (wildcardBinding.bound != null && ref instanceof CtTypeParameterReference) {
            if (bindingCache.containsKey(wildcardBinding.bound)) {
                ((CtTypeParameterReference) ref)
                        .setBoundingType(getCtCircularTypeReference(wildcardBinding.bound));
            } else {

                ((CtTypeParameterReference) ref)
                        .setBoundingType(getTypeReference(((WildcardBinding) binding).bound));
            }
        }
    } else if (binding instanceof LocalTypeBinding) {
        ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
        if (binding.isAnonymousType()) {
            ref.setSimpleName(JDTTreeBuilderHelper
                    .computeAnonymousName(((SourceTypeBinding) binding).constantPoolName()));
            ref.setDeclaringType(getTypeReference((binding.enclosingType())));
        } else {
            ref.setSimpleName(new String(binding.sourceName()));
            if (((LocalTypeBinding) binding).enclosingMethod == null && binding.enclosingType() != null
                    && binding.enclosingType() instanceof LocalTypeBinding) {
                ref.setDeclaringType(getTypeReference(binding.enclosingType()));
            } else if (binding.enclosingMethod() != null) {
                ref.setSimpleName(JDTTreeBuilderHelper
                        .computeAnonymousName(((SourceTypeBinding) binding).constantPoolName()));
                ref.setDeclaringType(getTypeReference(binding.enclosingType()));
            }
        }
    } else if (binding instanceof SourceTypeBinding) {
        ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
        if (binding.isAnonymousType()) {
            ref.setSimpleName(JDTTreeBuilderHelper
                    .computeAnonymousName(((SourceTypeBinding) binding).constantPoolName()));
            ref.setDeclaringType(getTypeReference((binding.enclosingType())));
        } else {
            ref.setSimpleName(new String(binding.sourceName()));
            if (binding.enclosingType() != null) {
                ref.setDeclaringType(getTypeReference(binding.enclosingType()));
            } else {
                ref.setPackage(getPackageReference(binding.getPackage()));
            }
            // if(((SourceTypeBinding) binding).typeVariables!=null &&
            // ((SourceTypeBinding) binding).typeVariables.length>0){
            // for (TypeBinding b : ((SourceTypeBinding)
            // binding).typeVariables) {
            // ref.getActualTypeArguments().add(getTypeReference(b));
            // }
            // }
        }
    } else if (binding instanceof ArrayBinding) {
        CtArrayTypeReference<Object> arrayref;
        arrayref = this.jdtTreeBuilder.getFactory().Core().createArrayTypeReference();
        ref = arrayref;
        for (int i = 1; i < binding.dimensions(); i++) {
            CtArrayTypeReference<Object> tmp = this.jdtTreeBuilder.getFactory().Core()
                    .createArrayTypeReference();
            arrayref.setComponentType(tmp);
            arrayref = tmp;
        }
        arrayref.setComponentType(getTypeReference(binding.leafComponentType()));
    } else if (binding instanceof PolyTypeBinding) {
        // JDT can't resolve the type of this binding and we only have a string.
        // In this case, we return a type Object because we can't know more about it.
        ref = this.jdtTreeBuilder.getFactory().Type().objectType();
    } else if (binding instanceof ProblemReferenceBinding) {
        // Spoon is able to analyze also without the classpath
        ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
        ref.setSimpleName(new String(binding.readableName()));
        final CtReference declaring = this.getDeclaringReferenceFromImports(binding.sourceName());
        setPackageOrDeclaringType(ref, declaring);
    } else if (binding instanceof JDTTreeBuilder.SpoonReferenceBinding) {
        ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
        ref.setSimpleName(new String(binding.sourceName()));
        ref.setDeclaringType(getTypeReference(binding.enclosingType()));
    } else if (binding instanceof IntersectionTypeBinding18) {
        List<CtTypeReference<?>> bounds = new ArrayList<>();
        for (ReferenceBinding superInterface : binding.getIntersectingTypes()) {
            bounds.add(getTypeReference(superInterface));
        }
        ref = this.jdtTreeBuilder.getFactory().Type().createIntersectionTypeReferenceWithBounds(bounds);
    } else {
        throw new RuntimeException("Unknown TypeBinding: " + binding.getClass() + " " + binding);
    }
    bindingCache.remove(binding);
    this.exploringParameterizedBindings.remove(binding);
    return (CtTypeReference<T>) ref;
}