List of usage examples for org.eclipse.jdt.internal.compiler.lookup TypeBinding dimensions
public int dimensions()
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; }