use of com.sun.tools.javac.code.Type.MethodType in project ceylon-compiler by ceylon.
the class Attr method checkMethod.
/**
* Check that method arguments conform to its instantation.
*/
public Type checkMethod(Type site, Symbol sym, Env<AttrContext> env, final List<JCExpression> argtrees, List<Type> argtypes, List<Type> typeargtypes, boolean useVarargs) {
// an unchecked warning if its argument types change under erasure.
if (allowGenerics && (sym.flags() & STATIC) == 0 && (site.tag == CLASS || site.tag == TYPEVAR)) {
Type s = types.asOuterSuper(site, sym.owner);
if (s != null && s.isRaw() && !types.isSameTypes(sym.type.getParameterTypes(), sym.erasure(types).getParameterTypes())) {
chk.warnUnchecked(env.tree.pos(), "unchecked.call.mbr.of.raw.type", sym, s);
}
}
// Compute the identifier's instantiated type.
// For methods, we need to compute the instance type by
// Resolve.instantiate from the symbol's type as well as
// any type arguments and value arguments.
noteWarner.clear();
Type owntype;
// Added by Ceylon
if (sym.kind == MTH && ((MethodSymbol) sym).isDynamic()) {
owntype = sym.type;
} else {
owntype = rs.instantiate(env, site, sym, argtypes, typeargtypes, true, useVarargs, noteWarner);
}
boolean warned = noteWarner.hasNonSilentLint(LintCategory.UNCHECKED);
// found the identifier in the first place.
if (owntype == null) {
if (!pt.isErroneous())
log.error(env.tree.pos(), "internal.error.cant.instantiate", sym, site, Type.toString(pt.getParameterTypes()));
owntype = types.createErrorType(site);
} else {
// System.out.println("call : " + env.tree);
// System.out.println("method : " + owntype);
// System.out.println("actuals: " + argtypes);
List<Type> formals = owntype.getParameterTypes();
Type last = useVarargs ? formals.last() : null;
if (sym.name == names.init && sym.owner == syms.enumSym)
formals = formals.tail.tail;
List<JCExpression> args = argtrees;
while (formals.head != last) {
JCTree arg = args.head;
Warner warn = chk.convertWarner(arg.pos(), arg.type, formals.head);
assertConvertible(arg, arg.type, formals.head, warn);
warned |= warn.hasNonSilentLint(LintCategory.UNCHECKED);
args = args.tail;
formals = formals.tail;
}
if (useVarargs) {
Type varArg = types.elemtype(last);
while (args.tail != null) {
JCTree arg = args.head;
Warner warn = chk.convertWarner(arg.pos(), arg.type, varArg);
assertConvertible(arg, arg.type, varArg, warn);
warned |= warn.hasNonSilentLint(LintCategory.UNCHECKED);
args = args.tail;
}
} else if ((sym.flags() & VARARGS) != 0 && allowVarargs) {
// non-varargs call to varargs method
Type varParam = owntype.getParameterTypes().last();
Type lastArg = argtypes.last();
if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) && !types.isSameType(types.erasure(varParam), types.erasure(lastArg)))
log.warning(argtrees.last().pos(), "inexact.non-varargs.call", types.elemtype(varParam), varParam);
}
if (warned && sym.type.tag == FORALL) {
chk.warnUnchecked(env.tree.pos(), "unchecked.meth.invocation.applied", kindName(sym), sym.name, rs.methodArguments(sym.type.getParameterTypes()), rs.methodArguments(argtypes), kindName(sym.location()), sym.location());
// Don't erase the return type of the instantiated method type
// for Ceylon #1095
owntype = new MethodType(owntype.getParameterTypes(), sourceLanguage.isCeylon() && typeargtypes != null && !typeargtypes.isEmpty() ? owntype.getReturnType() : types.erasure(owntype.getReturnType()), types.erasure(owntype.getThrownTypes()), syms.methodClass);
}
if (useVarargs) {
JCTree tree = env.tree;
Type argtype = owntype.getParameterTypes().last();
if (owntype.getReturnType().tag != FORALL || warned) {
chk.checkVararg(env.tree.pos(), owntype.getParameterTypes(), sym);
}
Type elemtype = types.elemtype(argtype);
switch(tree.getTag()) {
case JCTree.APPLY:
((JCMethodInvocation) tree).varargsElement = elemtype;
break;
case JCTree.NEWCLASS:
((JCNewClass) tree).varargsElement = elemtype;
break;
default:
throw new AssertionError("" + tree);
}
}
}
return owntype;
}
use of com.sun.tools.javac.code.Type.MethodType in project ceylon-compiler by ceylon.
the class Attr method resolveIndyCall.
// Added by Ceylon
private Symbol resolveIndyCall(JCTree tree, JCExpression indyReturnTypeExpression, List<JCExpression> indyParameterTypeExpressions, Name indyName, JCExpression bsmType, Name bsmName, List<Object> bsmStatic, List<Type> parameterTypes) {
// build the list of static bsm arguments
List<Type> bsm_staticArgs = List.of(syms.methodHandleLookupType, syms.stringType, syms.methodTypeType).appendList(bsmStaticArgToTypes(bsmStatic));
// find the type of the bootstrap method class
Type bsmSite = attribTree(bsmType, env, TYP, Infer.anyPoly);
// find the bsm method
Symbol bsm = rs.resolveInternalMethod(tree.pos(), env, bsmSite, bsmName, bsm_staticArgs, List.<Type>nil());
if (!bsm.isStatic())
log.error(tree.pos(), "ceylon", "Bootstrap method must be static: " + bsmName.toString());
// find the type of the indy call
Type indyReturnType = attribTree(indyReturnTypeExpression, env, TYP, Infer.anyPoly);
ListBuffer<Type> indyParameterTypes = new ListBuffer<Type>();
int c = 0;
List<Type> givenParameterTypes = parameterTypes;
for (JCExpression expectedParamTypeExpr : indyParameterTypeExpressions) {
// also check that the parameter types we are passing to the method are compatible with the declared type
Type givenParameterType = givenParameterTypes.head;
if (givenParameterType == null) {
log.error(tree.pos(), "ceylon", "Indy declared method expects more parameters than given. Expecting " + indyParameterTypeExpressions.size() + ", but given " + c);
return syms.errSymbol;
}
Type paramType = attribTree(expectedParamTypeExpr, env, TYP, Infer.anyPoly);
if (!types.isAssignable(givenParameterType, paramType)) {
log.error(tree.pos(), "ceylon", "Indy given method parameter " + c + " not compatible with expected parameter type: " + paramType + ", but given " + givenParameterType);
return syms.errSymbol;
}
indyParameterTypes.append(paramType);
c++;
givenParameterTypes = givenParameterTypes.tail;
}
if (!givenParameterTypes.isEmpty()) {
log.error(tree.pos(), "ceylon", "Indy declared method expects less parameters than given. Expecting " + indyParameterTypeExpressions.size() + ", but given " + parameterTypes.size());
return syms.errSymbol;
}
MethodType indyType = new MethodType(indyParameterTypes.toList(), indyReturnType, List.<Type>nil(), syms.methodClass);
// make an indy symbol for it
DynamicMethodSymbol dynSym = new DynamicMethodSymbol(indyName, syms.noSymbol, bsm.isStatic() ? ClassFile.REF_invokeStatic : ClassFile.REF_invokeVirtual, (MethodSymbol) bsm, indyType, bsmStatic.toArray());
return dynSym;
}
Aggregations