protected ConstraintVisitingInfo createVisiting(JvmTypeParameter initialValue) { ConstraintVisitingInfo result = createVisiting(); result.tryVisit(initialValue); return result; } }
protected LightweightTypeReference getDeclaredUpperBound(/* @Nullable */ JvmTypeParameterDeclarator type, int parameterIndex, ConstraintVisitingInfo visiting) { if (type != null && type.getTypeParameters().size() > parameterIndex) { JvmTypeParameter typeParameter = type.getTypeParameters().get(parameterIndex); LightweightTypeReference result = getDeclaredUpperBound(typeParameter, visiting); if (result != null) return result; } return getObjectReference(); }
protected boolean isDeclaredTypeParameter(JvmTypeParameter typeParameter) { return getOwner().getDeclaredTypeParameters().contains(typeParameter); }
@Override public LightweightTypeReference doVisitParameterizedTypeReference(ParameterizedTypeReference reference, ConstraintVisitingInfo visiting) { if (reference.isResolved() && reference.isOwnedBy(getOwner())) return reference; JvmType type = reference.getType(); 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; } else { LightweightMergedBoundTypeArgument candidate = getTypeParameterMapping().get(typeParameter); if (candidate != null && candidate.getTypeReference() != null) return candidate.getTypeReference(); LightweightTypeReference mappedReference = getDeclaredUpperBound(typeParameter, visiting); if (mappedReference == null) { mappedReference = getObjectReference(); getTypeParameterMapping().put((JvmTypeParameter)type, new LightweightMergedBoundTypeArgument(mappedReference, VarianceInfo.INVARIANT)); return mappedReference; LightweightMergedBoundTypeArgument boundTypeArgument = getBoundTypeArgument(typeParameter, visiting); if (boundTypeArgument != null && boundTypeArgument.getTypeReference() != reference) { LightweightTypeReference result = boundTypeArgument.getTypeReference().accept(this, visiting); if (boundTypeArgument.getVariance() == VarianceInfo.OUT) { WildcardTypeReference wildcard = getOwner().newWildcardTypeReference(); wildcard.addUpperBound(result.getInvariantBoundSubstitute());
@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; } }
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; }
/** * @param type the type parameter that is bound * @param info the current traversal state */ /* @Nullable */ protected LightweightMergedBoundTypeArgument getBoundTypeArgument(JvmTypeParameter type, ConstraintVisitingInfo info) { return getTypeParameterMapping().get(type); }
@Override protected LightweightTypeReference doVisitWildcardTypeReference(WildcardTypeReference reference, ConstraintVisitingInfo visiting) { if (reference.isResolved() && reference.isOwnedBy(getOwner())) return reference; LightweightTypeReference lowerBound = reference.getLowerBound(); if (lowerBound instanceof UnboundTypeReference) { if (!handles.add(((UnboundTypeReference) lowerBound).getHandle())) { WildcardTypeReference result = getOwner().newWildcardTypeReference(); for(LightweightTypeReference upperBound: reference.getUpperBounds()) { result.addUpperBound(visitTypeArgument(upperBound, visiting)); } return result; } } return super.doVisitWildcardTypeReference(reference, visiting); }
protected LightweightTypeReference getObjectReference() { return getOwner().newReferenceToObject(); }