Search in sources :

Example 26 with Symbol

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

the class Resolve method findInheritedMemberType.

/**
 * Find a member type inherited from a superclass or interface.
 *  @param env       The current environment.
 *  @param site      The original type from where the selection takes
 *                   place.
 *  @param name      The type's name.
 *  @param c         The class to search for the member type. This is
 *                   always a superclass or implemented interface of
 *                   site's class.
 */
Symbol findInheritedMemberType(Env<AttrContext> env, Type site, Name name, TypeSymbol c) {
    Symbol bestSoFar = typeNotFound;
    Symbol sym;
    Type st = types.supertype(c.type);
    if (st != null && st.hasTag(CLASS)) {
        sym = findMemberType(env, site, name, st.tsym);
        if (sym.kind < bestSoFar.kind)
            bestSoFar = sym;
    }
    for (List<Type> l = types.interfaces(c.type); bestSoFar.kind != AMBIGUOUS && l.nonEmpty(); l = l.tail) {
        sym = findMemberType(env, site, name, l.head.tsym);
        if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
            bestSoFar = new AmbiguityError(bestSoFar, sym);
        else if (sym.kind < bestSoFar.kind)
            bestSoFar = sym;
    }
    return bestSoFar;
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) DeferredType(org.eclipse.ceylon.langtools.tools.javac.comp.DeferredAttr.DeferredType) DiagnosticType(org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticType) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol)

Example 27 with Symbol

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

the class Resolve method findIdentInType.

/**
 * Find an identifier among the members of a given type `site'.
 *  @param env       The current environment.
 *  @param site      The type containing the symbol to be found.
 *  @param name      The identifier's name.
 *  @param kind      Indicates the possible symbol kinds
 *                   (a subset of VAL, TYP).
 */
Symbol findIdentInType(Env<AttrContext> env, Type site, Name name, int kind) {
    Symbol bestSoFar = typeNotFound;
    Symbol sym;
    if ((kind & VAR) != 0) {
        sym = findField(env, site, name, site.tsym);
        if (sym.exists())
            return sym;
        else if (sym.kind < bestSoFar.kind)
            bestSoFar = sym;
    }
    if ((kind & TYP) != 0) {
        sym = findMemberType(env, site, name, site.tsym);
        if (sym.exists())
            return sym;
        else if (sym.kind < bestSoFar.kind)
            bestSoFar = sym;
    }
    return bestSoFar;
}
Also used : Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol)

Example 28 with Symbol

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

the class Resolve method mostSpecific.

/* Return the most specific of the two methods for a call,
     *  given that both are accessible and applicable.
     *  @param m1               A new candidate for most specific.
     *  @param m2               The previous most specific candidate.
     *  @param env              The current environment.
     *  @param site             The original type from where the selection
     *                          takes place.
     *  @param allowBoxing Allow boxing conversions of arguments.
     *  @param useVarargs Box trailing arguments into an array for varargs.
     */
Symbol mostSpecific(List<Type> argtypes, Symbol m1, Symbol m2, Env<AttrContext> env, final Type site, boolean allowBoxing, boolean useVarargs) {
    switch(m2.kind) {
        case MTH:
            if (m1 == m2)
                return m1;
            boolean m1SignatureMoreSpecific = signatureMoreSpecific(argtypes, env, site, m1, m2, allowBoxing, useVarargs);
            boolean m2SignatureMoreSpecific = signatureMoreSpecific(argtypes, env, site, m2, m1, allowBoxing, useVarargs);
            if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
                Type mt1 = types.memberType(site, m1);
                Type mt2 = types.memberType(site, m2);
                if (!types.overrideEquivalent(mt1, mt2))
                    return ambiguityError(m1, m2);
                // one, or (d) merge both abstract signatures
                if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
                    return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
                // if one overrides or hides the other, use it
                TypeSymbol m1Owner = (TypeSymbol) m1.owner;
                TypeSymbol m2Owner = (TypeSymbol) m2.owner;
                if (types.asSuper(m1Owner.type, m2Owner) != null && ((m1.owner.flags_field & INTERFACE) == 0 || (m2.owner.flags_field & INTERFACE) != 0) && m1.overrides(m2, m1Owner, types, false))
                    return m1;
                if (types.asSuper(m2Owner.type, m1Owner) != null && ((m2.owner.flags_field & INTERFACE) == 0 || (m1.owner.flags_field & INTERFACE) != 0) && m2.overrides(m1, m2Owner, types, false))
                    return m2;
                boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
                boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
                if (m1Abstract && !m2Abstract)
                    return m2;
                if (m2Abstract && !m1Abstract)
                    return m1;
                // both abstract or both concrete
                return ambiguityError(m1, m2);
            }
            if (m1SignatureMoreSpecific)
                return m1;
            if (m2SignatureMoreSpecific)
                return m2;
            return ambiguityError(m1, m2);
        case AMBIGUOUS:
            // compare m1 to ambiguous methods in m2
            AmbiguityError e = (AmbiguityError) m2.baseSymbol();
            boolean m1MoreSpecificThanAnyAmbiguous = true;
            boolean allAmbiguousMoreSpecificThanM1 = true;
            for (Symbol s : e.ambiguousSyms) {
                Symbol moreSpecific = mostSpecific(argtypes, m1, s, env, site, allowBoxing, useVarargs);
                m1MoreSpecificThanAnyAmbiguous &= moreSpecific == m1;
                allAmbiguousMoreSpecificThanM1 &= moreSpecific == s;
            }
            if (m1MoreSpecificThanAnyAmbiguous)
                return m1;
            // more specific than m1, add it as a new ambiguous method:
            if (!allAmbiguousMoreSpecificThanM1)
                e.addAmbiguousSymbol(m1);
            return e;
        default:
            throw new AssertionError();
    }
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) DeferredType(org.eclipse.ceylon.langtools.tools.javac.comp.DeferredAttr.DeferredType) DiagnosticType(org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticType) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol)

Example 29 with Symbol

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

the class Annotate method enterAttributeValue.

Attribute enterAttributeValue(Type expected, JCExpression tree, Env<AttrContext> env) {
    // ordinary resolution diagnostic.
    try {
        expected.tsym.complete();
    } catch (CompletionFailure e) {
        log.error(tree.pos(), "cant.resolve", Kinds.kindName(e.sym), e.sym);
        expected = syms.errType;
    }
    if (expected.hasTag(ARRAY)) {
        if (!tree.hasTag(NEWARRAY)) {
            tree = make.at(tree.pos).NewArray(null, List.<JCExpression>nil(), List.of(tree));
        }
        JCNewArray na = (JCNewArray) tree;
        if (na.elemtype != null) {
            log.error(na.elemtype.pos(), "new.not.allowed.in.annotation");
        }
        ListBuffer<Attribute> buf = new ListBuffer<Attribute>();
        for (List<JCExpression> l = na.elems; l.nonEmpty(); l = l.tail) {
            buf.append(enterAttributeValue(types.elemtype(expected), l.head, env));
        }
        na.type = expected;
        return new Attribute.Array(expected, buf.toArray(new Attribute[buf.length()]));
    }
    if (tree.hasTag(NEWARRAY)) {
        // error recovery
        if (!expected.isErroneous())
            log.error(tree.pos(), "annotation.value.not.allowable.type");
        JCNewArray na = (JCNewArray) tree;
        if (na.elemtype != null) {
            log.error(na.elemtype.pos(), "new.not.allowed.in.annotation");
        }
        for (List<JCExpression> l = na.elems; l.nonEmpty(); l = l.tail) {
            enterAttributeValue(syms.errType, l.head, env);
        }
        return new Attribute.Error(syms.errType);
    }
    if ((expected.tsym.flags() & Flags.ANNOTATION) != 0) {
        if (tree.hasTag(ANNOTATION)) {
            return enterAnnotation((JCAnnotation) tree, expected, env);
        } else {
            log.error(tree.pos(), "annotation.value.must.be.annotation");
            expected = syms.errType;
        }
    }
    if (tree.hasTag(ANNOTATION)) {
        // error recovery
        if (!expected.isErroneous())
            log.error(tree.pos(), "annotation.not.valid.for.type", expected);
        enterAnnotation((JCAnnotation) tree, syms.errType, env);
        return new Attribute.Error(((JCAnnotation) tree).annotationType.type);
    }
    if (expected.isPrimitive() || types.isSameType(expected, syms.stringType)) {
        Type result = attr.attribExpr(tree, env, expected);
        if (result.isErroneous())
            return new Attribute.Error(result.getOriginalType());
        if (result.constValue() == null) {
            log.error(tree.pos(), "attribute.value.must.be.constant");
            return new Attribute.Error(expected);
        }
        result = cfolder.coerce(result, expected);
        return new Attribute.Constant(expected, result.constValue());
    }
    if (expected.tsym == syms.classType.tsym) {
        Type result = attr.attribExpr(tree, env, expected);
        if (result.isErroneous()) {
            // Does it look like an unresolved class literal?
            if (TreeInfo.name(tree) == names._class && ((JCFieldAccess) tree).selected.type.isErroneous()) {
                Name n = (((JCFieldAccess) tree).selected).type.tsym.flatName();
                return new Attribute.UnresolvedClass(expected, types.createErrorType(n, syms.unknownSymbol, syms.classType));
            } else {
                return new Attribute.Error(result.getOriginalType());
            }
        }
        // at the tree level
        if (TreeInfo.name(tree) != names._class) {
            log.error(tree.pos(), "annotation.value.must.be.class.literal");
            return new Attribute.Error(syms.errType);
        }
        return new Attribute.Class(types, (((JCFieldAccess) tree).selected).type);
    }
    if (expected.hasTag(CLASS) && (expected.tsym.flags() & Flags.ENUM) != 0) {
        Type result = attr.attribExpr(tree, env, expected);
        Symbol sym = TreeInfo.symbol(tree);
        if (sym == null || TreeInfo.nonstaticSelect(tree) || sym.kind != Kinds.VAR || (sym.flags() & Flags.ENUM) == 0) {
            log.error(tree.pos(), "enum.annotation.must.be.enum.constant");
            return new Attribute.Error(result.getOriginalType());
        }
        VarSymbol enumerator = (VarSymbol) sym;
        return new Attribute.Enum(expected, enumerator);
    }
    // error recovery:
    if (!expected.isErroneous())
        log.error(tree.pos(), "annotation.value.not.allowable.type");
    return new Attribute.Error(attr.attribExpr(tree, env, expected));
}
Also used : Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) ErrorType(org.eclipse.ceylon.javax.lang.model.type.ErrorType)

Example 30 with Symbol

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

the class Annotate method validateContainer.

/* Validate that the suggested targetContainerType Type is a valid
     * container type for repeated instances of originalAnnoType
     * annotations. Return null and report errors if this is not the
     * case, return the MethodSymbol of the value element in
     * targetContainerType if it is suitable (this is needed to
     * synthesize the container). */
private MethodSymbol validateContainer(Type targetContainerType, Type originalAnnoType, DiagnosticPosition pos) {
    MethodSymbol containerValueSymbol = null;
    boolean fatalError = false;
    // Validate that there is a (and only 1) value method
    Scope scope = targetContainerType.tsym.members();
    int nr_value_elems = 0;
    boolean error = false;
    for (Symbol elm : scope.getElementsByName(names.value)) {
        nr_value_elems++;
        if (nr_value_elems == 1 && elm.kind == Kinds.MTH) {
            containerValueSymbol = (MethodSymbol) elm;
        } else {
            error = true;
        }
    }
    if (error) {
        log.error(pos, "invalid.repeatable.annotation.multiple.values", targetContainerType, nr_value_elems);
        return null;
    } else if (nr_value_elems == 0) {
        log.error(pos, "invalid.repeatable.annotation.no.value", targetContainerType);
        return null;
    }
    // probably "impossible" to fail this
    if (containerValueSymbol.kind != Kinds.MTH) {
        log.error(pos, "invalid.repeatable.annotation.invalid.value", targetContainerType);
        fatalError = true;
    }
    // validate that the 'value' element has the correct return type
    // i.e. array of original anno
    Type valueRetType = containerValueSymbol.type.getReturnType();
    Type expectedType = types.makeArrayType(originalAnnoType);
    if (!(types.isArray(valueRetType) && types.isSameType(expectedType, valueRetType))) {
        log.error(pos, "invalid.repeatable.annotation.value.return", targetContainerType, valueRetType, expectedType);
        fatalError = true;
    }
    if (error) {
        fatalError = true;
    }
    return fatalError ? null : containerValueSymbol;
}
Also used : ErrorType(org.eclipse.ceylon.javax.lang.model.type.ErrorType) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol)

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