@Override public String getDependencyName(GraphUtils.Node<ListBuffer<Type>> to, GraphUtils.DependencyKind dk) { if (dk == DependencyKind.STUCK) return ""; else { StringBuilder buf = new StringBuilder(); String sep = ""; for (Type from : data) { UndetVar uv = (UndetVar)inferenceContext.asFree(from); for (Type bound : uv.getBounds(InferenceBound.values())) { if (bound.containsAny(List.from(to.data))) { buf.append(sep); buf.append(bound); sep = ","; } } } return buf.toString(); } }
@SuppressWarnings("fallthrough") void checkReferenceCompatible(JCMemberReference tree, Type descriptor, Type refType, CheckContext checkContext, boolean speculativeAttr) { Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType()); List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes()); if (chk.unhandled(refType.getThrownTypes(), thrownTypes).nonEmpty()) { log.error(tree, "incompatible.thrown.types.in.mref", refType.getThrownTypes());
@Override public void visitReference(JCMemberReference tree) { if (types.isFunctionalInterface(t.tsym) && types.isFunctionalInterface(s.tsym)) { Type desc_t = types.findDescriptorType(t); Type desc_s = types.findDescriptorType(s); if (types.isSameTypes(desc_t.getParameterTypes(), inferenceContext().asFree(desc_s.getParameterTypes()))) { if (types.asSuper(t, s.tsym) != null || types.asSuper(s, t.tsym) != null) { result &= MostSpecificCheckContext.super.compatible(t, s, warn); } else if (!desc_s.getReturnType().hasTag(VOID)) { //perform structural comparison Type ret_t = desc_t.getReturnType(); Type ret_s = desc_s.getReturnType(); result &= ((tree.refPolyKind == PolyKind.STANDALONE) ? standaloneMostSpecific(ret_t, ret_s, tree.sym.type.getReturnType(), warn) : polyMostSpecific(ret_t, ret_s, warn)); } else { return; } } } else { result &= false; } }
public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { Infer infer = inferenceContext.infer(); for (Type b : uv.getBounds(InferenceBound.EQ)) { if (inferenceContext.inferenceVars().contains(b)) { UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); if (uv2.isCaptured()) continue; //alpha == beta //0. set beta == alpha addBound(InferenceBound.EQ, uv2, inferenceContext.asInstType(uv.qtype), infer); //1. copy all alpha's bounds to beta's for (InferenceBound ib : InferenceBound.values()) { for (Type b2 : uv.getBounds(ib)) { if (b2 != uv2) { addBound(ib, uv2, inferenceContext.asInstType(b2), infer); } } } //2. copy all beta's bounds to alpha's for (InferenceBound ib : InferenceBound.values()) { for (Type b2 : uv2.getBounds(ib)) { if (b2 != uv) { addBound(ib, uv, inferenceContext.asInstType(b2), infer); } } } } } } };
@Override public void visitLambda(JCLambda tree) { if (types.isFunctionalInterface(t.tsym) && types.isFunctionalInterface(s.tsym)) { Type desc_t = types.findDescriptorType(t); Type desc_s = types.findDescriptorType(s); if (types.isSameTypes(desc_t.getParameterTypes(), inferenceContext().asFree(desc_s.getParameterTypes()))) { if (types.asSuper(t, s.tsym) != null || types.asSuper(s, t.tsym) != null) { result &= MostSpecificCheckContext.super.compatible(t, s, warn); } else if (!desc_s.getReturnType().hasTag(VOID)) { //perform structural comparison Type ret_t = desc_t.getReturnType(); Type ret_s = desc_s.getReturnType(); scanLambdaBody(tree, ret_t, ret_s); } else { return; } } } else { result &= false; } } //where
public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { Infer infer = inferenceContext.infer(); uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), infer.types); infer.checkCompatibleUpperBounds(uv, inferenceContext); if (uv.inst != null) { Type inst = uv.inst; for (Type u : uv.getBounds(InferenceBound.UPPER)) { if (!isSubtype(inst, inferenceContext.asFree(u), warn, infer)) { infer.reportBoundError(uv, BoundErrorKind.UPPER); } } for (Type l : uv.getBounds(InferenceBound.LOWER)) { if (!isSubtype(inferenceContext.asFree(l), inst, warn, infer)) { infer.reportBoundError(uv, BoundErrorKind.LOWER); } } for (Type e : uv.getBounds(InferenceBound.EQ)) { if (!isSameType(inst, inferenceContext.asFree(e), infer)) { infer.reportBoundError(uv, BoundErrorKind.EQ); } } } } @Override
/** * Lambda compatibility. Check that given return types, thrown types, parameter types * are compatible with the expected functional interface descriptor. This means that: * (i) parameter types must be identical to those of the target descriptor; (ii) return * types must be compatible with the return type of the expected descriptor. */ private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext) { Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType()); //return values have already been checked - but if lambda has no return //values, we must ensure that void/value compatibility is correct; //this amounts at checking that, if a lambda body can complete normally, //the descriptor's return type must be void if (tree.getBodyKind() == JCLambda.BodyKind.STATEMENT && tree.canCompleteNormally && !returnType.hasTag(VOID) && returnType != Type.recoveryType) { checkContext.report(tree, diags.fragment("incompatible.ret.type.in.lambda", diags.fragment("missing.ret.val", returnType))); } List<Type> argTypes = checkContext.inferenceContext().asFree(descriptor.getParameterTypes()); if (!types.isSameTypes(argTypes, TreeInfo.types(tree.params))) { checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda")); } }
public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { Infer infer = inferenceContext.infer(); for (Type b : uv.getBounds(InferenceBound.LOWER)) { if (inferenceContext.inferenceVars().contains(b)) { UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); if (uv2.isCaptured()) continue; //alpha :> beta //0. set beta <: alpha addBound(InferenceBound.UPPER, uv2, inferenceContext.asInstType(uv.qtype), infer); //1. copy alpha's upper to beta's for (Type u : uv.getBounds(InferenceBound.UPPER)) { addBound(InferenceBound.UPPER, uv2, inferenceContext.asInstType(u), infer); } //2. copy beta's lower to alpha's for (Type l : uv2.getBounds(InferenceBound.LOWER)) { addBound(InferenceBound.LOWER, uv, inferenceContext.asInstType(l), infer); } } } } },
public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { Infer infer = inferenceContext.infer(); for (Type b : uv.getBounds(InferenceBound.UPPER)) { if (inferenceContext.inferenceVars().contains(b)) { UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); if (uv2.isCaptured()) continue; //alpha <: beta //0. set beta :> alpha addBound(InferenceBound.LOWER, uv2, inferenceContext.asInstType(uv.qtype), infer); //1. copy alpha's lower to beta's for (Type l : uv.getBounds(InferenceBound.LOWER)) { addBound(InferenceBound.LOWER, uv2, inferenceContext.asInstType(l), infer); } //2. copy beta's upper to alpha's for (Type u : uv2.getBounds(InferenceBound.UPPER)) { addBound(InferenceBound.UPPER, uv, inferenceContext.asInstType(u), infer); } } } } },
public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { Infer infer = inferenceContext.infer(); for (Type e : uv.getBounds(InferenceBound.EQ)) { if (e.containsAny(inferenceContext.inferenceVars())) continue; for (Type u : uv.getBounds(InferenceBound.UPPER)) { if (!isSubtype(e, inferenceContext.asFree(u), warn, infer)) { infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER); } } for (Type l : uv.getBounds(InferenceBound.LOWER)) { if (!isSubtype(inferenceContext.asFree(l), e, warn, infer)) { infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER); } } } } },
private boolean solveBasic(List<Type> varsToSolve, EnumSet<InferenceStep> steps) { boolean changed = false; for (Type t : varsToSolve.intersect(restvars())) { UndetVar uv = (UndetVar)asFree(t); for (InferenceStep step : steps) { if (step.accepts(uv, this)) { uv.inst = step.solve(uv, this); changed = true; break; } } } return changed; }
public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { Infer infer = inferenceContext.infer(); for (Type b1 : uv.getBounds(InferenceBound.EQ)) { for (Type b2 : uv.getBounds(InferenceBound.LOWER)) { isSubtype(inferenceContext.asFree(b2), inferenceContext.asFree(b1), warn, infer); } } } },
public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { Infer infer = inferenceContext.infer(); for (Type b1 : uv.getBounds(InferenceBound.UPPER)) { for (Type b2 : uv.getBounds(InferenceBound.LOWER)) { isSubtype(inferenceContext.asFree(b2), inferenceContext.asFree(b1), warn , infer); } } } },
final List<Type> asFree(List<Type> ts) { ListBuffer<Type> buf = new ListBuffer<>(); for (Type t : ts) { buf.append(asFree(t)); } return buf.toList(); }
public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { Infer infer = inferenceContext.infer(); for (Type b1 : uv.getBounds(InferenceBound.EQ)) { for (Type b2 : uv.getBounds(InferenceBound.EQ)) { if (b1 != b2) { isSameType(inferenceContext.asFree(b2), inferenceContext.asFree(b1), infer); } } } } },
public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { Infer infer = inferenceContext.infer(); for (Type b1 : uv.getBounds(InferenceBound.UPPER)) { for (Type b2 : uv.getBounds(InferenceBound.EQ)) { isSubtype(inferenceContext.asFree(b2), inferenceContext.asFree(b1), warn, infer); } } } },
@Override ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { if (TreeInfo.isStaticSelector(referenceTree.expr, names) && argtypes.nonEmpty() && (argtypes.head.hasTag(NONE) || types.isSubtypeUnchecked(inferenceContext.asFree(argtypes.head), site))) { return new UnboundMethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase); } else { return super.unboundLookup(inferenceContext); } }
@Override public boolean compatible(Type found, Type req, Warner warn) { //return type must be compatible in both current context and assignment context return chk.basicHandler.compatible(found, inferenceContext().asFree(req), warn); }
@Override public boolean compatible(Type found, Type req, Warner warn) { found = pendingInferenceContext.asFree(found); req = infer.returnConstraintTarget(found, req); return super.compatible(found, req, warn); }