Search in sources :

Example 96 with Symbol

use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.

the class Attr method visitAssignop.

public void visitAssignop(JCAssignOp tree) {
    // Attribute arguments.
    Type owntype = attribTree(tree.lhs, env, varInfo);
    Type operand = attribExpr(tree.rhs, env);
    // Find operator.
    Symbol operator = tree.operator = rs.resolveBinaryOperator(tree.pos(), tree.getTag().noAssignOp(), env, owntype, operand);
    if (operator.kind == MTH && !owntype.isErroneous() && !operand.isErroneous()) {
        chk.checkOperator(tree.pos(), (OperatorSymbol) operator, tree.getTag().noAssignOp(), owntype, operand);
        chk.checkDivZero(tree.rhs.pos(), operator, operand);
        chk.checkCastable(tree.rhs.pos(), operator.type.getReturnType(), owntype);
    }
    result = check(tree, owntype, VAL, resultInfo);
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol)

Example 97 with Symbol

use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.

the class Attr method visitIdent.

public void visitIdent(JCIdent tree) {
    Symbol sym;
    /*if(tree instanceof JCIndyIdent) {
            sym = resolveIndyCall((JCIndyIdent) tree, pt().getParameterTypes());
        } else*/
    if (pt().hasTag(METHOD) || pt().hasTag(FORALL)) {
        // If we are looking for a method, the prototype `pt' will be a
        // method type with the type of the call's arguments as parameters.
        env.info.pendingResolutionPhase = null;
        sym = rs.resolveMethod(tree.pos(), env, tree.name, pt().getParameterTypes(), pt().getTypeArguments());
    } else if (tree.sym != null && tree.sym.kind != VAR) {
        sym = tree.sym;
    } else {
        sym = rs.resolveIdent(tree.pos(), env, tree.name, pkind());
    }
    tree.sym = sym;
    // (1) Also find the environment current for the class where
    // sym is defined (`symEnv').
    // Only for pre-tiger versions (1.4 and earlier):
    // (2) Also determine whether we access symbol out of an anonymous
    // class in a this or super call.  This is illegal for instance
    // members since such classes don't carry a this$n link.
    // (`noOuterThisPath').
    Env<AttrContext> symEnv = env;
    boolean noOuterThisPath = false;
    if (// we are in an inner class
    env.enclClass.sym.owner.kind != PCK && (sym.kind & (VAR | MTH | TYP)) != 0 && sym.owner.kind == TYP && tree.name != names._this && tree.name != names._super) {
        // Find environment in which identifier is defined.
        while (symEnv.outer != null && !sym.isMemberOf(symEnv.enclClass.sym, types)) {
            if ((symEnv.enclClass.sym.flags() & NOOUTERTHIS) != 0)
                noOuterThisPath = !allowAnonOuterThis;
            symEnv = symEnv.outer;
        }
    }
    // If symbol is a variable, ...
    if (sym.kind == VAR) {
        VarSymbol v = (VarSymbol) sym;
        // ..., evaluate its initializer, if it has one, and check for
        // illegal forward reference.
        checkInit(tree, env, v, false);
        // that the variable is assignable in the current environment.
        if (pkind() == VAR)
            checkAssignable(tree.pos(), v, null, env);
    }
    // not accessed before the supertype constructor is called.
    if ((symEnv.info.isSelfCall || noOuterThisPath) && (sym.kind & (VAR | MTH)) != 0 && sym.owner.kind == TYP && (sym.flags() & STATIC) == 0) {
        chk.earlyRefError(tree.pos(), sym.kind == VAR ? sym : thisSym(tree.pos(), env));
    }
    Env<AttrContext> env1 = env;
    if (sym.kind != ERR && sym.kind != TYP && sym.owner != null && sym.owner != env1.enclClass.sym) {
        // enclosing instance:
        while (env1.outer != null && !rs.isAccessible(env, env1.enclClass.sym.type, sym)) env1 = env1.outer;
    }
    if (env.info.isSerializable) {
        chk.checkElemAccessFromSerializableLambda(tree);
    }
    result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo);
}
Also used : Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol)

Example 98 with Symbol

use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.

the class Attr method copyScope.

Scope copyScope(Scope sc) {
    Scope newScope = new Scope(sc.owner);
    List<Symbol> elemsList = List.nil();
    while (sc != null) {
        for (Scope.Entry e = sc.elems; e != null; e = e.sibling) {
            elemsList = elemsList.prepend(e.sym);
        }
        sc = sc.next;
    }
    for (Symbol s : elemsList) {
        newScope.enter(s);
    }
    return newScope;
}
Also used : DelegatedScope(org.eclipse.ceylon.langtools.tools.javac.code.Scope.DelegatedScope) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol)

Example 99 with Symbol

use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.

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 type parameters, supertype and interfaces.
    attribStats(tree.typarams, env);
    if (!c.isAnonymous()) {
        // already checked if anonymous
        chk.validate(tree.typarams, env);
        chk.validate(tree.extending, env);
        chk.validate(tree.implementing, env);
    }
    c.markAbstractIfNeeded(types);
    // methods or unimplemented methods of an implemented interface.
    if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) {
        if (!relax)
            chk.checkAllDefined(tree.pos(), c);
    }
    if ((c.flags() & 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");
        // If this annotation has a @Repeatable, validate
        Attribute.Compound repeatable = c.attribute(syms.repeatableType.tsym);
        if (repeatable != null) {
            // get diagnostic position for error reporting
            DiagnosticPosition cbPos = getDiagnosticPosition(tree, repeatable.type);
            Assert.checkNonNull(cbPos);
            chk.validateRepeatable(c, repeatable, cbPos);
        }
    } 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);
        if (allowDefaultMethods) {
            chk.checkDefaultMethodClashes(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.hasTag(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.type) && (c.flags() & Flags.ENUM) == 0 && checkForSerial(c)) {
        checkSerialVersionUID(tree, c);
    }
    if (allowTypeAnnos) {
        // Correctly organize the postions of the type annotations
        typeAnnotations.organizeTypeAnnotationsBodies(tree);
        // Check type annotations applicability rules
        validateTypeAnnotations(tree, false);
    }
}
Also used : DiagnosticPosition(org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)

Example 100 with Symbol

use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.

the class Attr method visitNewClass.

public void visitNewClass(final JCNewClass tree) {
    Type owntype = types.createErrorType(tree.type);
    // The local environment of a class creation is
    // a new environment nested in the current one.
    Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
    // The anonymous inner class definition of the new expression,
    // if one is defined by it.
    JCClassDecl cdef = tree.def;
    // If enclosing class is given, attribute it, and
    // complete class name to be fully qualified
    // Class field following new
    JCExpression clazz = tree.clazz;
    // Identifier in class field
    JCExpression clazzid;
    // Annotated type enclosing clazzid
    JCAnnotatedType annoclazzid;
    annoclazzid = null;
    if (clazz.hasTag(TYPEAPPLY)) {
        clazzid = ((JCTypeApply) clazz).clazz;
        if (clazzid.hasTag(ANNOTATED_TYPE)) {
            annoclazzid = (JCAnnotatedType) clazzid;
            clazzid = annoclazzid.underlyingType;
        }
    } else {
        if (clazz.hasTag(ANNOTATED_TYPE)) {
            annoclazzid = (JCAnnotatedType) clazz;
            clazzid = annoclazzid.underlyingType;
        } else {
            clazzid = clazz;
        }
    }
    // The same in fully qualified form
    JCExpression clazzid1 = clazzid;
    if (tree.encl != null) {
        // We are seeing a qualified new, of the form
        // <expr>.new C <...> (...) ...
        // In this case, we let clazz stand for the name of the
        // allocated class C prefixed with the type of the qualifier
        // expression, so that we can
        // resolve it with standard techniques later. I.e., if
        // <expr> has type T, then <expr>.new C <...> (...)
        // yields a clazz T.C.
        Type encltype = chk.checkRefType(tree.encl.pos(), attribExpr(tree.encl, env));
        // TODO 308: in <expr>.new C, do we also want to add the type annotations
        // from expr to the combined type, or not? Yes, do this.
        clazzid1 = make.at(clazz.pos).Select(make.Type(encltype), ((JCIdent) clazzid).name);
        EndPosTable endPosTable = this.env.toplevel.endPositions;
        endPosTable.storeEnd(clazzid1, tree.getEndPosition(endPosTable));
        if (clazz.hasTag(ANNOTATED_TYPE)) {
            JCAnnotatedType annoType = (JCAnnotatedType) clazz;
            List<JCAnnotation> annos = annoType.annotations;
            if (annoType.underlyingType.hasTag(TYPEAPPLY)) {
                clazzid1 = make.at(tree.pos).TypeApply(clazzid1, ((JCTypeApply) clazz).arguments);
            }
            clazzid1 = make.at(tree.pos).AnnotatedType(annos, clazzid1);
        } else if (clazz.hasTag(TYPEAPPLY)) {
            clazzid1 = make.at(tree.pos).TypeApply(clazzid1, ((JCTypeApply) clazz).arguments);
        }
        clazz = clazzid1;
    }
    // Attribute clazz expression and store
    // symbol + type back into the attributed tree.
    Type clazztype = TreeInfo.isEnumInit(env.tree) ? attribIdentAsEnumType(env, (JCIdent) clazz) : attribType(clazz, env);
    clazztype = chk.checkDiamond(tree, clazztype);
    chk.validate(clazz, localEnv);
    if (tree.encl != null) {
        // We have to work in this case to store
        // symbol + type back into the attributed tree.
        tree.clazz.type = clazztype;
        TreeInfo.setSymbol(clazzid, TreeInfo.symbol(clazzid1));
        clazzid.type = ((JCIdent) clazzid).sym.type;
        if (annoclazzid != null) {
            annoclazzid.type = clazzid.type;
        }
        if (!clazztype.isErroneous()) {
            if (cdef != null && clazztype.tsym.isInterface()) {
                log.error(tree.encl.pos(), "anon.class.impl.intf.no.qual.for.new");
            } else if (clazztype.tsym.isStatic()) {
                log.error(tree.encl.pos(), "qualified.new.of.static.class", clazztype.tsym);
            }
        }
    } else if (!clazztype.tsym.isInterface() && clazztype.getEnclosingType().hasTag(CLASS)) {
        // Check for the existence of an apropos outer instance
        rs.resolveImplicitThis(tree.pos(), env, clazztype);
    }
    // Attribute constructor arguments.
    ListBuffer<Type> argtypesBuf = new ListBuffer<>();
    int pkind = attribArgs(VAL, tree.args, localEnv, argtypesBuf);
    List<Type> argtypes = argtypesBuf.toList();
    List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
    // If we have made no mistakes in the class type...
    if (clazztype.hasTag(CLASS)) {
        // Enums may not be instantiated except implicitly
        if (allowEnums && (clazztype.tsym.flags_field & Flags.ENUM) != 0 && (!env.tree.hasTag(VARDEF) || (((JCVariableDecl) env.tree).mods.flags & Flags.ENUM) == 0 || ((JCVariableDecl) env.tree).init != tree))
            log.error(tree.pos(), "enum.cant.be.instantiated");
        // Check that class is not abstract
        if (cdef == null && (clazztype.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
            log.error(tree.pos(), "abstract.cant.be.instantiated", clazztype.tsym);
        } else if (cdef != null && clazztype.tsym.isInterface()) {
            // anonymous classes implementing an interface
            if (!argtypes.isEmpty())
                log.error(tree.args.head.pos(), "anon.class.impl.intf.no.args");
            if (!typeargtypes.isEmpty())
                log.error(tree.typeargs.head.pos(), "anon.class.impl.intf.no.typeargs");
            // Error recovery: pretend no arguments were supplied.
            argtypes = List.nil();
            typeargtypes = List.nil();
        } else if (TreeInfo.isDiamond(tree)) {
            ClassType site = new ClassType(clazztype.getEnclosingType(), clazztype.tsym.type.getTypeArguments(), clazztype.tsym);
            Env<AttrContext> diamondEnv = localEnv.dup(tree);
            diamondEnv.info.selectSuper = cdef != null;
            diamondEnv.info.pendingResolutionPhase = null;
            // if the type of the instance creation expression is a class type
            // apply method resolution inference (JLS 15.12.2.7). The return type
            // of the resolved constructor will be a partially instantiated type
            Symbol constructor = rs.resolveDiamond(tree.pos(), diamondEnv, site, argtypes, typeargtypes);
            tree.constructor = constructor.baseSymbol();
            final TypeSymbol csym = clazztype.tsym;
            ResultInfo diamondResult = new ResultInfo(pkind, newMethodTemplate(resultInfo.pt, argtypes, typeargtypes), new Check.NestedCheckContext(resultInfo.checkContext) {

                @Override
                public void report(DiagnosticPosition _unused, JCDiagnostic details) {
                    enclosingContext.report(tree.clazz, diags.fragment("cant.apply.diamond.1", diags.fragment("diamond", csym), details));
                }
            });
            Type constructorType = tree.constructorType = types.createErrorType(clazztype);
            constructorType = checkId(noCheckTree, site, constructor, diamondEnv, diamondResult);
            tree.clazz.type = types.createErrorType(clazztype);
            if (!constructorType.isErroneous()) {
                tree.clazz.type = clazztype = constructorType.getReturnType();
                tree.constructorType = types.createMethodTypeWithReturn(constructorType, syms.voidType);
            }
            clazztype = chk.checkClassType(tree.clazz, tree.clazz.type, true);
        } else // Resolve the called constructor under the assumption
        // that we are referring to a superclass instance of the
        // current instance (JLS ???).
        {
            // the following code alters some of the fields in the current
            // AttrContext - hence, the current context must be dup'ed in
            // order to avoid downstream failures
            Env<AttrContext> rsEnv = localEnv.dup(tree);
            rsEnv.info.selectSuper = cdef != null;
            rsEnv.info.pendingResolutionPhase = null;
            tree.constructor = rs.resolveConstructor(tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
            if (cdef == null) {
                // do not check twice!
                tree.constructorType = checkId(noCheckTree, clazztype, tree.constructor, rsEnv, new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
                if (rsEnv.info.lastResolveVarargs())
                    Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null);
            }
            if (cdef == null && !clazztype.isErroneous() && clazztype.getTypeArguments().nonEmpty() && findDiamonds) {
                findDiamond(localEnv, tree, clazztype);
            }
        }
        if (cdef != null) {
            // }
            if (Resolve.isStatic(env))
                cdef.mods.flags |= STATIC;
            if (clazztype.tsym.isInterface()) {
                cdef.implementing = List.of(clazz);
            } else {
                cdef.extending = clazz;
            }
            if (resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK && isSerializable(clazztype)) {
                localEnv.info.isSerializable = true;
            }
            attribStat(cdef, localEnv);
            checkLambdaCandidate(tree, cdef.sym, clazztype);
            // and delete it from the new expression
            if (tree.encl != null && !clazztype.tsym.isInterface()) {
                tree.args = tree.args.prepend(makeNullCheck(tree.encl));
                argtypes = argtypes.prepend(tree.encl.type);
                tree.encl = null;
            }
            // Reassign clazztype and recompute constructor.
            clazztype = cdef.sym.type;
            Symbol sym = tree.constructor = rs.resolveConstructor(tree.pos(), localEnv, clazztype, argtypes, typeargtypes);
            Assert.check(sym.kind < AMBIGUOUS);
            tree.constructor = sym;
            tree.constructorType = checkId(noCheckTree, clazztype, tree.constructor, localEnv, new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
        }
        if (tree.constructor != null && tree.constructor.kind == MTH)
            owntype = clazztype;
    }
    result = check(tree, owntype, VAL, resultInfo);
    InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
    if (tree.constructorType != null && inferenceContext.free(tree.constructorType)) {
        // we need to wait for inference to finish and then replace inference vars in the constructor type
        inferenceContext.addFreeTypeListener(List.of(tree.constructorType), new FreeTypeListener() {

            @Override
            public void typesInferred(InferenceContext instantiatedContext) {
                tree.constructorType = instantiatedContext.asInstType(tree.constructorType);
            }
        });
    }
    chk.validate(tree.typeargs, localEnv);
}
Also used : Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) DiagnosticPosition(org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition) FreeTypeListener(org.eclipse.ceylon.langtools.tools.javac.comp.Infer.FreeTypeListener) InferenceContext(org.eclipse.ceylon.langtools.tools.javac.comp.Infer.InferenceContext) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type)

Aggregations

Symbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol)115 Type (org.eclipse.ceylon.langtools.tools.javac.code.Type)42 ClassSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol)16 MethodSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol)15 VarSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.VarSymbol)12 TypeSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol)11 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)11 DeferredAttrContext (org.eclipse.ceylon.langtools.tools.javac.comp.DeferredAttr.DeferredAttrContext)8 DeferredType (org.eclipse.ceylon.langtools.tools.javac.comp.DeferredAttr.DeferredType)8 DiagnosticType (org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticType)8 DynamicMethodSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.DynamicMethodSymbol)6 MethodType (org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType)6 JavaFileObject (org.eclipse.ceylon.javax.tools.JavaFileObject)5 DiagnosticPosition (org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition)4 ErrorType (org.eclipse.ceylon.javax.lang.model.type.ErrorType)3 Scope (org.eclipse.ceylon.langtools.tools.javac.code.Scope)3 PackageSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.PackageSymbol)3 HashSet (java.util.HashSet)2 LinkedList (java.util.LinkedList)2 DeclaredType (org.eclipse.ceylon.javax.lang.model.type.DeclaredType)2