Search in sources :

Example 51 with Symbol

use of com.sun.tools.javac.code.Symbol 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);
}
Also used : 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) WildcardType(com.sun.tools.javac.code.Type.WildcardType) JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) DynamicMethodSymbol(com.sun.tools.javac.code.Symbol.DynamicMethodSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) OperatorSymbol(com.sun.tools.javac.code.Symbol.OperatorSymbol) JCTree(com.sun.tools.javac.tree.JCTree) ClassType(com.sun.tools.javac.code.Type.ClassType) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) Kinds.kindName(com.sun.tools.javac.code.Kinds.kindName) Name(com.sun.tools.javac.util.Name)

Example 52 with Symbol

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

the class Attr method attribClassBody.

/** Finish the attribution of a class. */
private void attribClassBody(Env<AttrContext> env, ClassSymbol c) {
    JCClassDecl tree = (JCClassDecl) env.tree;
    Assert.check(c == tree.sym);
    // Validate annotations
    chk.validateAnnotations(tree.mods.annotations, c);
    // Validate type parameters, supertype and interfaces.
    attribBounds(tree.typarams);
    if (!c.isAnonymous()) {
        //already checked if anonymous
        chk.validate(tree.typarams, env);
        chk.validate(tree.extending, env);
        chk.validate(tree.implementing, env);
    }
    // methods or unimplemented methods of an implemented interface.
    if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) {
        if (!relax)
            chk.checkAllDefined(tree.pos(), c);
    }
    if ((c.flags() & ANNOTATION) != 0) {
        if (tree.implementing.nonEmpty())
            log.error(tree.implementing.head.pos(), "cant.extend.intf.annotation");
        if (tree.typarams.nonEmpty())
            log.error(tree.typarams.head.pos(), "intf.annotation.cant.have.type.params");
    } else {
        // Check that all extended classes and interfaces
        // are compatible (i.e. no two define methods with same arguments
        // yet different return types).  (JLS 8.4.6.3)
        chk.checkCompatibleSupertypes(tree.pos(), c.type);
    }
    // Check that class does not import the same parameterized interface
    // with two different argument lists.
    chk.checkClassBounds(tree.pos(), c.type);
    tree.type = c.type;
    for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail) {
        Assert.checkNonNull(env.info.scope.lookup(l.head.name).scope);
    }
    // Check that a generic class doesn't extend Throwable
    if (!sourceLanguage.isCeylon() && !c.type.allparams().isEmpty() && types.isSubtype(c.type, syms.throwableType))
        log.error(tree.extending.pos(), "generic.throwable");
    // Check that all methods which implement some
    // method conform to the method they implement.
    chk.checkImplementations(tree);
    //check that a resource implementing AutoCloseable cannot throw InterruptedException
    checkAutoCloseable(tree.pos(), env, c.type);
    for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
        // Attribute declaration
        attribStat(l.head, env);
        // Make an exception for static constants.
        if (c.owner.kind != PCK && ((c.flags() & STATIC) == 0 || c.name == names.empty) && (TreeInfo.flags(l.head) & (STATIC | INTERFACE)) != 0) {
            Symbol sym = null;
            if (l.head.getTag() == JCTree.VARDEF)
                sym = ((JCVariableDecl) l.head).sym;
            if (sym == null || sym.kind != VAR || ((VarSymbol) sym).getConstValue() == null)
                log.error(l.head.pos(), "icls.cant.have.static.decl", c);
        }
    }
    // Check for cycles among non-initial constructors.
    chk.checkCyclicConstructors(tree);
    // Check for cycles among annotation elements.
    chk.checkNonCyclicElements(tree);
    // Check for proper use of serialVersionUID
    if (env.info.lint.isEnabled(LintCategory.SERIAL) && isSerializable(c) && (c.flags() & Flags.ENUM) == 0 && (c.flags() & ABSTRACT) == 0) {
        checkSerialVersionUID(tree, c);
    }
}
Also used : JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) DynamicMethodSymbol(com.sun.tools.javac.code.Symbol.DynamicMethodSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) OperatorSymbol(com.sun.tools.javac.code.Symbol.OperatorSymbol) JCTree(com.sun.tools.javac.tree.JCTree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Example 53 with Symbol

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

the class Check method checkOverrideClashes.

/** Check that all non-override equivalent methods accessible from 'site'
     *  are mutually compatible (JLS 8.4.8/9.4.1).
     *
     *  @param pos  Position to be used for error reporting.
     *  @param site The class whose methods are checked.
     *  @param sym  The method symbol to be checked.
     */
void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
    ClashFilter cf = new ClashFilter(site);
    //for each method m1 that is a member of 'site'...
    for (Symbol s1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
        //by method 'sym' in 'site'
        for (Symbol s2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
            if (s1 == s2 || !sym.overrides(s2, site.tsym, types, false))
                continue;
            //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
            if (!types.isSubSignature(sym.type, types.memberType(site, s1), false) && types.hasSameArgs(s1.erasure(types), s2.erasure(types))) {
                sym.flags_field |= CLASH;
                String key = s2 == sym ? "name.clash.same.erasure.no.override" : "name.clash.same.erasure.no.override.1";
                log.error(pos, key, sym, sym.location(), s1, s1.location(), s2, s2.location());
                return;
            }
        }
    }
}
Also used : Symbol(com.sun.tools.javac.code.Symbol)

Example 54 with Symbol

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

the class Check method checkNonCyclicInternal.

/** Check for cyclic references. Issue an error if the
     *  symbol of the type referred to has a LOCKED flag set.
     *
     *  @param pos      Position to be used for error reporting.
     *  @param t        The type referred to.
     *  @returns        True if the check completed on all attributed classes
     */
private boolean checkNonCyclicInternal(DiagnosticPosition pos, Type t) {
    // was the check complete?
    boolean complete = true;
    //- System.err.println("checkNonCyclicInternal("+t+");");//DEBUG
    Symbol c = t.tsym;
    if ((c.flags_field & ACYCLIC) != 0)
        return true;
    if ((c.flags_field & LOCKED) != 0) {
        noteCyclic(pos, (ClassSymbol) c);
    } else if (!c.type.isErroneous()) {
        try {
            c.flags_field |= LOCKED;
            if (c.type.tag == CLASS) {
                ClassType clazz = (ClassType) c.type;
                if (clazz.interfaces_field != null)
                    for (List<Type> l = clazz.interfaces_field; l.nonEmpty(); l = l.tail) complete &= checkNonCyclicInternal(pos, l.head);
                if (clazz.supertype_field != null) {
                    Type st = clazz.supertype_field;
                    if (st != null && st.tag == CLASS)
                        complete &= checkNonCyclicInternal(pos, st);
                }
                if (c.owner.kind == TYP)
                    complete &= checkNonCyclicInternal(pos, c.owner.type);
            }
        } finally {
            c.flags_field &= ~LOCKED;
        }
    }
    if (complete)
        complete = ((c.flags_field & UNATTRIBUTED) == 0) && c.completer == null;
    if (complete)
        c.flags_field |= ACYCLIC;
    return complete;
}
Also used : Type(com.sun.tools.javac.code.Type) Symbol(com.sun.tools.javac.code.Symbol)

Example 55 with Symbol

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

the class Enter method visitClassDef.

@Override
public void visitClassDef(JCClassDecl tree) {
    Symbol owner = env.info.scope.owner;
    Scope enclScope = enterScope(env);
    ClassSymbol c;
    if (owner.kind == PCK) {
        // We are seeing a toplevel class.
        PackageSymbol packge = (PackageSymbol) owner;
        for (Symbol q = packge; q != null && q.kind == PCK; q = q.owner) q.flags_field |= EXISTS;
        c = reader.enterClass(tree.name, packge);
        packge.members().enterIfAbsent(c);
        if ((tree.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env) && !sourceLanguage.isCeylon()) {
            log.error(tree.pos(), "class.public.should.be.in.file", tree.name);
        }
    } else {
        if (!tree.name.isEmpty() && !chk.checkUniqueClassName(tree.pos(), tree.name, enclScope)) {
            result = null;
            return;
        }
        if (owner.kind == TYP) {
            // We are seeing a member class.
            c = reader.enterClass(tree.name, (TypeSymbol) owner);
            if ((owner.flags_field & INTERFACE) != 0) {
                tree.mods.flags |= PUBLIC | STATIC;
            }
        } else {
            // We are seeing a local class.
            c = reader.defineClass(tree.name, owner);
            c.flatname = chk.localClassName(c);
            if (!c.name.isEmpty())
                chk.checkTransparentClass(tree.pos(), c, env.info.scope);
        }
    }
    tree.sym = c;
    // Enter class into `compiled' table and enclosing scope.
    if (chk.compiled.get(c.flatname) != null) {
        duplicateClass(tree.pos(), c);
        result = types.createErrorType(tree.name, (TypeSymbol) owner, Type.noType);
        tree.sym = (ClassSymbol) result.tsym;
        return;
    }
    chk.compiled.put(c.flatname, c);
    // CEYLON(stef): don't add anonymous classes to the environment 
    if (tree.name.length() != 0)
        enclScope.enter(c);
    // Set up an environment for class block and store in `typeEnvs'
    // table, to be retrieved later in memberEnter and attribution.
    Env<AttrContext> localEnv = classEnv(tree, env);
    typeEnvs.put(c, localEnv);
    // Fill out class fields.
    c.completer = memberEnter;
    c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
    c.sourcefile = env.toplevel.sourcefile;
    c.members_field = new Scope(c);
    // determine the enclosing type
    if (sourceLanguage.isCeylon()) {
        // (This would be an illegal access to "this before super").
        if (env.info.isSelfCall && (isNewAnonymousClass(env.tree) || isNewLetClass(env.tree))) {
            c.flags_field |= CEYLON_NOOUTERTHIS;
        }
    }
    ClassType ct = (ClassType) c.type;
    // Ceylon: make sure everything is reset if we Enter twice for bootstrap
    ct.interfaces_field = null;
    ct.allparams_field = null;
    ct.supertype_field = null;
    ct.all_interfaces_field = null;
    // End Ceylon
    if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
        // We are seeing a local or inner class.
        // Set outer_field of this class to closest enclosing class
        // which contains this class in a non-static context
        // (its "enclosing instance class"), provided such a class exists.
        Symbol owner1 = owner;
        // Ceylon: make sure we skip outer classes if required
        boolean skip = c.skipOuterClass();
        while (skip || ((owner1.kind & (VAR | MTH)) != 0 && (owner1.flags_field & STATIC) == 0)) {
            // Ceylon: we only take new outer class skip orders from types, never from methods/vars
            if (owner1.kind == TYP)
                skip = owner1.skipOuterClass();
            owner1 = owner1.owner;
        }
        if (owner1.kind == TYP) {
            ct.setEnclosingType(owner1.type);
        }
    }
    // Enter type parameters.
    ct.typarams_field = classEnter(tree.typarams, localEnv);
    // completed later.
    if (!c.isLocal() && uncompleted != null)
        uncompleted.append(c);
    //      System.err.println("entering " + c.fullname + " in " + c.owner);//DEBUG
    // Recursively enter all member classes.
    classEnter(tree.defs, localEnv);
    result = c.type;
}
Also used : Scope(com.sun.tools.javac.code.Scope) Symbol(com.sun.tools.javac.code.Symbol)

Aggregations

Symbol (com.sun.tools.javac.code.Symbol)195 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)56 Type (com.sun.tools.javac.code.Type)54 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)53 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)45 TypeSymbol (com.sun.tools.javac.code.Symbol.TypeSymbol)36 PackageSymbol (com.sun.tools.javac.code.Symbol.PackageSymbol)29 JCTree (com.sun.tools.javac.tree.JCTree)28 ClassType (com.sun.tools.javac.code.Type.ClassType)18 Tree (com.sun.source.tree.Tree)17 ExpressionTree (com.sun.source.tree.ExpressionTree)15 DynamicMethodSymbol (com.sun.tools.javac.code.Symbol.DynamicMethodSymbol)15 OperatorSymbol (com.sun.tools.javac.code.Symbol.OperatorSymbol)15 ClassTree (com.sun.source.tree.ClassTree)14 MethodTree (com.sun.source.tree.MethodTree)14 Name (com.sun.tools.javac.util.Name)14 IdentifierTree (com.sun.source.tree.IdentifierTree)13 ArrayType (com.sun.tools.javac.code.Type.ArrayType)12 MethodType (com.sun.tools.javac.code.Type.MethodType)12 UnionClassType (com.sun.tools.javac.code.Type.UnionClassType)12