package com.sun.tools.javac.comp;
import com.sun.tools.javac.code.RPL;
import com.sun.tools.javac.code.RPLElement;
import com.sun.tools.javac.code.RPLs;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.code.RPLElement.RPLParameterElement;
import com.sun.tools.javac.code.RPLElement.UndetRPLParameterElement;
import com.sun.tools.javac.code.Symbol.RegionParameterSymbol;
import com.sun.tools.javac.code.Type.MethodType;
import com.sun.tools.javac.code.Type.UndetVar;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Warner;
public class InferRPL {
protected static final Context.Key<InferRPL> inferRPLKey =
new Context.Key<InferRPL>();
RPLs rpls;
Types types;
Symtab syms;
public static InferRPL instance(Context context) {
InferRPL instance = context.get(inferRPLKey);
if (instance == null)
instance = new InferRPL(context);
return instance;
}
protected InferRPL(Context context) {
context.put(inferRPLKey, this);
rpls = RPLs.instance(context);
types = Types.instance(context);
syms = Symtab.instance(context);
}
public Type instantiateMethod(List<RPL> rvars, List<Type> tvars,
MethodType mt, List<Type> actualtypes, boolean allowBoxing, Warner warn) {
ListBuffer<RPL> buf = ListBuffer.lb();
for (RPL rvar : rvars) {
if (rvar.size() == 1 && rvar.elts.head instanceof RPLParameterElement)
buf.append(new RPL(new
UndetRPLParameterElement(((RPLParameterElement) rvar.elts.head).sym)));
else
buf.append(rvar);
}
List<RPL> undetvars = buf.toList();
List<Type> formaltypes = types.substRPL(mt.argtypes, rvars, undetvars);
for (Type t : tvars) {
formaltypes = types.subst(formaltypes, List.of(t), List.<Type>of(new UndetVar(t)));
}
// Note: This step fills in the bounds on the undet variables. See RPL.isIncludedIn
// for details. This is kind of a hack, but it makes for a very lean coding of the
// algorithm, i.e., no extra machinery is required to fill in the bounds.
if (!types.isSubtypesUnchecked(actualtypes, formaltypes, allowBoxing, warn)) {
return null;
}
buf = ListBuffer.lb();
for (RPL undetvar : undetvars) {
if (undetvar.size() == 1 &&
undetvar.elts.head instanceof UndetRPLParameterElement) {
UndetRPLParameterElement element = (UndetRPLParameterElement) undetvar.elts.head;
if (element.includedIn == null)
element.includedIn =
new RPL(List.<RPLElement>of(RPLElement.ROOT_ELEMENT, RPLElement.STAR));
buf.append(element.includedIn);
} else {
buf.append(undetvar);
}
}
//System.err.println("mt now ="+mt);
//System.err.println("rvars as params="+rpls.toParams(rvars));
//System.err.println("actuals="+buf.toList());
mt = (MethodType) types.substRPL(mt, rvars, buf.toList());
mt.regionActuals = buf.toList();
return mt;
}
}