protected void addIdentifier(LightweightTypeReference type, Set<String> allNames, Set<String> allBoundNames) { if (type instanceof UnboundTypeReference && !type.isResolved()) { allNames.add(((UnboundTypeReference) type).getHandle().toString()); } else { String identifier = type.getJavaIdentifier(); allNames.add(identifier); allBoundNames.add(identifier); } }
protected String getIdentifier(LightweightTypeReference type) { if (type instanceof UnboundTypeReference && !type.isResolved()) return ((UnboundTypeReference) type).getHandle().toString(); return type.getJavaIdentifier(); }
protected UnboundTypeReference createUnboundTypeReference(XExpression expression, JvmTypeParameter type) { UnboundTypeReference result = new UnboundTypeReference(getReferenceOwner(), expression, type) { // the constructor is protected since this guides developers better // therefore we use an anonymous class, here }; acceptUnboundTypeReference(result.getHandle(), result); return result; }
public List<LightweightBoundTypeArgument> getAllHints() { if (internalGetResolvedTo() != null) { throw new IllegalStateException("Cannot query hints for a resolved reference"); } return getOwner().getAllHints(getHandle()); }
@Override protected LightweightTypeReference visitTypeArgument(LightweightTypeReference reference, ConstraintVisitingInfo visiting, boolean lowerBound) { if (reference.getKind() == LightweightTypeReference.KIND_UNBOUND_TYPE_REFERENCE) { if (handle.equals(((UnboundTypeReference) reference).getHandle())) { return doVisitUnboundTypeReference((UnboundTypeReference) reference, visiting); } } return super.visitTypeArgument(reference, visiting, lowerBound); }
protected UnboundTypeReference createCopy(ITypeReferenceOwner owner) { UnboundTypeReference result = new UnboundTypeReference(owner, expression, getTypeParameter(), getHandle()); return result; }
protected void addNonRecursiveHints(LightweightBoundTypeArgument original, UnboundTypeReference reference, Set<Object> seenHandles, List<LightweightBoundTypeArgument> result) { Object otherHandle = reference.getHandle(); if (seenHandles.add(otherHandle)) { if (isResolved(otherHandle)) { result.addAll(getHints(otherHandle)); } else { addNonRecursiveHints(original, getHints(otherHandle), seenHandles, result); } } }
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); }
@Override public void doVisitUnboundTypeReference(UnboundTypeReference reference, ArrayTypeReference declaration) { if (reference.internalIsResolved() || getOwner().isResolved(reference.getHandle())) { reference.tryResolve(); outerVisit(reference, declaration); } else { addHint(reference, declaration); } } }
@Override public void doVisitUnboundTypeReference(UnboundTypeReference reference, ParameterizedTypeReference declaration) { if (reference.internalIsResolved() || getOwner().isResolved(reference.getHandle())) { reference.tryResolve(); outerVisit(reference, declaration); } else { addHint(reference, declaration); } } }
protected void mergeTypesIntoParent(ResolvedTypes parent) { Map<JvmIdentifiableElement, LightweightTypeReference> types = basicGetTypes(); if (!types.isEmpty()) { for(Map.Entry<JvmIdentifiableElement, LightweightTypeReference> entry: types.entrySet()) { LightweightTypeReference value = entry.getValue(); if (value instanceof UnboundTypeReference && super.isResolved(((UnboundTypeReference) value).getHandle())) { parent.setType(entry.getKey(), value.getUpperBoundSubstitute().copyInto(parent.getReferenceOwner())); } else { parent.setType(entry.getKey(), value.copyInto(parent.getReferenceOwner())); } } } }
public void acceptHint(LightweightBoundTypeArgument hint) { if (internalIsResolved()) { throw new IllegalStateException("Cannot add hints to a resolved reference"); } if (hint.getSource() == BoundTypeArgumentSource.EXPLICIT) { LightweightTypeReference reference = hint.getTypeReference(); if (!(reference instanceof ParameterizedTypeReference) && !reference.isArray() && !reference.isUnknown()) { throw new IllegalArgumentException("cannot set " + hint + " as explicit hint"); } if (!getAllHints().isEmpty()) { throw new IllegalStateException("Cannot set explicit hint if other hints are present: " + getAllHints()); } this.resolvedTo = reference; getOwner().acceptHint(getHandle(), new LightweightBoundTypeArgument(resolvedTo, BoundTypeArgumentSource.RESOLVED, this, hint.getDeclaredVariance(), hint.getActualVariance())); return; } getOwner().acceptHint(this.getHandle(), hint); }
protected void resolveAgainstConstraints() { TypeParameterByConstraintSubstitutor unboundSubstitutor = new TypeParameterByConstraintSubstitutor( Collections.<JvmTypeParameter, LightweightMergedBoundTypeArgument>emptyMap(), getOwner(), true); LightweightTypeReference substitute = unboundSubstitutor.substitute(getOwner().newParameterizedTypeReference(typeParameter)); getOwner().acceptHint(getHandle(), new LightweightBoundTypeArgument(substitute, BoundTypeArgumentSource.RESOLVED, this, VarianceInfo.INVARIANT, VarianceInfo.INVARIANT)); resolvedTo = substitute; }
@Override protected void doVisitTypeReference(LightweightTypeReference reference, UnboundTypeReference declaration) { if (declaration.internalIsResolved() || getOwner().isResolved(declaration.getHandle())) { declaration.tryResolve(); outerVisit(declaration, reference, declaration, getExpectedVariance(), getActualVariance()); } else { acceptHint(declaration, reference); } }
@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 protected void doVisitTypeReference(LightweightTypeReference reference, UnboundTypeReference declaration) { if (declaration.internalIsResolved() || getOwner().isResolved(declaration.getHandle())) { declaration.tryResolve(); outerVisit(declaration, reference, declaration, getExpectedVariance(), getActualVariance()); } else if (reference.isValidHint()) { addHint(declaration, reference); } }
@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); } }
protected TypeData prepareMerge(TypeData typeData, ITypeReferenceOwner owner) { LightweightTypeReference typeReference = typeData.getActualType(); if (typeData.isOwnedBy(owner) && !(typeReference instanceof UnboundTypeReference)) return typeData; if (typeReference instanceof UnboundTypeReference && super.isResolved(((UnboundTypeReference) typeReference).getHandle())) { typeReference = typeReference.getUpperBoundSubstitute(); } return new TypeData(typeData.getExpression(), typeData.getExpectation().copyInto(owner), typeReference.copyInto(owner), typeData.getConformanceFlags(), typeData.isReturnType()); }