Search in sources :

Example 1 with TypeVar

use of com.sun.tools.javac.code.Type.TypeVar in project error-prone by google.

the class ASTHelpersTest method testGetUpperBoundCapturedTypeVariable.

@Test
public void testGetUpperBoundCapturedTypeVariable() {
    writeFile("A.java", "import java.lang.Number;", "import java.util.List;", "public class A {", "  public void doSomething(List<? extends Number> list) {", "    list.get(0);", "  }", "}");
    TestScanner scanner = new TestScanner() {

        @Override
        public Void visitMethodInvocation(MethodInvocationTree tree, VisitorState state) {
            if (!"super()".equals(tree.toString())) {
                // ignore synthetic super call
                setAssertionsComplete();
                Type type = ASTHelpers.getType(tree);
                assertThat(type instanceof TypeVar).isTrue();
                assertThat(((TypeVar) type).isCaptured()).isTrue();
                assertThat(ASTHelpers.getUpperBound(type, state.getTypes()).toString()).isEqualTo("java.lang.Number");
            }
            return super.visitMethodInvocation(tree, state);
        }
    };
    tests.add(scanner);
    assertCompiles(scanner);
}
Also used : Type(com.sun.tools.javac.code.Type) TypeVar(com.sun.tools.javac.code.Type.TypeVar) VisitorState(com.google.errorprone.VisitorState) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) CompilerBasedAbstractTest(com.google.errorprone.matchers.CompilerBasedAbstractTest) Test(org.junit.Test)

Example 2 with TypeVar

use of com.sun.tools.javac.code.Type.TypeVar in project error-prone by google.

the class TypeParameterUnusedInFormals method matchMethod.

@Override
public Description matchMethod(MethodTree tree, VisitorState state) {
    MethodSymbol methodSymbol = ASTHelpers.getSymbol(tree);
    if (methodSymbol == null) {
        return Description.NO_MATCH;
    }
    // Only match methods where the return type is just a type parameter.
    // e.g. the following is OK: <T> List<T> newArrayList();
    TypeVar retType;
    switch(methodSymbol.getReturnType().getKind()) {
        case TYPEVAR:
            retType = (TypeVar) methodSymbol.getReturnType();
            break;
        default:
            return Description.NO_MATCH;
    }
    if (!methodSymbol.equals(retType.tsym.owner)) {
        return Description.NO_MATCH;
    }
    // e.g.: <T extends Enum<T>> T unsafeEnumDeserializer();
    if (retType.bound != null && TypeParameterFinder.visit(retType.bound).contains(retType.tsym)) {
        return Description.NO_MATCH;
    }
    // e.g.: <T> T noop(T t);
    for (VarSymbol formalParam : methodSymbol.getParameters()) {
        if (TypeParameterFinder.visit(formalParam.type).contains(retType.tsym)) {
            return Description.NO_MATCH;
        }
    }
    return describeMatch(tree);
}
Also used : TypeVar(com.sun.tools.javac.code.Type.TypeVar) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol)

Example 3 with TypeVar

use of com.sun.tools.javac.code.Type.TypeVar in project ceylon-compiler by ceylon.

the class TypeMaker method typeParametersString.

/**
     * Return the formal type parameters of a class or method as an
     * angle-bracketed string.  Each parameter is a type variable with
     * optional bounds.  Class names are qualified if "full" is true.
     * Return "" if there are no type parameters or we're hiding generics.
     */
static String typeParametersString(DocEnv env, Symbol sym, boolean full) {
    if (env.legacyDoclet || sym.type.getTypeArguments().isEmpty()) {
        return "";
    }
    StringBuilder s = new StringBuilder();
    for (Type t : sym.type.getTypeArguments()) {
        s.append(s.length() == 0 ? "<" : ", ");
        s.append(TypeVariableImpl.typeVarToString(env, (TypeVar) t, full));
    }
    s.append(">");
    return s.toString();
}
Also used : ClassType(com.sun.tools.javac.code.Type.ClassType) ArrayType(com.sun.tools.javac.code.Type.ArrayType) Type(com.sun.tools.javac.code.Type) TypeVar(com.sun.tools.javac.code.Type.TypeVar)

Example 4 with TypeVar

use of com.sun.tools.javac.code.Type.TypeVar in project error-prone by google.

the class Inliner method inlineAsVar.

public TypeVar inlineAsVar(UTypeVar var) throws CouldNotResolveImportException {
    /*
     * In order to handle recursively bounded type variables without a stack overflow,
     * we first cache a type var with no bounds, then we inline the bounds.
     */
    TypeVar typeVar = typeVarCache.get(var.getName());
    if (typeVar != null) {
        return typeVar;
    }
    Name name = asName(var.getName());
    TypeSymbol sym = new TypeVariableSymbol(0, name, null, symtab().noSymbol);
    typeVar = new TypeVar(sym, null, null);
    sym.type = typeVar;
    typeVarCache.put(var.getName(), typeVar);
    // Any recursive uses of var will point to the same TypeVar object generated above.
    typeVar.bound = var.getUpperBound().inline(this);
    typeVar.lower = var.getLowerBound().inline(this);
    return typeVar;
}
Also used : TypeVar(com.sun.tools.javac.code.Type.TypeVar) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) TypeVariableSymbol(com.sun.tools.javac.code.Symbol.TypeVariableSymbol) Name(com.sun.tools.javac.util.Name)

Example 5 with TypeVar

use of com.sun.tools.javac.code.Type.TypeVar in project ceylon-compiler by ceylon.

the class Attr method visitTypeParameter.

public void visitTypeParameter(JCTypeParameter tree) {
    TypeVar a = (TypeVar) tree.type;
    Set<Type> boundSet = new HashSet<Type>();
    if (a.bound.isErroneous())
        return;
    List<Type> bs = types.getBounds(a);
    if (tree.bounds.nonEmpty()) {
        // accept class or interface or typevar as first bound.
        Type b = checkBase(bs.head, tree.bounds.head, env, false, false, false);
        boundSet.add(types.erasure(b));
        if (b.isErroneous()) {
            a.bound = b;
        } else if (b.tag == TYPEVAR) {
            // if first bound was a typevar, do not accept further bounds.
            if (tree.bounds.tail.nonEmpty()) {
                log.error(tree.bounds.tail.head.pos(), "type.var.may.not.be.followed.by.other.bounds");
                tree.bounds = List.of(tree.bounds.head);
                a.bound = bs.head;
            }
        } else {
            // as further bounds.
            for (JCExpression bound : tree.bounds.tail) {
                bs = bs.tail;
                Type i = checkBase(bs.head, bound, env, false, true, false);
                if (i.isErroneous())
                    a.bound = i;
                else if (i.tag == CLASS)
                    chk.checkNotRepeated(bound.pos(), types.erasure(i), boundSet);
            }
        }
    }
    bs = types.getBounds(a);
    // in case of multiple bounds ...
    if (bs.length() > 1) {
        // ... the variable's bound is a class type flagged COMPOUND
        // (see comment for TypeVar.bound).
        // In this case, generate a class tree that represents the
        // bound class, ...
        JCExpression extending;
        List<JCExpression> implementing;
        if ((bs.head.tsym.flags() & INTERFACE) == 0) {
            extending = tree.bounds.head;
            implementing = tree.bounds.tail;
        } else {
            extending = null;
            implementing = tree.bounds;
        }
        JCClassDecl cd = make.at(tree.pos).ClassDef(make.Modifiers(PUBLIC | ABSTRACT), tree.name, List.<JCTypeParameter>nil(), extending, implementing, List.<JCTree>nil());
        ClassSymbol c = (ClassSymbol) a.getUpperBound().tsym;
        Assert.check((c.flags() & COMPOUND) != 0);
        cd.sym = c;
        c.sourcefile = env.toplevel.sourcefile;
        // ... and attribute the bound class
        c.flags_field |= UNATTRIBUTED;
        Env<AttrContext> cenv = enter.classEnv(cd, env);
        enter.typeEnvs.put(c, cenv);
    }
}
Also used : TypeVar(com.sun.tools.javac.code.Type.TypeVar) ClassType(com.sun.tools.javac.code.Type.ClassType) MethodType(com.sun.tools.javac.code.Type.MethodType) WildcardType(com.sun.tools.javac.code.Type.WildcardType) Type(com.sun.tools.javac.code.Type) ArrayType(com.sun.tools.javac.code.Type.ArrayType) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) HashSet(java.util.HashSet)

Aggregations

TypeVar (com.sun.tools.javac.code.Type.TypeVar)6 Type (com.sun.tools.javac.code.Type)4 ArrayType (com.sun.tools.javac.code.Type.ArrayType)3 ClassType (com.sun.tools.javac.code.Type.ClassType)3 MethodType (com.sun.tools.javac.code.Type.MethodType)2 UnionClassType (com.sun.tools.javac.code.Type.UnionClassType)2 WildcardType (com.sun.tools.javac.code.Type.WildcardType)2 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)2 VisitorState (com.google.errorprone.VisitorState)1 CompilerBasedAbstractTest (com.google.errorprone.matchers.CompilerBasedAbstractTest)1 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)1 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)1 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)1 TypeSymbol (com.sun.tools.javac.code.Symbol.TypeSymbol)1 TypeVariableSymbol (com.sun.tools.javac.code.Symbol.TypeVariableSymbol)1 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)1 JCClassDecl (com.sun.tools.javac.tree.JCTree.JCClassDecl)1 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)1 Name (com.sun.tools.javac.util.Name)1 HashSet (java.util.HashSet)1