Search in sources :

Example 6 with MethodSymbol

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

the class JavacClass method getEnclosingMethod.

@Override
public MethodMirror getEnclosingMethod() {
    if (!enclosingMethodSet) {
        Symbol encl = classSymbol.getEnclosingElement();
        if (encl != null && encl instanceof MethodSymbol) {
            // it's a method, it must be in a Class
            ClassSymbol enclosingClass = (ClassSymbol) encl.getEnclosingElement();
            JavacClass enclosingClassMirror = new JavacClass(enclosingClass);
            enclosingMethod = new JavacMethod(enclosingClassMirror, (MethodSymbol) encl);
        }
        enclosingMethodSet = true;
    }
    return enclosingMethod;
}
Also used : 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) ClassSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol)

Example 7 with MethodSymbol

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

the class LambdaToMethod method makeIndyCall.

/**
 * Generate an indy method call with given name, type and static bootstrap
 * arguments types
 */
private JCExpression makeIndyCall(DiagnosticPosition pos, Type site, Name bsmName, List<Object> staticArgs, MethodType indyType, List<JCExpression> indyArgs, Name methName) {
    int prevPos = make.pos;
    try {
        make.at(pos);
        List<Type> bsm_staticArgs = List.of(syms.methodHandleLookupType, syms.stringType, syms.methodTypeType).appendList(bsmStaticArgToTypes(staticArgs));
        Symbol bsm = rs.resolveInternalMethod(pos, attrEnv, site, bsmName, bsm_staticArgs, List.<Type>nil());
        DynamicMethodSymbol dynSym = new DynamicMethodSymbol(methName, syms.noSymbol, bsm.isStatic() ? ClassFile.REF_invokeStatic : ClassFile.REF_invokeVirtual, (MethodSymbol) bsm, indyType, staticArgs.toArray());
        JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), bsmName);
        qualifier.sym = dynSym;
        qualifier.type = indyType.getReturnType();
        JCMethodInvocation proxyCall = make.Apply(List.<JCExpression>nil(), qualifier, indyArgs);
        proxyCall.type = indyType.getReturnType();
        return proxyCall;
    } finally {
        make.at(prevPos);
    }
}
Also used : MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) 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) DynamicMethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.DynamicMethodSymbol)

Example 8 with MethodSymbol

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

the class LambdaToMethod method visitLambda.

/**
 * Translate a lambda into a method to be inserted into the class.
 * Then replace the lambda site with an invokedynamic call of to lambda
 * meta-factory, which will use the lambda method.
 * @param tree
 */
@Override
public void visitLambda(JCLambda tree) {
    LambdaAnalyzerPreprocessor.LambdaTranslationContext localContext = (LambdaAnalyzerPreprocessor.LambdaTranslationContext) context;
    MethodSymbol sym = localContext.translatedSym;
    MethodType lambdaType = (MethodType) sym.type;
    {
        Symbol owner = localContext.owner;
        ListBuffer<Attribute.TypeCompound> ownerTypeAnnos = new ListBuffer<Attribute.TypeCompound>();
        ListBuffer<Attribute.TypeCompound> lambdaTypeAnnos = new ListBuffer<Attribute.TypeCompound>();
        for (Attribute.TypeCompound tc : owner.getRawTypeAttributes()) {
            if (tc.position.onLambda == tree) {
                lambdaTypeAnnos.append(tc);
            } else {
                ownerTypeAnnos.append(tc);
            }
        }
        if (lambdaTypeAnnos.nonEmpty()) {
            owner.setTypeAttributes(ownerTypeAnnos.toList());
            sym.setTypeAttributes(lambdaTypeAnnos.toList());
        }
    }
    // create the method declaration hoisting the lambda body
    JCMethodDecl lambdaDecl = make.MethodDef(make.Modifiers(sym.flags_field), sym.name, make.QualIdent(lambdaType.getReturnType().tsym), List.<JCTypeParameter>nil(), localContext.syntheticParams, lambdaType.getThrownTypes() == null ? List.<JCExpression>nil() : make.Types(lambdaType.getThrownTypes()), null, null);
    lambdaDecl.sym = sym;
    lambdaDecl.type = lambdaType;
    // translate lambda body
    // As the lambda body is translated, all references to lambda locals,
    // captured variables, enclosing members are adjusted accordingly
    // to refer to the static method parameters (rather than i.e. acessing to
    // captured members directly).
    lambdaDecl.body = translate(makeLambdaBody(tree, lambdaDecl));
    // Add the method to the list of methods to be added to this class.
    kInfo.addMethod(lambdaDecl);
    // now that we have generated a method for the lambda expression,
    // we can translate the lambda into a method reference pointing to the newly
    // created method.
    // 
    // Note that we need to adjust the method handle so that it will match the
    // signature of the SAM descriptor - this means that the method reference
    // should be added the following synthetic arguments:
    // 
    // * the "this" argument if it is an instance method
    // * enclosing locals captured by the lambda expression
    ListBuffer<JCExpression> syntheticInits = new ListBuffer<>();
    if (localContext.methodReferenceReceiver != null) {
        syntheticInits.append(localContext.methodReferenceReceiver);
    } else if (!sym.isStatic()) {
        syntheticInits.append(makeThis(sym.owner.enclClass().asType(), localContext.owner.enclClass()));
    }
    // add captured locals
    for (Symbol fv : localContext.getSymbolMap(CAPTURED_VAR).keySet()) {
        if (fv != localContext.self) {
            JCTree captured_local = make.Ident(fv).setType(fv.type);
            syntheticInits.append((JCExpression) captured_local);
        }
    }
    // then, determine the arguments to the indy call
    List<JCExpression> indy_args = translate(syntheticInits.toList(), localContext.prev);
    // build a sam instance using an indy call to the meta-factory
    int refKind = referenceKind(sym);
    // convert to an invokedynamic call
    result = makeMetafactoryIndyCall(context, refKind, sym, indy_args);
}
Also used : MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) LambdaAnalyzerPreprocessor(org.eclipse.ceylon.langtools.tools.javac.comp.LambdaToMethod.LambdaAnalyzerPreprocessor) Attribute(org.eclipse.ceylon.langtools.tools.javac.code.Attribute) 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) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) DynamicMethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.DynamicMethodSymbol)

Example 9 with MethodSymbol

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

the class CeylonModelLoader method isFunctionalInterface.

@Override
protected String isFunctionalInterface(ClassMirror klass) {
    Type type = ((JavacClass) klass).classSymbol.type;
    try {
        Type descriptorType = types.findDescriptorType(type);
        if (descriptorType == null)
            return null;
        // 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))
            return null;
        MethodSymbol descriptorSymbol = (MethodSymbol) types.findDescriptorSymbol(type.tsym);
        if (descriptorSymbol != null) {
            // make sure we don't treat ignored shit like impl accessors as SAM
            if (isIgnored(descriptorSymbol))
                return null;
            String name = descriptorSymbol.getSimpleName().toString();
            if (isGetter(descriptorSymbol)) {
                name = NamingBase.getJavaAttributeName(name);
            }
            return name;
        }
        return null;
    } catch (Symbol.CompletionFailure err) {
        // bad luck
        return null;
    } catch (FunctionDescriptorLookupError err) {
        return null;
    }
}
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) 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) FunctionDescriptorLookupError(org.eclipse.ceylon.langtools.tools.javac.code.Types.FunctionDescriptorLookupError)

Example 10 with MethodSymbol

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

the class CeylonModelLoader method isFunctionalInterfaceType.

@Override
protected boolean isFunctionalInterfaceType(TypeMirror typeMirror) {
    if (typeMirror.getKind() != TypeKind.DECLARED)
        return false;
    // 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))
            return false;
        MethodType methodDescriptorType = (MethodType) descriptorType;
        MethodSymbol methodSymbol = (MethodSymbol) types.findDescriptorSymbol(type.tsym);
        // make sure we can load them
        methodDescriptorType.complete();
        methodSymbol.complete();
        return true;
    } catch (Symbol.CompletionFailure err) {
        // bad luck
        return false;
    } catch (FunctionDescriptorLookupError err) {
        return false;
    }
}
Also used : JavacType(org.eclipse.ceylon.compiler.java.loader.mirror.JavacType) MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) 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) 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) FunctionDescriptorLookupError(org.eclipse.ceylon.langtools.tools.javac.code.Types.FunctionDescriptorLookupError)

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