public boolean hasSignificantHints(List<LightweightBoundTypeArgument> hints) { return hasSignificantHints(hints, true); }
public boolean hasSignificantHints() { if (internalIsResolved()) return true; List<LightweightBoundTypeArgument> hints = getAllHints(); if (!hints.isEmpty() && hasSignificantHints(hints)) return true; return false; }
protected int doIsConformant(UnboundTypeReference left, UnboundTypeReference right, int flags) { if (left.getHandle().equals(right.getHandle())) { return flags | SUCCESS; } List<LightweightBoundTypeArgument> leftHints = left.getAllHints(); List<LightweightBoundTypeArgument> rightHints = right.getAllHints(); if ((flags & UNBOUND_COMPUTATION_ADDS_HINTS) != 0) { if (leftHints.isEmpty() || rightHints.isEmpty() || !left.hasSignificantHints(leftHints) || !right.hasSignificantHints()) { left.acceptHint(right, BoundTypeArgumentSource.INFERRED, this, VarianceInfo.OUT, VarianceInfo.OUT); return flags | SUCCESS; } } if (leftHints.equals(rightHints)) { return flags | SUCCESS; } return tryResolveAndCheckConformance(left, right, flags); }
/** * Try to resolve this reference iff there are hints available. * May be invoked multiple times since it will simply returns if * the reference is already resolved. The caller can decide whether * type constraints are considered to be significant hints or not. */ public void tryResolve(boolean constraintsAreSignificant) { if (internalIsResolved()) return; List<LightweightBoundTypeArgument> hints = getAllHints(); if (!hints.isEmpty() && hasSignificantHints(hints, constraintsAreSignificant)) { resolveWithHints(hints); } }
/** * Returns true if the existing hints would allow to resolve to the given reference. */ public boolean canResolveTo(LightweightTypeReference reference) { if (internalIsResolved()) return reference.isAssignableFrom(resolvedTo, new TypeConformanceComputationArgument(false, true, true, true, false, false /* TODO do we need to support synonmys here? */)); List<LightweightBoundTypeArgument> hints = getAllHints(); if (!hints.isEmpty() && hasSignificantHints(hints)) { return canResolveTo(reference, hints); } return false; }
protected int doIsConformant(LightweightTypeReference left, UnboundTypeReference right, int flags) { if (left.getType() == right.getType() || left.isType(Object.class)) { return flags | SUCCESS; } if ((flags & ALLOW_UNBOXING) == 0 && left.isPrimitive()) { return flags; } boolean doesNotHaveSignificantHints = false; if (((flags & RAW_TYPE) == 0) && (right.canResolveTo(left) || (flags & AS_TYPE_ARGUMENT) != 0 && (doesNotHaveSignificantHints = !right.hasSignificantHints()))) { if ((flags & UNBOUND_COMPUTATION_ADDS_HINTS) != 0 && doesNotHaveSignificantHints) { right.acceptHint(left, BoundTypeArgumentSource.INFERRED_LATER, left, VarianceInfo.INVARIANT, VarianceInfo.INVARIANT); } return flags | SUCCESS; } right.tryResolve(false); LightweightTypeReference resolvedTo = right.getResolvedTo(); if (resolvedTo != null) { return doIsConformant(left, resolvedTo, flags); } return flags; }
UnboundTypeReference casted = (UnboundTypeReference)operationParameterType; boolean isSkippedHandle = casted.getHandle().equals(skippedHandle); if (!isSkippedHandle && !casted.internalIsResolved() && casted.hasSignificantHints()) { casted.acceptHint(VarianceInfo.IN);
@Override protected void addHint(UnboundTypeReference typeParameter, LightweightTypeReference reference) { if (!typeParameter.internalIsResolved() && getExpectedVariance() == VarianceInfo.INVARIANT) { if (getExpectedVariance() == getActualVariance() && reference.getKind() != LightweightTypeReference.KIND_UNBOUND_TYPE_REFERENCE) { doAddHint(typeParameter, reference, BoundTypeArgumentSource.INFERRED_EXPECTATION); } else if (getActualVariance() == VarianceInfo.IN && !typeParameter.hasSignificantHints()) { if (reference.getKind() != LightweightTypeReference.KIND_UNBOUND_TYPE_REFERENCE) { doAddHint(typeParameter, reference, BoundTypeArgumentSource.INFERRED_EXPECTATION); } else { UnboundTypeReference casted = (UnboundTypeReference)reference; List<LightweightBoundTypeArgument> hints = casted.getAllHints(); for(LightweightBoundTypeArgument hint: hints) { // avoid bogus transitive hints, e.g. if a reference was used with another variance // INFERRED_LATER serves as an indicator for these hints if (hint.getSource() == BoundTypeArgumentSource.INFERRED_LATER) { return; } } doAddHint(typeParameter, reference, BoundTypeArgumentSource.INFERRED_EXPECTATION); } } } }