use of com.sun.tools.javac.code.Type.MethodType in project error-prone by google.
the class Template method infer.
/**
* Returns the inferred method type of the template based on the given actual argument types.
*
* @throws InferException if no instances of the specified type variables would allow the {@code
* actualArgTypes} to match the {@code expectedArgTypes}
*/
private Type infer(Warner warner, Inliner inliner, List<Type> freeTypeVariables, List<Type> expectedArgTypes, Type returnType, List<Type> actualArgTypes) throws InferException {
Symtab symtab = inliner.symtab();
Type methodType = new MethodType(expectedArgTypes, returnType, List.<Type>nil(), symtab.methodClass);
if (!freeTypeVariables.isEmpty()) {
methodType = new ForAll(freeTypeVariables, methodType);
}
Enter enter = inliner.enter();
MethodSymbol methodSymbol = new MethodSymbol(0, inliner.asName("__m__"), methodType, symtab.unknownSymbol);
Type site = symtab.methodClass.type;
Env<AttrContext> env = enter.getTopLevelEnv(TreeMaker.instance(inliner.getContext()).TopLevel(List.<JCTree>nil()));
// Set up the resolution phase:
try {
Field field = AttrContext.class.getDeclaredField("pendingResolutionPhase");
field.setAccessible(true);
field.set(env.info, newMethodResolutionPhase(autoboxing()));
} catch (ReflectiveOperationException e) {
throw new LinkageError(e.getMessage(), e);
}
Object resultInfo;
try {
Class<?> resultInfoClass = Class.forName("com.sun.tools.javac.comp.Attr$ResultInfo");
Constructor<?> resultInfoCtor = resultInfoClass.getDeclaredConstructor(Attr.class, KindSelector.class, Type.class);
resultInfoCtor.setAccessible(true);
resultInfo = resultInfoCtor.newInstance(Attr.instance(inliner.getContext()), KindSelector.PCK, Type.noType);
} catch (ReflectiveOperationException e) {
throw new LinkageError(e.getMessage(), e);
}
// Type inference sometimes produces diagnostics, so we need to catch them to avoid interfering
// with the enclosing compilation.
Log.DeferredDiagnosticHandler handler = new Log.DeferredDiagnosticHandler(Log.instance(inliner.getContext()));
try {
MethodType result = callCheckMethod(warner, inliner, resultInfo, actualArgTypes, methodSymbol, site, env);
if (!handler.getDiagnostics().isEmpty()) {
throw new InferException(handler.getDiagnostics());
}
return result;
} finally {
Log.instance(inliner.getContext()).popDiagnosticHandler(handler);
}
}
use of com.sun.tools.javac.code.Type.MethodType in project ceylon-compiler by ceylon.
the class Attr method visitApply.
/**
* Visitor method for method invocations.
* NOTE: The method part of an application will have in its type field
* the return type of the method, not the method's type itself!
*/
public void visitApply(JCMethodInvocation tree) {
// The local environment of a method application is
// a new environment nested in the current one.
Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
// The types of the actual method arguments.
List<Type> argtypes;
// The types of the actual method type arguments.
List<Type> typeargtypes = null;
Name methName = TreeInfo.name(tree.meth);
boolean isConstructorCall = methName == names._this || methName == names._super;
if (isConstructorCall) {
// Check that this is the first statement in a constructor.
if (checkFirstConstructorStat(tree, env)) {
// Record the fact
// that this is a constructor call (using isSelfCall).
localEnv.info.isSelfCall = true;
// Attribute arguments, yielding list of argument types.
argtypes = attribArgs(tree.args, localEnv);
typeargtypes = attribTypes(tree.typeargs, localEnv);
// Variable `site' points to the class in which the called
// constructor is defined.
Type site = env.enclClass.sym.type;
if (methName == names._super) {
if (site == syms.objectType) {
log.error(tree.meth.pos(), "no.superclass", site);
site = types.createErrorType(syms.objectType);
} else {
site = types.supertype(site);
}
}
if (site.tag == CLASS) {
Type encl = site.getEnclosingType();
while (encl != null && encl.tag == TYPEVAR) encl = encl.getUpperBound();
if (encl.tag == CLASS) {
if (tree.meth.getTag() == JCTree.SELECT) {
JCTree qualifier = ((JCFieldAccess) tree.meth).selected;
// We are seeing a prefixed call, of the form
// <expr>.super(...).
// Check that the prefix expression conforms
// to the outer instance type of the class.
chk.checkRefType(qualifier.pos(), attribExpr(qualifier, localEnv, encl));
} else if (methName == names._super) {
// qualifier omitted; check for existence
// of an appropriate implicit qualifier.
rs.resolveImplicitThis(tree.meth.pos(), localEnv, site, true);
}
} else if (tree.meth.getTag() == JCTree.SELECT) {
log.error(tree.meth.pos(), "illegal.qual.not.icls", site.tsym);
}
// prefix the implicit String and int parameters
if (site.tsym == syms.enumSym && allowEnums)
argtypes = argtypes.prepend(syms.intType).prepend(syms.stringType);
// Resolve the called constructor under the assumption
// that we are referring to a superclass instance of the
// current instance (JLS ???).
boolean selectSuperPrev = localEnv.info.selectSuper;
localEnv.info.selectSuper = true;
localEnv.info.varArgs = false;
Symbol sym = rs.resolveConstructor(tree.meth.pos(), localEnv, site, argtypes, typeargtypes);
localEnv.info.selectSuper = selectSuperPrev;
// Set method symbol to resolved constructor...
TreeInfo.setSymbol(tree.meth, sym);
// ...and check that it is legal in the current context.
// (this will also set the tree's type)
Type mpt = newMethTemplate(argtypes, typeargtypes);
checkId(tree.meth, site, sym, localEnv, MTH, mpt, tree.varargsElement != null);
}
// Otherwise, `site' is an error type and we do nothing
}
result = tree.type = syms.voidType;
} else {
// Otherwise, we are seeing a regular method call.
// Attribute the arguments, yielding list of argument types, ...
argtypes = attribArgs(tree.args, localEnv);
typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
// ... and attribute the method using as a prototype a methodtype
// whose formal argument types is exactly the list of actual
// arguments (this will also set the method symbol).
Type mpt = newMethTemplate(argtypes, typeargtypes);
localEnv.info.varArgs = false;
Type mtype = attribExpr(tree.meth, localEnv, mpt);
if (localEnv.info.varArgs)
Assert.check(mtype.isErroneous() || tree.varargsElement != null);
// Compute the result type.
Type restype = mtype.getReturnType();
if (restype.tag == WILDCARD)
throw new AssertionError(mtype);
// the same as static type of the array being cloned
if (tree.meth.getTag() == JCTree.SELECT && allowCovariantReturns && methName == names.clone && types.isArray(((JCFieldAccess) tree.meth).selected.type))
restype = ((JCFieldAccess) tree.meth).selected.type;
// as a special case, x.getClass() has type Class<? extends |X|>
if (allowGenerics && methName == names.getClass && tree.args.isEmpty()) {
Type qualifier = (tree.meth.getTag() == JCTree.SELECT) ? ((JCFieldAccess) tree.meth).selected.type : env.enclClass.sym.type;
restype = new ClassType(restype.getEnclosingType(), List.<Type>of(new WildcardType(types.erasure(qualifier), BoundKind.EXTENDS, syms.boundClass)), restype.tsym);
}
chk.checkRefTypes(tree.typeargs, typeargtypes);
// Check that value of resulting type is admissible in the
// current context. Also, capture the return type
result = check(tree, capture(restype), VAL, pkind, pt);
}
chk.validate(tree.typeargs, localEnv);
}
use of com.sun.tools.javac.code.Type.MethodType in project lombok by rzwitserloot.
the class JavacHandlerUtil method fixMethodMirror.
private static void fixMethodMirror(Context context, Element typeMirror, long access, Name methodName, List<Type> paramTypes, Type returnType) {
if (typeMirror == null || paramTypes == null || returnType == null)
return;
ClassSymbol cs = (ClassSymbol) typeMirror;
MethodSymbol methodSymbol = new MethodSymbol(access, methodName, new MethodType(paramTypes, returnType, List.<Type>nil(), Symtab.instance(context).methodClass), cs);
ClassSymbolMembersField.enter(cs, methodSymbol);
}
use of com.sun.tools.javac.code.Type.MethodType in project error-prone by google.
the class AbstractToString method checkToString.
/**
* Tests if the given expression is converted to a String by its parent (i.e. its parent is a
* string concat expression, {@code String.format}, or {@code println(Object)}).
*/
private Description checkToString(ExpressionTree tree, VisitorState state) {
Symbol sym = ASTHelpers.getSymbol(tree);
if (!(sym instanceof VarSymbol || sym instanceof MethodSymbol)) {
return NO_MATCH;
}
Type type = ASTHelpers.getType(tree);
if (type instanceof MethodType) {
type = type.getReturnType();
}
Tree parent = state.getPath().getParentPath().getLeaf();
ToStringKind toStringKind = isToString(parent, tree, state);
if (toStringKind == ToStringKind.NONE) {
return NO_MATCH;
}
Optional<Fix> fix;
switch(toStringKind) {
case IMPLICIT:
fix = implicitToStringFix(tree, state);
break;
case EXPLICIT:
fix = toStringFix(parent, tree, state);
break;
default:
throw new AssertionError(toStringKind);
}
if (!typePredicate().apply(type, state)) {
return NO_MATCH;
}
return maybeFix(tree, fix);
}
use of com.sun.tools.javac.code.Type.MethodType in project error-prone by google.
the class Template method callCheckMethod.
/**
* Reflectively invoke Resolve.checkMethod(), which despite being package-private is apparently
* the only useful entry-point into javac8's type inference implementation.
*/
private MethodType callCheckMethod(Warner warner, Inliner inliner, Object resultInfo, List<Type> actualArgTypes, MethodSymbol methodSymbol, Type site, Env<AttrContext> env) throws InferException {
try {
Method checkMethod;
checkMethod = Resolve.class.getDeclaredMethod("checkMethod", Env.class, Type.class, Symbol.class, Class.forName(// ResultInfo is package-private
"com.sun.tools.javac.comp.Attr$ResultInfo"), List.class, List.class, Warner.class);
checkMethod.setAccessible(true);
return (MethodType) checkMethod.invoke(Resolve.instance(inliner.getContext()), env, site, methodSymbol, resultInfo, actualArgTypes, /*freeTypeVariables=*/
List.<Type>nil(), warner);
} catch (InvocationTargetException e) {
if (e.getCause() instanceof Resolve.InapplicableMethodException) {
throw new InferException(ImmutableList.of(((Resolve.InapplicableMethodException) e.getTargetException()).getDiagnostic()));
}
throw new LinkageError(e.getMessage(), e.getCause());
} catch (ReflectiveOperationException e) {
throw new LinkageError(e.getMessage(), e);
}
}
Aggregations