protected int doIsConformant(LightweightTypeReference left, WildcardTypeReference right, int flags) { if ((flags & AS_TYPE_ARGUMENT) == 0 || (flags & AS_NESTED_TYPE_ARGUMENT) != 0) { for(LightweightTypeReference upperBound: right.getUpperBounds()) { int result = doIsConformant(left, upperBound, flags); if ((result & SUCCESS) != 0) { return result; } } } return flags; }
protected int addHintAndAnnounceSuccess(UnboundTypeReference left, LightweightTypeReference hint, int flags) { if (hint instanceof WildcardTypeReference) { List<LightweightTypeReference> bounds = ((WildcardTypeReference) hint).getUpperBounds(); for(LightweightTypeReference upperBound: bounds) left.acceptHint(upperBound, BoundTypeArgumentSource.INFERRED, this, VarianceInfo.OUT, VarianceInfo.OUT); } else { left.acceptHint(hint, BoundTypeArgumentSource.INFERRED, this, VarianceInfo.OUT, VarianceInfo.OUT); } return flags | SUCCESS; }
@Override protected List<JvmType> doVisitWildcardTypeReference(WildcardTypeReference reference, ResourceSet resourceSet) { if (reference.isUnbounded()) { return createObjectReference(resourceSet); } List<LightweightTypeReference> upperBounds = reference.getUpperBounds(); if (upperBounds.isEmpty()) { throw new IllegalStateException("UpperBounds may not be empty"); } return collectRawTypes(upperBounds, resourceSet); }
@Override protected List<LightweightTypeReference> getSuperTypes(TypeParameterSubstitutor<?> substitutor) { if (isUnbounded()) { return Collections.singletonList(getUpperBoundSubstitute()); } List<LightweightTypeReference> nonNullUpperBounds = expose(getUpperBounds()); List<LightweightTypeReference> result = Lists.newArrayListWithCapacity(nonNullUpperBounds.size()); for(LightweightTypeReference upperBound: nonNullUpperBounds) { result.add(substitutor.substitute(upperBound)); } return result; }
@Override protected void doVisitWildcardTypeReference(WildcardTypeReference reference, StringBuilder param) { param.append("?"); if (reference.getLowerBound() != null) { param.append(" super "); reference.getLowerBound().accept(this, param); } else { List<LightweightTypeReference> upperBounds = reference.getUpperBounds(); if (!upperBounds.isEmpty()) { if (upperBounds.size() == 1 && upperBounds.get(0).isType(Object.class)) { return; } param.append(" extends "); for(int i = 0; i < upperBounds.size(); i++) { if (i != 0) { param.append(" & "); } upperBounds.get(i).accept(this, param); } } } }
@Override protected void doVisitWildcardTypeReference(WildcardTypeReference reference, ArrayTypeReference declaration) { LightweightTypeReference lowerBound = reference.getLowerBound(); if (lowerBound != null) { outerVisit(declaration, lowerBound, declaration, expectedVariance, VarianceInfo.IN); } else { for(LightweightTypeReference upperBound: reference.getUpperBounds()) { outerVisit(declaration, upperBound, declaration, expectedVariance, VarianceInfo.OUT); } } } }
@Override protected LightweightTypeReference doVisitWildcardTypeReference(WildcardTypeReference reference, ResourceSet resourceSet) { if (reference.isUnbounded()) { return reference.getUpperBoundSubstitute(); } if (reference.getUpperBounds().size() == 1) { return reference.getUpperBoundSubstitute().accept(this, resourceSet); } CompoundTypeReference result = reference.getOwner().newCompoundTypeReference(false); enhanceCompoundReference(reference.getUpperBounds(), result, resourceSet); return result; }
@Override protected void doVisitWildcardTypeReference(WildcardTypeReference reference, ArrayTypeReference declaration) { LightweightTypeReference lowerBound = reference.getLowerBound(); if (lowerBound != null) { outerVisit(declaration, lowerBound); } else { for(LightweightTypeReference upperBound: reference.getUpperBounds()) { outerVisit(declaration, upperBound); } } } };
@Override protected LightweightTypeReference doVisitWildcardTypeReference(final WildcardTypeReference reference) { final LightweightTypeReference unknownType = this.visit(reference.getUpperBounds()); if ((unknownType != null)) { return unknownType; } final LightweightTypeReference lowerBound = reference.getLowerBound(); if ((lowerBound != null)) { return lowerBound.<LightweightTypeReference>accept(this); } return null; }
@Override public void doVisitTypeReference(LightweightTypeReference reference, WildcardTypeReference declaration) { LightweightTypeReference declaredLowerBound = declaration.getLowerBound(); if (declaredLowerBound != null) { outerVisit(declaredLowerBound, reference, declaration, VarianceInfo.IN, VarianceInfo.INVARIANT); } else { for (LightweightTypeReference declaredUpperBound : declaration.getUpperBounds()) { outerVisit(declaredUpperBound, reference, declaration, VarianceInfo.OUT, VarianceInfo.INVARIANT); } } } }
@Override protected void doVisitWildcardTypeReference(WildcardTypeReference reference, ParameterizedTypeReference declaration) { LightweightTypeReference lowerBound = reference.getLowerBound(); if (lowerBound != null) { outerVisit(declaration, lowerBound, declaration, expectedVariance, VarianceInfo.IN); } else { for(LightweightTypeReference upperBound: reference.getUpperBounds()) { outerVisit(declaration, upperBound, declaration, expectedVariance, VarianceInfo.OUT); } } }
@Override protected LocalTypeSubstitutor.SubstitutionResult doVisitWildcardTypeReference(WildcardTypeReference reference, VarianceInfo varianceInfo) { WildcardTypeReference result = owner.newWildcardTypeReference(); LightweightTypeReference lowerBound = reference.getLowerBound(); boolean didSubstitute = false; if (lowerBound != null) { SubstitutionResult visited = lowerBound.accept(this, VarianceInfo.IN); result.setLowerBound(visited.typeReference); didSubstitute = didSubstitute || visited.didSubstitute; } for(LightweightTypeReference upperBound: reference.getUpperBounds()) { SubstitutionResult visited = upperBound.accept(this, VarianceInfo.OUT); result.addUpperBound(visited.typeReference); didSubstitute = didSubstitute || visited.didSubstitute; } if (result.getUpperBounds().isEmpty()) { throw new IllegalStateException("UpperBounds may not be empty"); } return new SubstitutionResult(result, didSubstitute); }
@Override protected void doVisitWildcardTypeReference(WildcardTypeReference reference, WildcardTypeReference declaration) { LightweightTypeReference declaredLowerBound = declaration.getLowerBound(); if (declaredLowerBound != null) { LightweightTypeReference actualLowerBound = reference.getLowerBound(); if (actualLowerBound != null) { outerVisit(declaredLowerBound, actualLowerBound, declaration, VarianceInfo.IN, VarianceInfo.IN); } else { for (LightweightTypeReference actualUpperBound : reference.getUpperBounds()) { outerVisit(declaredLowerBound, actualUpperBound, declaration, VarianceInfo.IN, VarianceInfo.OUT); } } } else { LightweightTypeReference actualLowerBound = reference.getLowerBound(); for (LightweightTypeReference declaredUpperBound : declaration.getUpperBounds()) { for (LightweightTypeReference actualUpperBound : reference.getUpperBounds()) { outerVisit(declaredUpperBound, actualUpperBound, declaration, VarianceInfo.OUT, VarianceInfo.OUT); } if (actualLowerBound != null) { outerVisit(declaredUpperBound, actualLowerBound, declaration, VarianceInfo.OUT, VarianceInfo.IN); } } } }
@Override /* @Nullable */ public LightweightTypeReference getSuperType(Class<?> rawType) { if (isUnbounded()) { if (Object.class.equals(rawType)) { return internalFindTopLevelType(rawType); } return null; } List<LightweightTypeReference> nonNullUpperBounds = expose(getUpperBounds()); for(LightweightTypeReference upperBound: nonNullUpperBounds) { LightweightTypeReference result = upperBound.getSuperType(rawType); if (result != null) return result; } return null; }
@Override public LightweightTypeReference getUpperBoundSubstitute() { if (isUnbounded()) { return getOwner().newReferenceToObject(); } List<LightweightTypeReference> upperBounds = getUpperBounds(); if (upperBounds.size() == 1) { LightweightTypeReference result = upperBounds.get(0); return result; } CompoundTypeReference result = getOwner().newCompoundTypeReference(false); for(LightweightTypeReference upperBound: upperBounds) { result.addComponent(upperBound); } return result; }
@Override /* @Nullable */ public LightweightTypeReference getSuperType(JvmType rawType) { if (isUnbounded()) { if (Object.class.getName().equals(rawType.getIdentifier())) { return getOwner().newParameterizedTypeReference(rawType); } return null; } List<LightweightTypeReference> nonNullUpperBounds = expose(getUpperBounds()); for(LightweightTypeReference upperBound: nonNullUpperBounds) { LightweightTypeReference result = upperBound.getSuperType(rawType); if (result != null) return result; } return null; }
@Override protected Boolean doVisitWildcardTypeReference(WildcardTypeReference reference) { if (reference.isResolved()) { return true; } if (!visit(reference.getUpperBounds())) { return false; } LightweightTypeReference lowerBound = reference.getLowerBound(); if (lowerBound != null) { return lowerBound.accept(this); } return true; }
@Override protected void doVisitWildcardTypeReference(WildcardTypeReference reference, UnboundTypeReference declaration) { LightweightTypeReference lowerBound = reference.getLowerBound(); if (lowerBound != null) { outerVisit(declaration, lowerBound, declaration, getExpectedVariance(), VarianceInfo.IN); } else { for (LightweightTypeReference upperBound : reference.getUpperBounds()) { outerVisit(declaration, upperBound, declaration, getExpectedVariance(), VarianceInfo.OUT); } } }
@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); }
@Override public void doVisitUnboundTypeReference(UnboundTypeReference reference, WildcardTypeReference declaration) { if (declaration.getLowerBound() == null) { if (!reference.internalIsResolved()) { List<LightweightTypeReference> upperBounds = declaration.getUpperBounds(); for(LightweightTypeReference upperBound: upperBounds) { if (!upperBound.isResolved() || !reference.canResolveTo(upperBound)) { super.doVisitUnboundTypeReference(reference, declaration); return; } } reference.tryResolve(); if (reference.internalIsResolved()) { outerVisit(reference, declaration); } else { addHint(reference, declaration); } return; } } super.doVisitUnboundTypeReference(reference, declaration); } }