@Override protected void doVisitUnboundTypeReference(UnboundTypeReference reference, ArrayTypeReference declaration) { if (shouldProcess(reference.getTypeParameter())) { processTypeParameter(reference.getTypeParameter(), declaration); } }
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 */ public JvmType getType() { if (internalIsResolved()) return resolvedTo.getType(); return getTypeParameter(); }
protected UnboundTypeReference createCopy(ITypeReferenceOwner owner) { UnboundTypeReference result = new UnboundTypeReference(owner, expression, getTypeParameter(), getHandle()); return result; }
@Override protected void doVisitWildcardTypeReference(WildcardTypeReference reference, UnboundTypeReference declaration) { if (shouldProcess(declaration.getTypeParameter())) { declaration.acceptHint(boundByInference(reference)); } else { super.doVisitWildcardTypeReference(reference, declaration); } } };
@Override protected List<JvmType> doVisitUnboundTypeReference(UnboundTypeReference reference, ResourceSet resourceSet) { List<LightweightBoundTypeArgument> hints = reference.getAllHints(); if (!hints.isEmpty()) { if (reference.resolveWithHints(hints)) { LightweightTypeReference resolvedTo = reference.getResolvedTo(); if (resolvedTo != null) return resolvedTo.accept(this, resourceSet); } } JvmTypeParameter typeParameter = reference.getTypeParameter(); return getRawTypesFromConstraints(reference.getOwner(), typeParameter, resourceSet); }
@Override public void doVisitUnboundTypeReference(UnboundTypeReference reference, ParameterizedTypeReference declaration) { JvmType type = declaration.getType(); if (type instanceof JvmTypeParameter) { JvmTypeParameter unboundTypeParameter = (JvmTypeParameter) type; if (unboundTypeParameter != reference.getTypeParameter() && shouldProcess(unboundTypeParameter)) { processTypeParameter(unboundTypeParameter, reference); } else { // register synonym type param resolution et al for the actual type in the given UnboundTypeParameter } } else { acceptHint(reference, declaration); } }
/** * Returns the substituted expected type for the argument at {@code argumentIndex}. * If the expected type is an unbound type parameter, a reference to the type parameter * itself is returned. */ /* @Nullable */ protected LightweightTypeReference getSubstitutedExpectedType(int argumentIndex) { XExpression expression = arguments.getArgument(argumentIndex); if (expression == null) return null; LightweightTypeReference expectedType = getExpectedType(expression); if (expectedType != null) { // don't use UnboundTypeReference.getRawTypeReference since that would potentially resolve the unbound candidate if (expectedType instanceof UnboundTypeReference) { JvmTypeParameter typeParameter = ((UnboundTypeReference) expectedType).getTypeParameter(); expectedType = expectedType.getOwner().newParameterizedTypeReference(typeParameter); } } return expectedType; }
@Override protected void acceptHint(UnboundTypeReference reference, LightweightTypeReference param) { if (!shouldProcess(reference.getTypeParameter())) { reference.tryResolve(); if (reference.internalIsResolved()) { outerVisit(reference, param); } else { super.acceptHint(reference, param); } } else { reference.acceptHint(boundByInference(param)); } }
final LightweightMergedBoundTypeArgument rightTypeArgument = new LightweightMergedBoundTypeArgument(right.getWrapperTypeIfPrimitive(), VarianceInfo.INVARIANT); final UnboundTypeParameterPreservingSubstitutor unboundSubstitutor = new UnboundTypeParameterPreservingSubstitutor( Collections.singletonMap(left.getTypeParameter(), rightTypeArgument), right.getOwner()) { @Override public LightweightTypeReference doVisitUnboundTypeReference(UnboundTypeReference reference, Set<JvmTypeParameter> visiting) {
@Override protected void doVisitUnboundTypeReference(UnboundTypeReference reference, UnboundTypeReference declaration) { if (declaration.internalIsResolved() || getOwner().isResolved(declaration.getHandle())) { declaration.tryResolve(); outerVisit(declaration, reference, declaration, getExpectedVariance(), getActualVariance()); } else { if (getParametersToProcess().contains(declaration.getTypeParameter()) && VarianceInfo.OUT == getActualVariance() && VarianceInfo.OUT == getExpectedVariance()) { if (getDefaultSource() == BoundTypeArgumentSource.EXPECTATION) { List<LightweightBoundTypeArgument> hints = reference.getAllHints(); for(int i = 0; i < hints.size(); i++) { if (hints.get(i).getSource() == BoundTypeArgumentSource.INFERRED) { return; } } } } acceptHint(declaration, reference); } }
@Override protected void addHint(UnboundTypeReference typeParameter, LightweightTypeReference reference) { LightweightTypeReference wrapped = reference.getWrapperTypeIfPrimitive(); typeParameter.acceptHint(wrapped, BoundTypeArgumentSource.RESOLVED, getOrigin(), getExpectedVariance(), getActualVariance()); LightweightTypeReference typeParameterReference = reference.getOwner().newParameterizedTypeReference(typeParameter.getTypeParameter()); if (validParameterTypes && !typeParameterReference.getRawTypeReference().isAssignableFrom(reference)) { validParameterTypes = false; } } }.processPairedReferences(operationParameterType, closureParameterType);
@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 void doVisitTypeReference(LightweightTypeReference reference, UnboundTypeReference declaration) { if (declaration.internalIsResolved() || getOwner().isResolved(declaration.getHandle())) { declaration.tryResolve(); outerVisit(declaration, reference, declaration, getExpectedVariance(), getActualVariance()); } else { processTypeParameter(declaration.getTypeParameter(), reference); } }
if (resolvedTo == null) { List<JvmTypeParameter> typeParameters = basicGetDeclardTypeParameters(); if (typeParameters != null && typeParameters.contains(unbound.getTypeParameter())) { unbound.tryResolve(); if (!unbound.internalIsResolved()) { unbound.acceptHint(unbound.getOwner().newParameterizedTypeReference(unbound.getTypeParameter()), BoundTypeArgumentSource.RESOLVED, unbound, VarianceInfo.INVARIANT, VarianceInfo.INVARIANT);
@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); } }
protected LightweightTypeReference getStricterConstraint(final UnboundTypeReference typeParameter, LightweightTypeReference hint) { final JvmTypeParameter parameter = typeParameter.getTypeParameter(); List<JvmTypeConstraint> constraints = parameter.getConstraints(); for(JvmTypeConstraint constraint: constraints) { JvmTypeReference constraintReference = constraint.getTypeReference(); if (constraintReference != null) { final boolean[] recursive = new boolean[] { false }; LightweightTypeReferenceFactory factory = new LightweightTypeReferenceFactory(hint.getOwner()) { @Override public LightweightTypeReference doVisitParameterizedTypeReference(JvmParameterizedTypeReference reference) { JvmType type = reference.getType(); if (type == parameter) {// recursively bound recursive[0] = true; } return super.doVisitParameterizedTypeReference(reference); } }; LightweightTypeReference lightweightReference = factory.toLightweightReference(constraintReference); if (!recursive[0]) { if (hint.isAssignableFrom(lightweightReference)) { hint = lightweightReference; } else if (hint.isResolved() && !lightweightReference.getRawTypeReference().isAssignableFrom(hint, TypeConformanceComputationArgument.RAW)) { return null; } } } } return hint; }
protected boolean isExpectedType(LightweightTypeReference expectation, Class<?> clazz) { if (expectation != null) { if (expectation.isResolved() && isSubtypeButNotSynonym(expectation, clazz)) { return true; } if (expectation instanceof UnboundTypeReference) { if (expectation.getOwner().newParameterizedTypeReference(((UnboundTypeReference) expectation).getTypeParameter()).isSubtypeOf(clazz)) { return true; } List<LightweightBoundTypeArgument> hints = ((UnboundTypeReference) expectation).getAllHints(); for(LightweightBoundTypeArgument hint: hints) { LightweightTypeReference hintReference = hint.getTypeReference(); if (hintReference != null && isSubtypeButNotSynonym(hintReference, clazz)) { return true; } } } else if (expectation instanceof ParameterizedTypeReference) { return isSubtypeButNotSynonym(expectation, clazz); } } return false; }
@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; } }
boolean othersSeen = false; boolean declarationMatches = getExpectedVariance() != VarianceInfo.OUT; if (reference.getTypeParameter() != declaration.getType()) { List<LightweightBoundTypeArgument> hints = reference.getAllHints(); for(int i = 0; i < hints.size(); i++) { if (getOwner().getDeclaredTypeParameters().contains(reference.getTypeParameter())) { reference.acceptHint(declaration, BoundTypeArgumentSource.RESOLVED, this, VarianceInfo.INVARIANT, VarianceInfo.INVARIANT); return;