use of com.sun.tools.javac.code.Type.WildcardType 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.WildcardType in project lombok by rzwitserloot.
the class JavacResolution method typeToJCTree0.
private static JCExpression typeToJCTree0(Type type, JavacAST ast, boolean allowCompound, boolean allowVoid) throws TypeNotConvertibleException {
// NB: There's such a thing as maker.Type(type), but this doesn't work very well; it screws up anonymous classes, captures, and adds an extra prefix dot for some reason too.
// -- so we write our own take on that here.
JavacTreeMaker maker = ast.getTreeMaker();
if (CTC_BOT.equals(typeTag(type)))
return createJavaLangObject(ast);
if (CTC_VOID.equals(typeTag(type)))
return allowVoid ? primitiveToJCTree(type.getKind(), maker) : createJavaLangObject(ast);
if (type.isPrimitive())
return primitiveToJCTree(type.getKind(), maker);
if (type.isErroneous())
throw new TypeNotConvertibleException("Type cannot be resolved");
TypeSymbol symbol = type.asElement();
List<Type> generics = type.getTypeArguments();
JCExpression replacement = null;
if (symbol == null)
throw new TypeNotConvertibleException("Null or compound type");
if (symbol.name.length() == 0) {
// Anonymous inner class
if (type instanceof ClassType) {
List<Type> ifaces = ((ClassType) type).interfaces_field;
Type supertype = ((ClassType) type).supertype_field;
if (ifaces != null && ifaces.length() == 1) {
return typeToJCTree(ifaces.get(0), ast, allowCompound, allowVoid);
}
if (supertype != null)
return typeToJCTree(supertype, ast, allowCompound, allowVoid);
}
throw new TypeNotConvertibleException("Anonymous inner class");
}
if (type instanceof CapturedType || type instanceof WildcardType) {
Type lower, upper;
if (type instanceof WildcardType) {
upper = ((WildcardType) type).getExtendsBound();
lower = ((WildcardType) type).getSuperBound();
} else {
lower = type.getLowerBound();
upper = type.getUpperBound();
}
if (allowCompound) {
if (lower == null || CTC_BOT.equals(typeTag(lower))) {
if (upper == null || upper.toString().equals("java.lang.Object")) {
return maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
}
if (upper.getTypeArguments().contains(type)) {
return maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
}
return maker.Wildcard(maker.TypeBoundKind(BoundKind.EXTENDS), typeToJCTree(upper, ast, false, false));
} else {
return maker.Wildcard(maker.TypeBoundKind(BoundKind.SUPER), typeToJCTree(lower, ast, false, false));
}
}
if (upper != null) {
if (upper.getTypeArguments().contains(type)) {
return maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
}
return typeToJCTree(upper, ast, allowCompound, allowVoid);
}
return createJavaLangObject(ast);
}
String qName;
if (symbol.isLocal()) {
qName = symbol.getSimpleName().toString();
} else if (symbol.type != null && symbol.type.getEnclosingType() != null && typeTag(symbol.type.getEnclosingType()).equals(typeTag("CLASS"))) {
replacement = typeToJCTree0(type.getEnclosingType(), ast, false, false);
qName = symbol.getSimpleName().toString();
} else {
qName = symbol.getQualifiedName().toString();
}
if (qName.isEmpty())
throw new TypeNotConvertibleException("unknown type");
if (qName.startsWith("<"))
throw new TypeNotConvertibleException(qName);
String[] baseNames = qName.split("\\.");
int i = 0;
if (replacement == null) {
replacement = maker.Ident(ast.toName(baseNames[0]));
i = 1;
}
for (; i < baseNames.length; i++) {
replacement = maker.Select(replacement, ast.toName(baseNames[i]));
}
return genericsToJCTreeNodes(generics, ast, replacement);
}
use of com.sun.tools.javac.code.Type.WildcardType in project ceylon-compiler by ceylon.
the class Attr method visitWildcard.
public void visitWildcard(JCWildcard tree) {
//- System.err.println("visitWildcard("+tree+");");//DEBUG
Type type = (tree.kind.kind == BoundKind.UNBOUND) ? syms.objectType : attribType(tree.inner, env);
result = check(tree, new WildcardType(chk.checkRefType(tree.pos(), type), tree.kind.kind, syms.boundClass), TYP, pkind, pt);
}
use of com.sun.tools.javac.code.Type.WildcardType in project ceylon-compiler by ceylon.
the class JavacType method getLowerBound.
@Override
public TypeMirror getLowerBound() {
if (!lowerBoundSet && type instanceof WildcardType) {
Type bound = ((WildcardType) type).getSuperBound();
if (bound != null) {
lowerBound = new JavacType(bound);
}
lowerBoundSet = true;
}
return lowerBound;
}
Aggregations