/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/** Helper class for type parameter inference, used by the attribution phase.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class Infer {
/** A value for prototypes that admit any type, including polymorphic ones. */
return instance;
}
new NoInstanceException(true, diags);
new NoInstanceException(false, diags);
}
super(diags);
}
}
super(diags);
this.isAmbiguous = isAmbiguous;
}
}
super(diags);
}
}
/***************************************************************************
* Auxiliary type values and classes
***************************************************************************/
/** A mapping that turns type variables into undetermined type variables.
*/
else return t.map(this);
}
};
/** A mapping that returns its type argument with every UndetVar replaced
* by its `inst' field. Throws a NoInstanceException
* if this not possible because an `inst' field is null.
* Note: mutually referring undertvars will be left uninstantiated
* (that is, they will be replaced by the underlying type-variable).
*/
switch (t.tag) {
case UNKNOWN:
.setMessage("undetermined.type");
case UNDETVAR:
.setMessage("type.variable.has.undetermined.type",
return isConstraintCyclic(that) ?
default:
return t.map(this);
}
}
if (visit(t)) return true;
}
return false;
}
return false;
}
if (t.isCompound()) {
} else {
return visit(t.getTypeArguments());
}
}
}
return true;
} else {
}
}
};
}
};
/***************************************************************************
* Mini/Maximization of UndetVars
***************************************************************************/
/** Instantiate undetermined type variable to its minimal upper bound.
* Throw a NoInstanceException if this not possible.
*/
else
}
.setMessage("no.unique.maximal.instance.exists",
}
//where
t = t.baseType();
return false;
}
}
}
} else {
return false;
}
}
return true;
}
return !t.isErroneous();
}
};
}
};
/** Instantiate undetermined type variable to the lub of all its lower bounds.
* Throw a NoInstanceException if this not possible.
*/
else {
}
.setMessage("no.unique.minimal.instance.exists",
// VGJ: sort of inlined maximizeInst() below. Adding
// bounds can cause lobounds that are above hibounds.
else
hb.isErroneous())
.setMessage("incompatible.upper.bounds",
}
}
/***************************************************************************
* Exported Methods
***************************************************************************/
/** Try to instantiate expression type `that' to given type `to'.
* If a maximal instantiation exists which makes this type
* a subtype of type `to', return the instantiated type.
* If no instantiation exists, or if several incomparable
* best instantiations exist throw a NoInstanceException.
*/
}
}
}
.setMessage("infer.no.conforming.instance.exists",
}
// System.out.println(" = " + qtype1.map(getInstFun));//DEBUG
// check bounds
//replace uninferred type-vars
}
}
//where
//step 1 - create synthetic captured vars
}
//step 2 - replace synthetic vars in their bounds
}
}
/** Instantiate method type `mt' by finding instantiations of
* `tvars' so that method can be applied to `argtypes'.
*/
final boolean allowBoxing,
final boolean useVarargs,
//-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
//need to capture exactly once - otherwise subsequent
//applicability checks might fail
// instantiate all polymorphic argument types and
// set up lower bounds constraints for undetvars
if (varargsFormal == null &&
.setMessage("infer.arg.length.mismatch");
}
boolean works = allowBoxing
if (!works) {
.setMessage("infer.no.conforming.assignment.exists",
}
}
// for varargs arguments as well
if (useVarargs) {
if (!works) {
.setMessage("infer.no.conforming.assignment.exists",
}
}
}
// minimize as yet undetermined type variables
/** Type variables instantiated to bottom */
/** Undet vars instantiated to bottom */
/** Instantiated types or TypeVars if under-constrained */
/** Instantiated types or UndetVars if under-constrained */
} else {
}
}
// if there are uninstantiated variables,
// quantify result type with them
switch (ck) {
}
}
}
}
// check that actuals conform to inferred formals
// check that inferred bounds conform to their bounds
if (useVarargs) {
}
}};
}
else {
// check that actuals conform to inferred formals
// return instantiated version of method type
return mt;
}
}
//where
/**
* A delegated type representing a partially uninferred method type.
* The return type of a partially uninferred method type is a ForAll
* type - when the return type is instantiated (see Infer.instantiateExpr)
* the underlying method type is also updated.
*/
}
return qtype.asMethodType();
}
}
void instantiateReturnType(Type restype, List<Type> inferred, Types types) throws NoInstanceException {
//update method type with newly inferred type-arguments
}
}
return newRestype;
}
}
}
}
try {
}
// inferred method is not applicable
}
}
/** Try to instantiate argument type `that' to given type `to'.
* If this fails, try to insantiate `that' to `to' where
* every occurrence of a type variable in `tvars' is replaced
* by an unknown type.
*/
try {
} catch (NoInstanceException ex) {
}
}
/** check that type parameters are within their bounds.
*/
throws InvalidInstanceException {
throw invalidInstanceException
.setMessage("inferred.do.not.conform.to.bounds",
}
}
/**
* Compute a synthetic method type corresponding to the requested polymorphic
* method signature. The target return type is computed from the immediately
* enclosing scope surrounding the polymorphic-signature call.
*/
//The return type for a polymorphic signature call is computed from
//the enclosing tree E, as follows: if E is a cast, then use the
//target type of the cast expression as a return type; if E is an
//expression statement, the return type is 'void' - otherwise the
//return type is simply 'Object'. A correctness check ensures that
//env.next refers to the lexically enclosing environment in which
//the polymorphic signature call environment is nested.
break;
break;
default:
}
return mtype;
}
//where
// nulls type as the marker type Null (which has no instances)
// infer as java.lang.Void for now
return t;
}
};
}