protected JvmTypeParameter findMappedParameter(JvmTypeParameter parameter, Map<JvmTypeParameter, LightweightMergedBoundTypeArgument> mapping, Collection<JvmTypeParameter> visited) { for(Map.Entry<JvmTypeParameter, LightweightMergedBoundTypeArgument> entry: mapping.entrySet()) { LightweightMergedBoundTypeArgument reference = entry.getValue(); JvmType type = reference.getTypeReference().getType(); if (parameter == type) { if (visited.add(entry.getKey())) return entry.getKey(); return null; } } return null; } }
protected LightweightTypeReference getBoundTypeArgument(ParameterizedTypeReference reference, JvmTypeParameter type, Visiting visiting) { LightweightMergedBoundTypeArgument boundTypeArgument = typeParameterMapping.get(type); if (boundTypeArgument != null) { LightweightTypeReference boundReference = boundTypeArgument.getTypeReference(); if (boundReference != null && reference != boundReference && boundReference.getType() != type) { return boundReference.accept(this, visiting); } } return null; }
@Override public List<LightweightTypeReference> getTypeArguments() { if (typeArguments == null) { List<JvmTypeParameter> typeParameters = getDeclaredTypeParameters(); if (typeParameters.isEmpty() || getTypeParameterMapping().isEmpty()) { typeArguments = Collections.emptyList(); } else { List<LightweightTypeReference> result = Lists.newArrayListWithCapacity(typeParameters.size()); for(JvmTypeParameter parameter: typeParameters) { LightweightMergedBoundTypeArgument typeArgument = getTypeParameterMapping().get(parameter); result.add(typeArgument.getTypeReference()); } typeArguments = result; } } return typeArguments; }
public static JvmTypeParameter findMappedParameter(JvmTypeParameter parameter, Map<JvmTypeParameter, LightweightMergedBoundTypeArgument> mapping, Collection<JvmTypeParameter> visited) { for(Map.Entry<JvmTypeParameter, LightweightMergedBoundTypeArgument> entry: mapping.entrySet()) { LightweightTypeReference reference = entry.getValue().getTypeReference(); JvmType type = null; if (reference instanceof UnboundTypeReference) { type = ((UnboundTypeReference) reference).getTypeParameter(); } else { type = reference.getType(); } if (parameter == type) { if (visited.add(entry.getKey())) return entry.getKey(); return null; } } return null; }
@Override /* @Nullable */ protected LightweightMergedBoundTypeArgument getBoundTypeArgument(JvmTypeParameter type, ConstraintVisitingInfo info) { LightweightMergedBoundTypeArgument result = super.getBoundTypeArgument(type, info); if (result != null && result.getTypeReference().getType() == type) { return null; } return result; } };
@Override /* @Nullable */ protected LightweightTypeReference getBoundTypeArgument(ParameterizedTypeReference reference, JvmTypeParameter type, Set<JvmTypeParameter> visiting) { LightweightMergedBoundTypeArgument boundTypeArgument = getTypeParameterMapping().get(type); if (boundTypeArgument != null && boundTypeArgument.getTypeReference() != reference) { LightweightTypeReference boundReference = boundTypeArgument.getTypeReference(); if (boundTypeArgument.getVariance() == VarianceInfo.OUT) { WildcardTypeReference wildcard = getOwner().newWildcardTypeReference(); wildcard.addUpperBound(boundReference); boundReference = wildcard; } return boundReference.accept(this, visiting); } return null; } };
@Override /* @Nullable */ protected LightweightTypeReference getUnmappedSubstitute(ParameterizedTypeReference reference, JvmTypeParameter type, ConstraintVisitingInfo visiting) { if (!ignoreDeclaredTypeParameters) { if (isDeclaredTypeParameter(type)) { return reference; } } ConstraintAwareTypeArgumentCollector collector = new ConstraintAwareTypeArgumentCollector(getOwner()); LightweightTraversalData data = new LightweightTraversalData(); data.getTypeParameterMapping().putAll(getTypeParameterMapping()); reference.accept(collector, data); LightweightMergedBoundTypeArgument boundTypeArgument = data.getTypeParameterMapping().get(type); if (boundTypeArgument != null && boundTypeArgument.getTypeReference() != reference) { return boundTypeArgument.getTypeReference().accept(this, visiting); } if (boundTypeArgument != null) return boundTypeArgument.getTypeReference(); return null; }
@Override /* @Nullable */ protected LightweightTypeReference getBoundTypeArgument(ParameterizedTypeReference reference, JvmTypeParameter type, Set<JvmTypeParameter> visiting) { LightweightMergedBoundTypeArgument boundTypeArgument = getTypeParameterMapping().get(type); if (boundTypeArgument != null) { LightweightTypeReference boundReference = boundTypeArgument.getTypeReference(); if (boundReference != null && reference != boundReference) { if (boundReference instanceof UnboundTypeReference) return boundReference.copyInto(getOwner()); JvmType boundType = boundReference.getType(); if (boundType != type) { if (visiting.add(type)) { try { LightweightTypeReference result = boundReference.accept(this, visiting); return result; } finally { visiting.remove(type); } } else { return reference; } } } } return null; }
public static void resolveAgainstActualType(final LightweightTypeReference declaredType, LightweightTypeReference actualType, Collection<JvmTypeParameter> typeParameters, Map<JvmTypeParameter, LightweightMergedBoundTypeArgument> typeParameterMapping, BoundTypeArgumentSource source, ITypeReferenceOwner owner) { if (declaredType.isRawType() || actualType.isRawType()) return; TypeArgumentFromComputedTypeCollector implementation = new TypeArgumentFromComputedTypeCollector(typeParameters, source, owner); implementation.populateTypeParameterMapping(declaredType, actualType); Map<JvmTypeParameter, List<LightweightBoundTypeArgument>> parameterMapping = implementation.rawGetTypeParameterMapping(); for(Map.Entry<JvmTypeParameter, List<LightweightBoundTypeArgument>> entry: parameterMapping.entrySet()) { LightweightMergedBoundTypeArgument boundTypeArgument = typeParameterMapping.get(entry.getKey()); if (boundTypeArgument != null ) { List<LightweightBoundTypeArgument> computedBoundTypeArguments = entry.getValue(); for(LightweightBoundTypeArgument computedBoundTypeArgument: computedBoundTypeArguments) { if (computedBoundTypeArgument.getSource() == BoundTypeArgumentSource.RESOLVED) { VarianceInfo varianceInfo = computedBoundTypeArgument.getDeclaredVariance().mergeDeclaredWithActual(computedBoundTypeArgument.getActualVariance()); typeParameterMapping.put(entry.getKey(), new LightweightMergedBoundTypeArgument(computedBoundTypeArgument.getTypeReference(), varianceInfo)); } else if (boundTypeArgument.getTypeReference() instanceof UnboundTypeReference) { UnboundTypeReference typeReference = (UnboundTypeReference) boundTypeArgument.getTypeReference(); if (!typeReference.internalIsResolved()) { if (!(computedBoundTypeArgument.getTypeReference() instanceof UnboundTypeReference) || ((UnboundTypeReference) computedBoundTypeArgument.getTypeReference()).getHandle() != typeReference.getHandle()) typeReference.acceptHint(computedBoundTypeArgument); } } } } } }
@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); } }
@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); } }
LightweightTypeReference declaredTypeReference = declaredBoundArgument.getTypeReference(); JvmType declaredType = declaredTypeReference.getType(); if (declaredType instanceof JvmTypeParameter) { declaredTypeReference = declaredSubstitutor.substitute(declaredTypeReference); LightweightTypeReference actual = actualSubstitutor.substitute(actualMapping.get(actualBoundParameter).getTypeReference()); if (!actual.isResolved() || !declaredTypeReference.isResolved() || !Strings.equal(actual.getIdentifier(), declaredTypeReference.getIdentifier())) { if (reference.getType() != actual.getType()
@Override public LightweightTypeReference doVisitUnboundTypeReference(UnboundTypeReference reference, Set<JvmTypeParameter> visiting) { if (reference.getHandle() == left.getHandle()) { if (right.getKind() == KIND_UNBOUND_TYPE_REFERENCE) { UnboundTypeReference rightUnbound = (UnboundTypeReference) right; List<LightweightBoundTypeArgument> rightHints = rightUnbound.getAllHints(); for(LightweightBoundTypeArgument rightHint: rightHints) { LightweightTypeReference rightHintReference = rightHint.getTypeReference(); if (rightHintReference != null && leftHintReference.getUniqueIdentifier().equals(rightHintReference.getUniqueIdentifier())) { return super.doVisitUnboundTypeReference(reference, visiting); } } } return rightTypeArgument.getTypeReference(); } return super.doVisitUnboundTypeReference(reference, visiting); } };
JvmTypeParameter declaredTypeParameter = declaredTypeParameters.get(i); LightweightMergedBoundTypeArgument boundTypeArgument = typeParameterMapping.get(declaredTypeParameter); LightweightTypeReference boundReference = boundTypeArgument.getTypeReference(); if (boundReference instanceof UnboundTypeReference) { initializeConstraintMapping(declaredTypeParameter, substitutor, (UnboundTypeReference) boundReference);
LightweightMergedBoundTypeArgument typeArgument = getServices().getBoundTypeArgumentMerger().merge(!inferredHints.isEmpty() ? inferredHints : effectiveHints, getOwner()); if (typeArgument != null) { resolvedTo = typeArgument.getTypeReference(); if (resolvedTo != null) { boolean outResolvedToInvariant = varianceHints.contains(VarianceInfo.OUT) && varianceHints.size() == 1 && typeArgument.getVariance() == VarianceInfo.INVARIANT;
@Override /* @Nullable */ protected LightweightMergedBoundTypeArgument getBoundTypeArgument(JvmTypeParameter typeParameter, ConstraintVisitingInfo info) { LightweightMergedBoundTypeArgument result = super.getBoundTypeArgument(typeParameter, info); if (result != null) { LightweightTypeReference typeReference = result.getTypeReference(); if (result.getVariance() == VarianceInfo.INVARIANT) { if (typeReference.isWildcard() && typeReference.getLowerBoundSubstitute().isAny() && typeReference.getUpperBoundSubstitute().isType(Object.class)) { // assume unbound wildcard - use the constraints of the respective type parameter if (!typeParameter.getConstraints().isEmpty()) { JvmTypeConstraint constraint = typeParameter.getConstraints().get(0); if (constraint instanceof JvmUpperBound) { LightweightTypeReference reference = getOwner().toLightweightTypeReference(constraint.getTypeReference()); return new LightweightMergedBoundTypeArgument(reference, VarianceInfo.OUT); } } } } if (declaratorParameterMapping.containsKey(typeParameter) && typeReference.isWildcard()) { wasCapturedWildcard = true; } } return result; }
return false; VarianceInfo variance = merged.getVariance(); LightweightTypeReference type = merged.getTypeReference(); if (variance == null || type == null) { return false;
protected int isConformantMergeResult(LightweightMergedBoundTypeArgument mergeResult, LightweightTypeReference right, int flags) { LightweightTypeReference mergeResultReference = mergeResult.getTypeReference(); if (right.isWildcard() && mergeResultReference.isWildcard()) { if (right.getLowerBoundSubstitute().isAny()) { LightweightTypeReference lowerBoundMergeResult = mergeResultReference.getLowerBoundSubstitute(); if (!lowerBoundMergeResult.isAny()) { mergeResultReference = lowerBoundMergeResult; } } else { flags = flags | AS_TYPE_ARGUMENT; } } else if (mergeResultReference.isWildcard()) { flags = flags | AS_TYPE_ARGUMENT; } return isConformant(mergeResultReference, right, flags); }
} else { LightweightMergedBoundTypeArgument candidate = getTypeParameterMapping().get(typeParameter); if (candidate != null && candidate.getTypeReference() != null) return candidate.getTypeReference(); LightweightTypeReference mappedReference = getDeclaredUpperBound(typeParameter, visiting); if (mappedReference == null) { try { 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();