Search in sources :

Example 1 with FunctionDeclaration

use of com.google.devtools.j2objc.ast.FunctionDeclaration in project j2objc by google.

the class Functionizer method makeFunction.

/**
   * Create an equivalent function declaration for a given method.
   */
private FunctionDeclaration makeFunction(MethodDeclaration method) {
    ExecutableElement elem = method.getExecutableElement();
    TypeElement declaringClass = ElementUtil.getDeclaringClass(elem);
    boolean isInstanceMethod = !ElementUtil.isStatic(elem) && !ElementUtil.isConstructor(elem);
    FunctionDeclaration function = new FunctionDeclaration(nameTable.getFullFunctionName(elem), elem.getReturnType());
    function.setJniSignature(signatureGenerator.createJniFunctionSignature(elem));
    function.setLineNumber(method.getLineNumber());
    if (!ElementUtil.isStatic(elem)) {
        VariableElement var = GeneratedVariableElement.newParameter(NameTable.SELF_NAME, declaringClass.asType(), null);
        function.addParameter(new SingleVariableDeclaration(var));
    }
    TreeUtil.copyList(method.getParameters(), function.getParameters());
    function.setModifiers(method.getModifiers() & Modifier.STATIC);
    if (ElementUtil.isPrivate(elem) || (isInstanceMethod && !ElementUtil.isDefault(elem))) {
        function.addModifiers(Modifier.PRIVATE);
    } else {
        function.addModifiers(Modifier.PUBLIC);
    }
    if (Modifier.isNative(method.getModifiers())) {
        function.addModifiers(Modifier.NATIVE);
        return function;
    }
    function.setBody(TreeUtil.remove(method.getBody()));
    if (ElementUtil.isStatic(elem)) {
        // Add class initialization invocation, since this may be the first use of this class.
        String initName = UnicodeUtils.format("%s_initialize", nameTable.getFullName(declaringClass));
        TypeMirror voidType = typeUtil.getVoid();
        FunctionElement initElement = new FunctionElement(initName, voidType, declaringClass);
        FunctionInvocation initCall = new FunctionInvocation(initElement, voidType);
        function.getBody().addStatement(0, new ExpressionStatement(initCall));
    } else {
        FunctionConverter.convert(function);
    }
    return function;
}
Also used : FunctionDeclaration(com.google.devtools.j2objc.ast.FunctionDeclaration) FunctionElement(com.google.devtools.j2objc.types.FunctionElement) FunctionInvocation(com.google.devtools.j2objc.ast.FunctionInvocation) TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement) SingleVariableDeclaration(com.google.devtools.j2objc.ast.SingleVariableDeclaration) GeneratedExecutableElement(com.google.devtools.j2objc.types.GeneratedExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ExpressionStatement(com.google.devtools.j2objc.ast.ExpressionStatement) GeneratedVariableElement(com.google.devtools.j2objc.types.GeneratedVariableElement) VariableElement(javax.lang.model.element.VariableElement)

Example 2 with FunctionDeclaration

use of com.google.devtools.j2objc.ast.FunctionDeclaration in project j2objc by google.

the class Functionizer method makeAllocatingConstructor.

/**
   * Create a wrapper for a constructor that does the object allocation.
   */
private FunctionDeclaration makeAllocatingConstructor(MethodDeclaration method, boolean releasing) {
    assert method.isConstructor();
    ExecutableElement element = method.getExecutableElement();
    TypeElement declaringClass = ElementUtil.getDeclaringClass(element);
    String name = releasing ? nameTable.getReleasingConstructorName(element) : nameTable.getAllocatingConstructorName(element);
    FunctionDeclaration function = new FunctionDeclaration(name, declaringClass.asType());
    function.setLineNumber(method.getLineNumber());
    function.setModifiers(ElementUtil.isPrivate(element) ? Modifier.PRIVATE : Modifier.PUBLIC);
    function.setReturnsRetained(!releasing);
    TreeUtil.copyList(method.getParameters(), function.getParameters());
    Block body = new Block();
    function.setBody(body);
    StringBuilder sb = new StringBuilder(releasing ? "J2OBJC_CREATE_IMPL(" : "J2OBJC_NEW_IMPL(");
    sb.append(nameTable.getFullName(declaringClass));
    sb.append(", ").append(nameTable.getFunctionName(element));
    for (SingleVariableDeclaration param : function.getParameters()) {
        sb.append(", ").append(nameTable.getVariableQualifiedName(param.getVariableElement()));
    }
    sb.append(")");
    body.addStatement(new NativeStatement(sb.toString()));
    return function;
}
Also used : FunctionDeclaration(com.google.devtools.j2objc.ast.FunctionDeclaration) NativeStatement(com.google.devtools.j2objc.ast.NativeStatement) TypeElement(javax.lang.model.element.TypeElement) SingleVariableDeclaration(com.google.devtools.j2objc.ast.SingleVariableDeclaration) GeneratedExecutableElement(com.google.devtools.j2objc.types.GeneratedExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Block(com.google.devtools.j2objc.ast.Block)

Example 3 with FunctionDeclaration

use of com.google.devtools.j2objc.ast.FunctionDeclaration in project j2objc by google.

the class Functionizer method endVisit.

@Override
public void endVisit(MethodDeclaration node) {
    ExecutableElement element = node.getExecutableElement();
    // they are added by the translator and need to remain in method form.
    if (!node.hasDeclaration()) {
        return;
    }
    boolean isConstructor = ElementUtil.isConstructor(element);
    boolean isInstanceMethod = !ElementUtil.isStatic(element) && !isConstructor;
    boolean isDefaultMethod = ElementUtil.isDefault(element);
    List<BodyDeclaration> declarationList = TreeUtil.asDeclarationSublist(node);
    if (!isInstanceMethod || isDefaultMethod || Modifier.isNative(node.getModifiers()) || functionizableMethods.contains(element)) {
        TypeElement declaringClass = ElementUtil.getDeclaringClass(element);
        boolean isEnumConstructor = isConstructor && ElementUtil.isEnum(declaringClass);
        if (isConstructor) {
            addImplicitParameters(node, declaringClass);
        }
        FunctionDeclaration function = makeFunction(node);
        declarationList.add(function);
        if (isConstructor && !ElementUtil.isAbstract(declaringClass) && !isEnumConstructor) {
            declarationList.add(makeAllocatingConstructor(node, false));
            declarationList.add(makeAllocatingConstructor(node, true));
        } else if (isEnumConstructor && options.useARC()) {
            // Enums with ARC need the retaining constructor.
            declarationList.add(makeAllocatingConstructor(node, false));
        }
        // Instance methods must be kept in case they are invoked using "super".
        boolean keepMethod = isInstanceMethod || // Public methods must be kept for the public API.
        !(ElementUtil.isPrivateInnerType(declaringClass) || ElementUtil.isPrivate(element)) || // Methods must be kept for reflection if enabled.
        (translationUtil.needsReflection(declaringClass) && !isEnumConstructor);
        if (keepMethod) {
            if (isDefaultMethod) {
                // For default methods keep only the declaration. Implementing classes will add a shim.
                node.setBody(null);
                node.addModifiers(Modifier.ABSTRACT);
            } else {
                setFunctionCaller(node, element);
            }
        } else {
            node.remove();
        }
        ErrorUtil.functionizedMethod();
    }
}
Also used : FunctionDeclaration(com.google.devtools.j2objc.ast.FunctionDeclaration) TypeElement(javax.lang.model.element.TypeElement) GeneratedExecutableElement(com.google.devtools.j2objc.types.GeneratedExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) BodyDeclaration(com.google.devtools.j2objc.ast.BodyDeclaration)

Example 4 with FunctionDeclaration

use of com.google.devtools.j2objc.ast.FunctionDeclaration in project j2objc by google.

the class AnnotationRewriter method addConstructor.

private void addConstructor(AnnotationTypeDeclaration node, Map<ExecutableElement, VariableElement> fieldElements) {
    TypeElement type = node.getTypeElement();
    String typeName = nameTable.getFullName(type);
    FunctionDeclaration constructorDecl = new FunctionDeclaration("create_" + typeName, type.asType());
    Block constructorBody = new Block();
    constructorDecl.setBody(constructorBody);
    List<Statement> stmts = constructorBody.getStatements();
    stmts.add(new NativeStatement(UnicodeUtils.format("%s *self = AUTORELEASE([[%s alloc] init]);", typeName, typeName)));
    for (ExecutableElement memberElement : ElementUtil.getSortedAnnotationMembers(type)) {
        TypeMirror memberType = memberElement.getReturnType();
        String propName = NameTable.getAnnotationPropertyName(memberElement);
        String fieldName = nameTable.getVariableShortName(fieldElements.get(memberElement));
        VariableElement param = GeneratedVariableElement.newParameter(propName, memberType, null);
        constructorDecl.addParameter(new SingleVariableDeclaration(param));
        String rhs = TypeUtil.isReferenceType(memberType) ? "RETAIN_(" + propName + ")" : propName;
        stmts.add(new NativeStatement("self->" + fieldName + " = " + rhs + ";"));
    }
    stmts.add(new NativeStatement("return self;"));
    node.addBodyDeclaration(constructorDecl);
}
Also used : FunctionDeclaration(com.google.devtools.j2objc.ast.FunctionDeclaration) NativeStatement(com.google.devtools.j2objc.ast.NativeStatement) TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement) Statement(com.google.devtools.j2objc.ast.Statement) ReturnStatement(com.google.devtools.j2objc.ast.ReturnStatement) NativeStatement(com.google.devtools.j2objc.ast.NativeStatement) SingleVariableDeclaration(com.google.devtools.j2objc.ast.SingleVariableDeclaration) GeneratedExecutableElement(com.google.devtools.j2objc.types.GeneratedExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Block(com.google.devtools.j2objc.ast.Block) VariableElement(javax.lang.model.element.VariableElement) GeneratedVariableElement(com.google.devtools.j2objc.types.GeneratedVariableElement)

Aggregations

FunctionDeclaration (com.google.devtools.j2objc.ast.FunctionDeclaration)4 GeneratedExecutableElement (com.google.devtools.j2objc.types.GeneratedExecutableElement)4 ExecutableElement (javax.lang.model.element.ExecutableElement)4 TypeElement (javax.lang.model.element.TypeElement)4 SingleVariableDeclaration (com.google.devtools.j2objc.ast.SingleVariableDeclaration)3 Block (com.google.devtools.j2objc.ast.Block)2 NativeStatement (com.google.devtools.j2objc.ast.NativeStatement)2 GeneratedVariableElement (com.google.devtools.j2objc.types.GeneratedVariableElement)2 VariableElement (javax.lang.model.element.VariableElement)2 TypeMirror (javax.lang.model.type.TypeMirror)2 BodyDeclaration (com.google.devtools.j2objc.ast.BodyDeclaration)1 ExpressionStatement (com.google.devtools.j2objc.ast.ExpressionStatement)1 FunctionInvocation (com.google.devtools.j2objc.ast.FunctionInvocation)1 ReturnStatement (com.google.devtools.j2objc.ast.ReturnStatement)1 Statement (com.google.devtools.j2objc.ast.Statement)1 FunctionElement (com.google.devtools.j2objc.types.FunctionElement)1