@Override protected ConstraintVisitingInfo createVisiting() { return new ConstraintVisitingInfo(); }
@Override protected LightweightTypeReference enhanceParameterizedTypeReference(ParameterizedTypeReference origin, JvmType type, ParameterizedTypeReference result, ConstraintVisitingInfo visiting) { for(int i = 0; i < origin.getTypeArguments().size(); i++) { LightweightTypeReference argument = origin.getTypeArguments().get(i); visiting.pushInfo(type instanceof JvmTypeParameterDeclarator ? (JvmTypeParameterDeclarator) type : null, i); LightweightTypeReference visitedArgument = visitTypeArgument(argument, visiting); result.addTypeArgument(visitedArgument); } return result; }
protected ConstraintVisitingInfo createVisiting(JvmTypeParameter initialValue) { ConstraintVisitingInfo result = createVisiting(); result.tryVisit(initialValue); return result; } }
@Override protected LightweightTypeReference doVisitUnboundTypeReference(UnboundTypeReference reference, ConstraintVisitingInfo visiting) { if (!handle.equals(reference.getHandle())) { return reference; } JvmTypeParameter typeParameter = reference.getTypeParameter(); if (!visiting.tryVisit(typeParameter)) { LightweightTypeReference mappedReference = getDeclaredUpperBound(typeParameter, visiting); getTypeParameterMapping().put(typeParameter, new LightweightMergedBoundTypeArgument(mappedReference, VarianceInfo.INVARIANT)); if (mappedReference != null) return mappedReference; return getObjectReference(); } try { LightweightMergedBoundTypeArgument boundTypeArgument = getTypeParameterMapping().get(typeParameter); if (boundTypeArgument != null && boundTypeArgument.getTypeReference() != reference) { LightweightTypeReference result = boundTypeArgument.getTypeReference().accept(this, visiting); return result; } else { LightweightTypeReference mappedReference = getDeclaredUpperBound(visiting.getCurrentDeclarator(), visiting.getCurrentIndex(), visiting); getTypeParameterMapping().put(typeParameter, new LightweightMergedBoundTypeArgument(mappedReference, VarianceInfo.INVARIANT)); return mappedReference; } } finally { visiting.didVisit(typeParameter); } }
protected LightweightTypeReference getDeclaredUpperBound(JvmTypeParameter typeParameter, ConstraintVisitingInfo visiting) { if (!typeParameter.getConstraints().isEmpty()) { JvmTypeConstraint constraint = typeParameter.getConstraints().get(0); if (constraint instanceof JvmUpperBound) { LightweightTypeReference reference = getOwner().toLightweightTypeReference(constraint.getTypeReference()); if (visiting.getCurrentDeclarator() != reference.getType()) { return visitTypeArgument(reference, visiting); } WildcardTypeReference result = getOwner().newWildcardTypeReference(); result.addUpperBound(getObjectReference()); return result; } } return null; }
@Override protected LightweightTypeReference visitTypeArgument(LightweightTypeReference reference, ConstraintVisitingInfo visiting, boolean lowerBound) { if (lowerBound && (reference instanceof ParameterizedTypeReference)) { if (reference.getType() instanceof JvmTypeParameter) { JvmTypeParameter typeParameter = (JvmTypeParameter) reference.getType(); // don't recurse into lower bounds of wildcards, e.g. constraint bound of // C extends Comparable<? super C> // is not // Comparable<? super Object> // but // Comparable<?> if (!visiting.canVisit(typeParameter)) { return getOwner().newWildcardExtendsObject(); } } } return super.visitTypeArgument(reference, visiting, lowerBound); }
@Override protected LightweightTypeReference doVisitUnboundTypeReference(UnboundTypeReference reference, ConstraintVisitingInfo visiting) { JvmTypeParameter typeParameter = reference.getTypeParameter(); if (!visiting.tryVisit(typeParameter)) { LightweightTypeReference mappedReference = getDeclaredUpperBound(typeParameter, visiting); getTypeParameterMapping().put(typeParameter, new LightweightMergedBoundTypeArgument(mappedReference, VarianceInfo.INVARIANT)); if (mappedReference != null) return mappedReference; return getObjectReference(); } try { LightweightMergedBoundTypeArgument boundTypeArgument = getTypeParameterMapping().get(typeParameter); if (boundTypeArgument != null && boundTypeArgument.getTypeReference() != reference) { LightweightTypeReference result = boundTypeArgument.getTypeReference().accept(this, visiting); return result; } else { JvmTypeParameterDeclarator currentDeclarator = visiting.getCurrentDeclarator(); LightweightTypeReference mappedReference = currentDeclarator != null ? getDeclaredUpperBound(currentDeclarator, visiting.getCurrentIndex(), visiting) : getDeclaredUpperBound(typeParameter, visiting); if (mappedReference == null) mappedReference = getObjectReference(); getTypeParameterMapping().put(typeParameter, new LightweightMergedBoundTypeArgument(mappedReference, VarianceInfo.INVARIANT)); return mappedReference; } } finally { visiting.didVisit(typeParameter); } }
@Override /* @Nullable */ protected LightweightTypeReference getDeclaredUpperBound(JvmTypeParameter typeParameter, ConstraintVisitingInfo visiting) { if (!typeParameter.getConstraints().isEmpty() && ((DeclaredConstraintVisitingInfo)visiting).tryVisitDeclaredUpperBoundsOf(typeParameter)) { try { JvmTypeConstraint constraint = typeParameter.getConstraints().get(0); if (constraint instanceof JvmUpperBound) { LightweightTypeReference reference = getOwner().toLightweightTypeReference(constraint.getTypeReference()); if (visiting.getCurrentDeclarator() != reference.getType()) { return reference.accept(this, visiting); } WildcardTypeReference result = getOwner().newWildcardTypeReference(); result.addUpperBound(getObjectReference()); return result; } } finally { ((DeclaredConstraintVisitingInfo)visiting).didVisitDeclaredUpperBoundsOf(typeParameter); } } return null; }
if (type instanceof JvmTypeParameter) { JvmTypeParameter typeParameter = (JvmTypeParameter) type; if (!visiting.tryVisit(typeParameter)) { if (!isDeclaredTypeParameter(typeParameter)) { if (visiting.getCurrentDeclarator() != null) { LightweightTypeReference mappedReference = getDeclaredUpperBound(visiting.getCurrentDeclarator(), visiting.getCurrentIndex(), visiting); getTypeParameterMapping().put((JvmTypeParameter)type, new LightweightMergedBoundTypeArgument(mappedReference, VarianceInfo.INVARIANT)); return mappedReference; visiting.didVisit(typeParameter);
@Override protected LightweightTypeReference enhanceParameterizedTypeReference(ParameterizedTypeReference reference, JvmType type, ParameterizedTypeReference result, ConstraintVisitingInfo visiting) { boolean convertToWildcard = false; for(int i = 0; i < reference.getTypeArguments().size(); i++) { wasCapturedWildcard = false; LightweightTypeReference argument = reference.getTypeArguments().get(i); visiting.pushInfo(type instanceof JvmTypeParameterDeclarator ? (JvmTypeParameterDeclarator) type : null, i); LightweightTypeReference visitedArgument = argument.accept(this, visiting); if (wasCapturedWildcard) convertToWildcard = true; wasCapturedWildcard = false; result.addTypeArgument(visitedArgument); } if (convertToWildcard) { WildcardTypeReference wildcard = result.getOwner().newWildcardTypeReference(); wildcard.addUpperBound(result); return wildcard; } return result; }
@Override public LightweightTypeReference substitute(LightweightTypeReference original) { if (original instanceof ArrayTypeReference) { LightweightTypeReference componentType = original.getComponentType(); if (componentType instanceof UnboundTypeReference) { LightweightTypeReference substitutedComponentType = substitute(componentType); return getOwner().newArrayTypeReference(substitutedComponentType); } } if (original instanceof UnboundTypeReference) { ConstraintVisitingInfo visitingInfo = createVisiting(); JvmTypeParameter typeParameter = ((UnboundTypeReference) original).getTypeParameter(); JvmTypeParameterDeclarator declarator = typeParameter.getDeclarator(); visitingInfo.pushInfo(declarator, declarator.getTypeParameters().indexOf(typeParameter)); LightweightTypeReference result = visitTypeArgument(original, visitingInfo); return result; } else { LightweightTypeReference result = original.accept(this, createVisiting()); return result; } }