Search in sources :

Example 1 with MethodSymbol

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

the class LambdaToMethod method makeMetafactoryIndyCall.

/**
 * Generate an indy method call to the meta factory
 */
private JCExpression makeMetafactoryIndyCall(LambdaAnalyzerPreprocessor.TranslationContext<?> context, int refKind, Symbol refSym, List<JCExpression> indy_args) {
    JCFunctionalExpression tree = context.tree;
    // determine the static bsm args
    MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym);
    List<Object> staticArgs = List.<Object>of(typeToMethodType(samSym.type), new Pool.MethodHandle(refKind, refSym, types), typeToMethodType(tree.getDescriptorType(types)));
    // computed indy arg types
    ListBuffer<Type> indy_args_types = new ListBuffer<>();
    for (JCExpression arg : indy_args) {
        indy_args_types.append(arg.type);
    }
    // finally, compute the type of the indy call
    MethodType indyType = new MethodType(indy_args_types.toList(), tree.type, List.<Type>nil(), syms.methodClass);
    Name metafactoryName = context.needsAltMetafactory() ? names.altMetafactory : names.metafactory;
    if (context.needsAltMetafactory()) {
        ListBuffer<Object> markers = new ListBuffer<>();
        for (Type t : tree.targets.tail) {
            if (t.tsym != syms.serializableType.tsym) {
                markers.append(t.tsym);
            }
        }
        int flags = context.isSerializable() ? FLAG_SERIALIZABLE : 0;
        boolean hasMarkers = markers.nonEmpty();
        boolean hasBridges = context.bridges.nonEmpty();
        if (hasMarkers) {
            flags |= FLAG_MARKERS;
        }
        if (hasBridges) {
            flags |= FLAG_BRIDGES;
        }
        staticArgs = staticArgs.append(flags);
        if (hasMarkers) {
            staticArgs = staticArgs.append(markers.length());
            staticArgs = staticArgs.appendList(markers.toList());
        }
        if (hasBridges) {
            staticArgs = staticArgs.append(context.bridges.length() - 1);
            for (Symbol s : context.bridges) {
                Type s_erasure = s.erasure(types);
                if (!types.isSameType(s_erasure, samSym.erasure(types))) {
                    staticArgs = staticArgs.append(s.erasure(types));
                }
            }
        }
        if (context.isSerializable()) {
            int prevPos = make.pos;
            try {
                make.at(kInfo.clazz);
                addDeserializationCase(refKind, refSym, tree.type, samSym, tree, staticArgs, indyType);
            } finally {
                make.at(prevPos);
            }
        }
    }
    return makeIndyCall(tree, syms.lambdaMetafactory, metafactoryName, staticArgs, indyType, indy_args, samSym.name);
}
Also used : MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) VarSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.VarSymbol) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) TypeSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol) DynamicMethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.DynamicMethodSymbol) ClassSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol) MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) DynamicMethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.DynamicMethodSymbol)

Example 2 with MethodSymbol

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

the class CeylonModelLoader method implemented.

/**
 * Copied from MethodSymbol.implemented and adapted for ignoring methods
 */
private Symbol implemented(MethodSymbol m, TypeSymbol c, Types types) {
    Symbol impl = null;
    for (List<Type> is = types.interfaces(c.type); impl == null && is.nonEmpty(); is = is.tail) {
        TypeSymbol i = is.head.tsym;
        impl = implementedIn(m, i, types);
        if (impl == null)
            impl = implemented(m, i, types);
    }
    return impl;
}
Also used : MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ArrayType(org.eclipse.ceylon.langtools.tools.javac.code.Type.ArrayType) JavacType(org.eclipse.ceylon.compiler.java.loader.mirror.JavacType) FunctionalInterfaceType(org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) TypeSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol) ClassSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) PackageSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.PackageSymbol) TypeSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol)

Example 3 with MethodSymbol

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

the class CeylonModelLoader method isOverloadingMethod.

/**
 * Returns true if the given method is overloading an inherited method (from super class or interfaces).
 */
private boolean isOverloadingMethod(final MethodSymbol method) {
    /*
         * Copied from getOverriddenMethod and adapted for overloading
         */
    try {
        // interfaces have a different way to work
        if (method.owner.isInterface())
            return overloaded(method, method.owner.type.tsym, types);
        // so we stop there for it, especially since it does not have any overloading
        if (method.owner.type.tsym.getQualifiedName().toString().equals("ceylon.language.Exception"))
            return false;
        for (Type superType = types.supertype(method.owner.type); superType.tsym != null; superType = types.supertype(superType)) {
            TypeSymbol i = superType.tsym;
            String fqn = i.getQualifiedName().toString();
            // never go above this type since it has no supertype in Ceylon (does in Java though)
            if (fqn.equals("ceylon.language.Anything"))
                break;
            try {
                for (Entry e = i.members().lookup(method.name); e.scope != null; e = e.next()) {
                    // ignore some methods
                    if (isIgnored(e.sym))
                        continue;
                    if (!method.overrides(e.sym, (TypeSymbol) method.owner, types, false)) {
                        return true;
                    }
                }
                // try in the interfaces
                if (overloaded(method, i, types))
                    return true;
            } catch (Symbol.CompletionFailure x) {
            // just ignore unresolved interfaces, error will be logged when we try to add it
            }
            // so we stop there for it, especially since it does not have any overloading
            if (fqn.equals("ceylon.language.Exception"))
                break;
        }
        // try in the interfaces
        if (overloaded(method, method.owner.type.tsym, types))
            return true;
        return false;
    } catch (CompletionFailure x) {
        handleCompletionFailure(method, x);
        return false;
    }
}
Also used : MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ArrayType(org.eclipse.ceylon.langtools.tools.javac.code.Type.ArrayType) JavacType(org.eclipse.ceylon.compiler.java.loader.mirror.JavacType) FunctionalInterfaceType(org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType) Entry(org.eclipse.ceylon.langtools.tools.javac.code.Scope.Entry) CompletionFailure(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.CompletionFailure) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) TypeSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol) ClassSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) PackageSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.PackageSymbol) CompletionFailure(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.CompletionFailure) TypeSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol)

Example 4 with MethodSymbol

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

the class CeylonModelLoader method getFunctionalInterfaceType.

@Override
protected FunctionalInterfaceType getFunctionalInterfaceType(TypeMirror typeMirror) throws ModelResolutionException {
    if (typeMirror.getKind() != TypeKind.DECLARED)
        throw new ModelResolutionException("Failed to find functional interface type in " + typeMirror);
    // FIXME: possibly apply other optimisations to lighten the lookup cost? see what javac does
    Type type = ((JavacType) typeMirror).type;
    try {
        Type descriptorType = types.findDescriptorType(type);
        // Let's be honest I've no idea what this means, but it happens and Javac seems to refuse it too
        if (descriptorType.hasTag(TypeTag.FORALL))
            throw new ModelResolutionException("Failed to find functional interface type in " + typeMirror);
        MethodType methodDescriptorType = (MethodType) descriptorType;
        MethodSymbol methodSymbol = (MethodSymbol) types.findDescriptorSymbol(type.tsym);
        List<Type> parameterTypes = methodDescriptorType.getParameterTypes();
        ListBuffer<TypeMirror> mirrorParameterTypes = new ListBuffer<>();
        for (int i = 0; i < parameterTypes.size(); i++) {
            Type parameterType = parameterTypes.get(i);
            if (methodSymbol.isVarArgs() && i == parameterTypes.size() - 1)
                parameterType = ((ArrayType) parameterType).getComponentType();
            mirrorParameterTypes.add(new JavacType(parameterType));
        }
        return new FunctionalInterfaceType(new JavacMethod(new JavacClass(methodSymbol.enclClass()), methodSymbol), new JavacType(methodDescriptorType.getReturnType()), mirrorParameterTypes.toList(), methodSymbol.isVarArgs());
    } catch (Symbol.CompletionFailure err) {
        // bad luck
        throw new ModelResolutionException("Failed to find functional interface type in " + typeMirror, err);
    } catch (FunctionDescriptorLookupError err) {
        throw new ModelResolutionException("Failed to find functional interface type in " + typeMirror, err);
    }
}
Also used : JavacType(org.eclipse.ceylon.compiler.java.loader.mirror.JavacType) MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) FunctionalInterfaceType(org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType) JavacMethod(org.eclipse.ceylon.compiler.java.loader.mirror.JavacMethod) CompletionFailure(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.CompletionFailure) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) TypeSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol) ClassSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) PackageSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.PackageSymbol) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) ArrayType(org.eclipse.ceylon.langtools.tools.javac.code.Type.ArrayType) ModelResolutionException(org.eclipse.ceylon.model.loader.ModelResolutionException) MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ArrayType(org.eclipse.ceylon.langtools.tools.javac.code.Type.ArrayType) JavacType(org.eclipse.ceylon.compiler.java.loader.mirror.JavacType) FunctionalInterfaceType(org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) TypeMirror(org.eclipse.ceylon.model.loader.mirror.TypeMirror) JavacClass(org.eclipse.ceylon.compiler.java.loader.mirror.JavacClass) FunctionDescriptorLookupError(org.eclipse.ceylon.langtools.tools.javac.code.Types.FunctionDescriptorLookupError)

Example 5 with MethodSymbol

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

the class JavacClass method getDirectMethods.

@Override
public List<MethodMirror> getDirectMethods() {
    if (methods == null) {
        List<MethodMirror> ret = new LinkedList<MethodMirror>();
        for (Symbol sym : classSymbol.getEnclosedElements()) {
            if (sym instanceof MethodSymbol && (sym.flags() & Flags.PRIVATE) == 0) {
                ret.add(new JavacMethod(this, (MethodSymbol) sym));
            }
        }
        methods = Collections.unmodifiableList(ret);
    }
    return methods;
}
Also used : MethodMirror(org.eclipse.ceylon.model.loader.mirror.MethodMirror) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) VarSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.VarSymbol) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) ClassSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol) LinkedList(java.util.LinkedList)

Aggregations

ClassSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol)11 MethodSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol)11 Symbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol)10 TypeSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol)8 Type (org.eclipse.ceylon.langtools.tools.javac.code.Type)8 MethodType (org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType)8 ArrayType (org.eclipse.ceylon.langtools.tools.javac.code.Type.ArrayType)6 JavacType (org.eclipse.ceylon.compiler.java.loader.mirror.JavacType)5 PackageSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.PackageSymbol)5 VarSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.VarSymbol)5 FunctionalInterfaceType (org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType)5 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)5 CompletionFailure (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.CompletionFailure)4 DynamicMethodSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.DynamicMethodSymbol)3 FunctionDescriptorLookupError (org.eclipse.ceylon.langtools.tools.javac.code.Types.FunctionDescriptorLookupError)3 LinkedList (java.util.LinkedList)1 JavacClass (org.eclipse.ceylon.compiler.java.loader.mirror.JavacClass)1 JavacMethod (org.eclipse.ceylon.compiler.java.loader.mirror.JavacMethod)1 DeclaredType (org.eclipse.ceylon.javax.lang.model.type.DeclaredType)1 Scope (org.eclipse.ceylon.langtools.source.tree.Scope)1