Search in sources :

Example 1 with DiagnosticPosition

use of org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition in project ceylon by eclipse.

the class Lower method visitAssert.

/**
 * Visitor method for assert statements. Translate them away.
 */
public void visitAssert(JCAssert tree) {
    DiagnosticPosition detailPos = (tree.detail == null) ? tree.pos() : tree.detail.pos();
    tree.cond = translate(tree.cond, syms.booleanType);
    if (!tree.cond.type.isTrue()) {
        JCExpression cond = assertFlagTest(tree.pos());
        List<JCExpression> exnArgs = (tree.detail == null) ? List.<JCExpression>nil() : List.of(translate(tree.detail));
        if (!tree.cond.type.isFalse()) {
            cond = makeBinary(AND, cond, makeUnary(NOT, tree.cond));
        }
        result = make.If(cond, make_at(tree).Throw(makeNewClass(syms.assertionErrorType, exnArgs)), null);
    } else {
        result = make.Skip();
    }
}
Also used : DiagnosticPosition(org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition)

Example 2 with DiagnosticPosition

use of org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition in project ceylon by eclipse.

the class MemberEnter method complete.

/* ********************************************************************
 * Source completer
 *********************************************************************/
/**
 * Complete entering a class.
 *  @param sym         The symbol of the class to be completed.
 */
public void complete(Symbol sym) throws CompletionFailure {
    // Suppress some (recursive) MemberEnter invocations
    if (!completionEnabled) {
        // Re-install same completer for next time around and return.
        Assert.check((sym.flags() & Flags.COMPOUND) == 0);
        sym.completer = this;
        return;
    }
    ClassSymbol c = (ClassSymbol) sym;
    ClassType ct = (ClassType) c.type;
    Env<AttrContext> env = typeEnvs.get(c);
    JCClassDecl tree = (JCClassDecl) env.tree;
    boolean wasFirst = isFirst;
    isFirst = false;
    try {
        annotate.enterStart();
        JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
        DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
        try {
            // Save class environment for later member enter (2) processing.
            halfcompleted.append(env);
            // Mark class as not yet attributed.
            c.flags_field |= UNATTRIBUTED;
            // clauses have been seen.
            if (c.owner.kind == PCK) {
                memberEnter(env.toplevel, env.enclosing(TOPLEVEL));
                todo.append(env);
            }
            if (c.owner.kind == TYP)
                c.owner.complete();
            // create an environment for evaluating the base clauses
            Env<AttrContext> baseEnv = baseEnv(tree, env);
            if (tree.extending != null)
                typeAnnotate(tree.extending, baseEnv, sym, tree.pos());
            for (JCExpression impl : tree.implementing) typeAnnotate(impl, baseEnv, sym, tree.pos());
            annotate.flush();
            // Determine supertype.
            Type supertype = (tree.extending != null) ? attr.attribBase(tree.extending, baseEnv, true, false, true) : ((tree.mods.flags & Flags.ENUM) != 0) ? attr.attribBase(enumBase(tree.pos, c), baseEnv, true, false, false) : (c.fullname == names.java_lang_Object) ? Type.noType : syms.objectType;
            ct.supertype_field = modelMissingTypes(supertype, tree.extending, false);
            // Determine interfaces.
            ListBuffer<Type> interfaces = new ListBuffer<Type>();
            // lazy init
            ListBuffer<Type> all_interfaces = null;
            Set<Type> interfaceSet = new HashSet<Type>();
            List<JCExpression> interfaceTrees = tree.implementing;
            for (JCExpression iface : interfaceTrees) {
                Type i = attr.attribBase(iface, baseEnv, false, true, true);
                if (i.hasTag(CLASS)) {
                    interfaces.append(i);
                    if (all_interfaces != null)
                        all_interfaces.append(i);
                    chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet);
                } else {
                    if (all_interfaces == null)
                        all_interfaces = new ListBuffer<Type>().appendList(interfaces);
                    all_interfaces.append(modelMissingTypes(i, iface, true));
                }
            }
            if ((c.flags_field & Flags.ANNOTATION) != 0) {
                ct.interfaces_field = List.of(syms.annotationType);
                ct.all_interfaces_field = ct.interfaces_field;
            } else {
                ct.interfaces_field = interfaces.toList();
                ct.all_interfaces_field = (all_interfaces == null) ? ct.interfaces_field : all_interfaces.toList();
            }
            if (c.fullname == names.java_lang_Object) {
                if (tree.extending != null) {
                    chk.checkNonCyclic(tree.extending.pos(), supertype);
                    ct.supertype_field = Type.noType;
                } else if (tree.implementing.nonEmpty()) {
                    chk.checkNonCyclic(tree.implementing.head.pos(), ct.interfaces_field.head);
                    ct.interfaces_field = List.nil();
                }
            }
            // Annotations.
            // In general, we cannot fully process annotations yet,  but we
            // can attribute the annotation types and then check to see if the
            // @Deprecated annotation is present.
            attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
            if (hasDeprecatedAnnotation(tree.mods.annotations))
                c.flags_field |= DEPRECATED;
            annotateLater(tree.mods.annotations, baseEnv, c, tree.pos());
            // class type parameters use baseEnv but everything uses env
            chk.checkNonCyclicDecl(tree);
            attr.attribTypeVariables(tree.typarams, baseEnv);
            // Do this here, where we have the symbol.
            for (JCTypeParameter tp : tree.typarams) typeAnnotate(tp, baseEnv, sym, tree.pos());
            // Add default constructor if needed.
            if ((c.flags() & INTERFACE) == 0 && !TreeInfo.hasConstructors(tree.defs)) {
                List<Type> argtypes = List.nil();
                List<Type> typarams = List.nil();
                List<Type> thrown = List.nil();
                long ctorFlags = 0;
                boolean based = false;
                boolean addConstructor = true;
                JCNewClass nc = null;
                if (c.name.isEmpty()) {
                    nc = (JCNewClass) env.next.tree;
                    if (nc.constructor != null) {
                        addConstructor = nc.constructor.kind != ERR;
                        Type superConstrType = types.memberType(c.type, nc.constructor);
                        argtypes = superConstrType.getParameterTypes();
                        typarams = superConstrType.getTypeArguments();
                        ctorFlags = nc.constructor.flags() & VARARGS;
                        if (nc.encl != null) {
                            argtypes = argtypes.prepend(nc.encl.type);
                            based = true;
                        }
                        thrown = superConstrType.getThrownTypes();
                    }
                }
                if (addConstructor) {
                    MethodSymbol basedConstructor = nc != null ? (MethodSymbol) nc.constructor : null;
                    JCTree constrDef = DefaultConstructor(make.at(tree.pos), c, basedConstructor, typarams, argtypes, thrown, ctorFlags, based);
                    tree.defs = tree.defs.prepend(constrDef);
                }
            }
            // enter symbols for 'this' into current scope.
            VarSymbol thisSym = new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
            thisSym.pos = Position.FIRSTPOS;
            env.info.scope.enter(thisSym);
            // if this is a class, enter symbol for 'super' into current scope.
            if ((c.flags_field & INTERFACE) == 0 && ct.supertype_field.hasTag(CLASS)) {
                VarSymbol superSym = new VarSymbol(FINAL | HASINIT, names._super, ct.supertype_field, c);
                superSym.pos = Position.FIRSTPOS;
                env.info.scope.enter(superSym);
            }
            // name as a top-level package.
            if (checkClash && c.owner.kind == PCK && c.owner != syms.unnamedPackage && reader.packageExists(c.fullname)) {
                log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
            }
            if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 && !env.toplevel.sourcefile.isNameCompatible(c.name.toString(), JavaFileObject.Kind.SOURCE)) {
                c.flags_field |= AUXILIARY;
            }
        } catch (CompletionFailure ex) {
            chk.completionError(tree.pos(), ex);
        } finally {
            deferredLintHandler.setPos(prevLintPos);
            log.useSource(prev);
        }
        // classes in a second phase.
        if (wasFirst) {
            try {
                while (halfcompleted.nonEmpty()) {
                    Env<AttrContext> toFinish = halfcompleted.next();
                    finish(toFinish);
                    if (allowTypeAnnos) {
                        typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl) toFinish.tree);
                        typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl) toFinish.tree);
                    }
                }
            } finally {
                isFirst = true;
            }
        }
    } finally {
        annotate.enterDone();
    }
}
Also used : JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) DiagnosticPosition(org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition) HashSet(java.util.HashSet)

Example 3 with DiagnosticPosition

use of org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition in project ceylon by eclipse.

the class MemberEnter method visitMethodDef.

public void visitMethodDef(JCMethodDecl tree) {
    Scope enclScope = enter.enterScope(env);
    MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner);
    m.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, m, tree);
    tree.sym = m;
    // if this is a default method, add the DEFAULT flag to the enclosing interface
    if ((tree.mods.flags & DEFAULT) != 0) {
        m.enclClass().flags_field |= DEFAULT;
    }
    Env<AttrContext> localEnv = methodEnv(tree, env);
    DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
    try {
        // Compute the method type
        m.type = signature(m, tree.typarams, tree.params, tree.restype, tree.recvparam, tree.thrown, localEnv);
    } finally {
        deferredLintHandler.setPos(prevLintPos);
    }
    if (types.isSignaturePolymorphic(m)) {
        m.flags_field |= SIGNATURE_POLYMORPHIC;
    }
    // Set m.params
    ListBuffer<VarSymbol> params = new ListBuffer<VarSymbol>();
    JCVariableDecl lastParam = null;
    for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
        JCVariableDecl param = lastParam = l.head;
        params.append(Assert.checkNonNull(param.sym));
    }
    m.params = params.toList();
    // mark the method varargs, if necessary
    if (lastParam != null && (lastParam.mods.flags & Flags.VARARGS) != 0)
        m.flags_field |= Flags.VARARGS;
    localEnv.info.scope.leave();
    if (chk.checkUnique(tree.pos(), m, enclScope)) {
        enclScope.enter(m);
    }
    annotateLater(tree.mods.annotations, localEnv, m, tree.pos());
    // Visit the signature of the method. Note that
    // TypeAnnotate doesn't descend into the body.
    typeAnnotate(tree, localEnv, m, tree.pos());
    if (tree.defaultValue != null)
        annotateDefaultValueLater(tree.defaultValue, localEnv, m);
}
Also used : DiagnosticPosition(org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition)

Example 4 with DiagnosticPosition

use of org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition in project ceylon by eclipse.

the class Attr method visitConditional.

public void visitConditional(JCConditional tree) {
    Type condtype = attribExpr(tree.cond, env, syms.booleanType);
    tree.polyKind = (!allowPoly || pt().hasTag(NONE) && pt() != Type.recoveryType || isBooleanOrNumeric(env, tree)) ? PolyKind.STANDALONE : PolyKind.POLY;
    if (tree.polyKind == PolyKind.POLY && resultInfo.pt.hasTag(VOID)) {
        // cannot get here (i.e. it means we are returning from void method - which is already an error)
        resultInfo.checkContext.report(tree, diags.fragment("conditional.target.cant.be.void"));
        result = tree.type = types.createErrorType(resultInfo.pt);
        return;
    }
    ResultInfo condInfo = tree.polyKind == PolyKind.STANDALONE ? unknownExprInfo : resultInfo.dup(new Check.NestedCheckContext(resultInfo.checkContext) {

        // this will use enclosing check context to check compatibility of
        // subexpression against target type; if we are in a method check context,
        // depending on whether boxing is allowed, we could have incompatibilities
        @Override
        public void report(DiagnosticPosition pos, JCDiagnostic details) {
            enclosingContext.report(pos, diags.fragment("incompatible.type.in.conditional", details));
        }
    });
    Type truetype = attribTree(tree.truepart, env, condInfo);
    Type falsetype = attribTree(tree.falsepart, env, condInfo);
    Type owntype = (tree.polyKind == PolyKind.STANDALONE) ? condType(tree, truetype, falsetype) : pt();
    if (condtype.constValue() != null && truetype.constValue() != null && falsetype.constValue() != null && !owntype.hasTag(NONE)) {
        // constant folding
        owntype = cfolder.coerce(condtype.isTrue() ? truetype : falsetype, owntype);
    }
    result = check(tree, owntype, VAL, resultInfo);
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) DiagnosticPosition(org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition)

Example 5 with DiagnosticPosition

use of org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition in project ceylon by eclipse.

the class Attr method selectSym.

/*
    // Added by Ceylon
    private Symbol resolveIndyCall(JCTree tree,
                                   JCExpression indyReturnTypeExpression, List<JCExpression> indyParameterTypeExpressions,
                                   Name indyName,
                                   JCExpression bsmType, Name bsmName, List<Object> bsmStatic, 
                                   List<Type> parameterTypes){
        // build the list of static bsm arguments
        List<Type> bsm_staticArgs = List.of(syms.methodHandleLookupType,
                syms.stringType,
                syms.methodTypeType).appendList(bsmStaticArgToTypes(bsmStatic));

        // find the type of the bootstrap method class
        Type bsmSite = attribTree(bsmType, env, TYP, Infer.anyPoly);

        // find the bsm method
        Symbol bsm = rs.resolveInternalMethod(tree.pos(), env, bsmSite,
                                              bsmName, bsm_staticArgs, List.<Type>nil());

        if(!bsm.isStatic())
            log.error(tree.pos(), "ceylon", "Bootstrap method must be static: " + bsmName.toString());
        
        // find the type of the indy call
        Type indyReturnType = attribTree(indyReturnTypeExpression, env, TYP, Infer.anyPoly);
        ListBuffer<Type> indyParameterTypes = new ListBuffer<Type>();
        int c=0;
        List<Type> givenParameterTypes = parameterTypes;
        for(JCExpression expectedParamTypeExpr : indyParameterTypeExpressions){
            // also check that the parameter types we are passing to the method are compatible with the declared type
            Type givenParameterType = givenParameterTypes.head;
            if(givenParameterType == null) {
                log.error(tree.pos(), "ceylon", "Indy declared method expects more parameters than given. Expecting " + indyParameterTypeExpressions.size()
                        + ", but given " + c);
                return syms.errSymbol;
            }
            Type paramType = attribTree(expectedParamTypeExpr, env, TYP, Infer.anyPoly);
            if(!types.isAssignable(givenParameterType, paramType)) {
                log.error(tree.pos(), "ceylon", "Indy given method parameter "+c+" not compatible with expected parameter type: " + paramType
                        + ", but given " + givenParameterType);
                return syms.errSymbol;
            }
            indyParameterTypes.append(paramType);
            c++;
            givenParameterTypes = givenParameterTypes.tail;
        }
        if(!givenParameterTypes.isEmpty()) {
            log.error(tree.pos(), "ceylon", "Indy declared method expects less parameters than given. Expecting " + indyParameterTypeExpressions.size()
                    + ", but given " + parameterTypes.size());
            return syms.errSymbol;
        }
        
        MethodType indyType = new MethodType(indyParameterTypes.toList(), indyReturnType, List.<Type>nil(), syms.methodClass);
        
        // make an indy symbol for it
        DynamicMethodSymbol dynSym =
                new DynamicMethodSymbol(indyName,
                                        syms.noSymbol,
                                        bsm.isStatic() ?
                                            ClassFile.REF_invokeStatic :
                                            ClassFile.REF_invokeVirtual,
                                        (MethodSymbol)bsm,
                                        indyType,
                                        bsmStatic.toArray());
        return dynSym;
    }
    */
// where
/**
 * Determine symbol referenced by a Select expression,
 *
 *  @param tree   The select tree.
 *  @param site   The type of the selected expression,
 *  @param env    The current environment.
 *  @param resultInfo The current result.
 */
private Symbol selectSym(JCFieldAccess tree, Symbol location, Type site, Env<AttrContext> env, ResultInfo resultInfo) {
    DiagnosticPosition pos = tree.pos();
    Name name = tree.name;
    switch(site.getTag()) {
        case PACKAGE:
            return rs.accessBase(rs.findIdentInPackage(env, site.tsym, name, resultInfo.pkind), pos, location, site, name, true);
        case ARRAY:
        case CLASS:
            if (resultInfo.pt.hasTag(METHOD) || resultInfo.pt.hasTag(FORALL)) {
                return rs.resolveQualifiedMethod(pos, env, location, site, name, resultInfo.pt.getParameterTypes(), resultInfo.pt.getTypeArguments());
            } else if (name == names._this || name == names._super) {
                return rs.resolveSelf(pos, env, site.tsym, name);
            } else if (name == names._class) {
                // In this case, we have already made sure in
                // visitSelect that qualifier expression is a type.
                Type t = syms.classType;
                List<Type> typeargs = allowGenerics ? List.of(types.erasure(site)) : List.<Type>nil();
                t = new ClassType(t.getEnclosingType(), typeargs, t.tsym);
                return new VarSymbol(STATIC | PUBLIC | FINAL, names._class, t, site.tsym);
            } else {
                // We are seeing a plain identifier as selector.
                Symbol sym = rs.findIdentInType(env, site, name, resultInfo.pkind);
                if ((resultInfo.pkind & Kinds.ERRONEOUS) == 0)
                    sym = rs.accessBase(sym, pos, location, site, name, true);
                return sym;
            }
        case WILDCARD:
            throw new AssertionError(tree);
        case TYPEVAR:
            // Normally, site.getUpperBound() shouldn't be null.
            // It should only happen during memberEnter/attribBase
            // when determining the super type which *must* beac
            // done before attributing the type variables.  In
            // other words, we are seeing this illegal program:
            // class B<T> extends A<T.foo> {}
            Symbol sym = (site.getUpperBound() != null) ? selectSym(tree, location, capture(site.getUpperBound()), env, resultInfo) : null;
            if (sym == null) {
                log.error(pos, "type.var.cant.be.deref");
                return syms.errSymbol;
            } else {
                // Ceylon: relax the rules for private methods in wildcards, damnit, we want the private
                // method to be called, not any subtype's method we can't possibly know about, this is really
                // a lame Java decision.
                Symbol sym2 = (!sourceLanguage.isCeylon() && (sym.flags() & Flags.PRIVATE) != 0) ? rs.new AccessError(env, site, sym) : sym;
                rs.accessBase(sym2, pos, location, site, name, true);
                return sym;
            }
        case ERROR:
            // preserve identifier names through errors
            return types.createErrorType(name, site.tsym, site).tsym;
        default:
            // .class is allowed for these.
            if (name == names._class) {
                // In this case, we have already made sure in Select that
                // qualifier expression is a type.
                Type t = syms.classType;
                Type arg = types.boxedClass(site).type;
                t = new ClassType(t.getEnclosingType(), List.of(arg), t.tsym);
                return new VarSymbol(STATIC | PUBLIC | FINAL, names._class, t, site.tsym);
            } else {
                log.error(pos, "cant.deref", site);
                return syms.errSymbol;
            }
    }
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) DiagnosticPosition(org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol)

Aggregations

DiagnosticPosition (org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition)13 Type (org.eclipse.ceylon.langtools.tools.javac.code.Type)7 Symbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol)4 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)3 HashSet (java.util.HashSet)1 JavaFileObject (org.eclipse.ceylon.javax.tools.JavaFileObject)1 CheckContext (org.eclipse.ceylon.langtools.tools.javac.comp.Check.CheckContext)1 FreeTypeListener (org.eclipse.ceylon.langtools.tools.javac.comp.Infer.FreeTypeListener)1 InferenceContext (org.eclipse.ceylon.langtools.tools.javac.comp.Infer.InferenceContext)1