private ArrayBinding findMostSpecificSuperArray( TypeBinding firstBound, TypeBinding[] otherUpperBounds, TypeBinding theType) { int numArrayBounds = 0; ArrayBinding result = null; if (firstBound != null && firstBound.isArrayType()) { result = (ArrayBinding) firstBound; numArrayBounds++; } for (int i = 0; i < otherUpperBounds.length; i++) { if (otherUpperBounds[i].isArrayType()) { result = (ArrayBinding) otherUpperBounds[i]; numArrayBounds++; } } if (numArrayBounds == 0) return null; if (numArrayBounds == 1) return result; InferenceContext18.missingImplementation( "Extracting array from intersection is not defined"); //$NON-NLS-1$ return null; }
// return: ReductionResult or ConstraintFormula[] public Object reduce(InferenceContext18 inferenceContext) { switch (this.relation) { case COMPATIBLE: // 18.2.2: if (this.left.isProperType(true) && this.right.isProperType(true)) { return this.left.isCompatibleWith(this.right, inferenceContext.scope) || this.left.isBoxingCompatibleWith(this.right, inferenceContext.scope) ? TRUE : FALSE; } if (this.left.isPrimitiveType()) { TypeBinding sPrime = inferenceContext.environment.computeBoxingType(this.left); return ConstraintTypeFormula.create(sPrime, this.right, COMPATIBLE, this.isSoft); } if (this.right.isPrimitiveType()) { TypeBinding tPrime = inferenceContext.environment.computeBoxingType(this.right); return ConstraintTypeFormula.create(this.left, tPrime, SAME, this.isSoft); } switch (this.right.kind()) { case Binding.ARRAY_TYPE: if (this.right.leafComponentType().kind() != Binding.PARAMETERIZED_TYPE) break; // $FALL-THROUGH$ array of parameterized is handled below: case Binding.PARAMETERIZED_TYPE: { // this.right = G<T1,T2,...> or G<T1,T2,...>[]k TypeBinding gs = this.left.findSuperTypeOriginatingFrom( this.right); // G<S1,S2,...> or G<S1,S2,...>[]k if (gs != null && gs.leafComponentType().isRawType()) { inferenceContext.recordUncheckedConversion(this); return TRUE; } break; } } return ConstraintTypeFormula.create(this.left, this.right, SUBTYPE, this.isSoft); case SUBTYPE: // 18.2.3: return reduceSubType(inferenceContext.scope, this.left, this.right); case SUPERTYPE: // 18.2.3: return reduceSubType(inferenceContext.scope, this.right, this.left); case SAME: if (inferenceContext.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) if (!checkIVFreeTVmatch(this.left, this.right)) checkIVFreeTVmatch(this.right, this.left); // 18.2.4: return reduceTypeEquality(inferenceContext.object); case TYPE_ARGUMENT_CONTAINED: // 18.2.3: if (this.right.kind() != Binding.WILDCARD_TYPE) { // "If T is a type" ... all alternatives require "wildcard" if (this.left.kind() != Binding.WILDCARD_TYPE) { return ConstraintTypeFormula.create(this.left, this.right, SAME, this.isSoft); } else { return FALSE; } } else { WildcardBinding t = (WildcardBinding) this.right; if (t.boundKind == Wildcard.UNBOUND) return TRUE; if (t.boundKind == Wildcard.EXTENDS) { if (this.left.kind() != Binding.WILDCARD_TYPE) { return ConstraintTypeFormula.create(this.left, t.bound, SUBTYPE, this.isSoft); } else { WildcardBinding s = (WildcardBinding) this.left; switch (s.boundKind) { case Wildcard.UNBOUND: return ConstraintTypeFormula.create( inferenceContext.object, t.bound, SUBTYPE, this.isSoft); case Wildcard.EXTENDS: return ConstraintTypeFormula.create(s.bound, t.bound, SUBTYPE, this.isSoft); case Wildcard.SUPER: return ConstraintTypeFormula.create( inferenceContext.object, t.bound, SAME, this.isSoft); default: throw new IllegalArgumentException( "Unexpected boundKind " + s.boundKind); // $NON-NLS-1$ } } } else { // SUPER if (this.left.kind() != Binding.WILDCARD_TYPE) { return ConstraintTypeFormula.create(t.bound, this.left, SUBTYPE, this.isSoft); } else { WildcardBinding s = (WildcardBinding) this.left; if (s.boundKind == Wildcard.SUPER) { return ConstraintTypeFormula.create(t.bound, s.bound, SUBTYPE, this.isSoft); } else { return FALSE; } } } } default: throw new IllegalStateException("Unexpected relation kind " + this.relation); // $NON-NLS-1$ } }