Search in sources :

Example 21 with MethodInvocation

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

the class ArrayRewriter method newInitializedArrayInvocation.

private MethodInvocation newInitializedArrayInvocation(ArrayType arrayType, List<Expression> elements, boolean retainedResult) {
    TypeMirror componentType = arrayType.getComponentType();
    TypeElement iosArrayElement = typeUtil.getIosArray(componentType);
    GeneratedExecutableElement methodElement = GeneratedExecutableElement.newMethodWithSelector(getInitializeSelector(componentType, retainedResult), iosArrayElement.asType(), iosArrayElement).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
    methodElement.addParameter(GeneratedVariableElement.newParameter("values", new PointerType(componentType), methodElement));
    methodElement.addParameter(GeneratedVariableElement.newParameter("count", typeUtil.getInt(), methodElement));
    if (!componentType.getKind().isPrimitive()) {
        methodElement.addParameter(GeneratedVariableElement.newParameter("type", TypeUtil.IOS_CLASS.asType(), methodElement));
    }
    MethodInvocation invocation = new MethodInvocation(new ExecutablePair(methodElement), arrayType, new SimpleName(iosArrayElement));
    // Create the array initializer and add it as the first parameter.
    ArrayInitializer arrayInit = new ArrayInitializer(arrayType);
    for (Expression element : elements) {
        arrayInit.addExpression(element.copy());
    }
    invocation.addArgument(arrayInit);
    // Add the array size parameter.
    invocation.addArgument(NumberLiteral.newIntLiteral(arrayInit.getExpressions().size(), typeUtil));
    // Add the type argument for object arrays.
    if (!componentType.getKind().isPrimitive()) {
        invocation.addArgument(new TypeLiteral(componentType, typeUtil));
    }
    return invocation;
}
Also used : GeneratedExecutableElement(com.google.devtools.j2objc.types.GeneratedExecutableElement) TypeLiteral(com.google.devtools.j2objc.ast.TypeLiteral) TypeMirror(javax.lang.model.type.TypeMirror) ExecutablePair(com.google.devtools.j2objc.types.ExecutablePair) InstanceofExpression(com.google.devtools.j2objc.ast.InstanceofExpression) Expression(com.google.devtools.j2objc.ast.Expression) PrefixExpression(com.google.devtools.j2objc.ast.PrefixExpression) TypeElement(javax.lang.model.element.TypeElement) SimpleName(com.google.devtools.j2objc.ast.SimpleName) PointerType(com.google.devtools.j2objc.types.PointerType) MethodInvocation(com.google.devtools.j2objc.ast.MethodInvocation) ArrayInitializer(com.google.devtools.j2objc.ast.ArrayInitializer)

Example 22 with MethodInvocation

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

the class Rewriter method visit.

@Override
public boolean visit(TryStatement node) {
    // This visit rewrites try-with-resources constructs into regular try statements according to
    // JLS 14.20.3. The rewriting is done in a visit instead of endVisit because the mutations may
    // result in more try-with-resources constructs that need to be rewritten recursively.
    List<TreeNode> resources = node.getResources();
    if (resources.isEmpty()) {
        return true;
    }
    if (!node.getCatchClauses().isEmpty() || node.getFinally() != null) {
        // Extended try-with-resources. (JLS 14.20.3.2)
        // The new innerTry statement will be a "Basic try-with-resources" and will be rewritten by
        // the code below when it is visited.
        TryStatement innerTry = new TryStatement().setBody(TreeUtil.remove(node.getBody()));
        ;
        TreeUtil.moveList(resources, innerTry.getResources());
        node.setBody(new Block().addStatement(innerTry));
        return true;
    }
    // Basic try-with-resources. (JLS 14.20.3.1)
    DeclaredType throwableType = (DeclaredType) typeUtil.getJavaThrowable().asType();
    VariableElement primaryException = GeneratedVariableElement.newLocalVar("__primaryException" + resources.size(), throwableType, null);
    TreeNode resource = resources.remove(0);
    VariableElement resourceVar = null;
    VariableDeclarationFragment resourceFrag = null;
    if (resource.getKind() == Kind.VARIABLE_DECLARATION_EXPRESSION) {
        List<VariableDeclarationFragment> resourceFrags = ((VariableDeclarationExpression) resource).getFragments();
        assert resourceFrags.size() == 1;
        resourceFrag = resourceFrags.get(0);
        resourceVar = resourceFrag.getVariableElement();
    } else {
        resourceVar = TreeUtil.getVariableElement((Expression) resource);
    }
    assert resourceVar != null;
    DeclaredType closeableType = typeUtil.findSupertype(resourceVar.asType(), "java.lang.AutoCloseable");
    ExecutablePair closeMethod = typeUtil.findMethod(closeableType, "close");
    ExecutablePair addSuppressedMethod = typeUtil.findMethod(throwableType, "addSuppressed", "java.lang.Throwable");
    Block block = new Block();
    if (resourceFrag != null) {
        block.addStatement(new VariableDeclarationStatement(resourceVar, TreeUtil.remove(resourceFrag.getInitializer())));
    }
    block.addStatement(new VariableDeclarationStatement(primaryException, new NullLiteral(typeUtil.getNull())));
    // If the current try node is the only statement in its parent block then replace the parent
    // block instead of the try node to avoid extra nesting of braces.
    TreeNode parent = node.getParent();
    if (parent instanceof Block && ((Block) parent).getStatements().size() == 1) {
        parent.replaceWith(block);
    } else {
        node.replaceWith(block);
    }
    block.addStatement(TreeUtil.remove(node));
    VariableElement caughtException = GeneratedVariableElement.newLocalVar("e", throwableType, null);
    Block catchBlock = new Block().addStatement(new ExpressionStatement(new Assignment(new SimpleName(primaryException), new SimpleName(caughtException)))).addStatement(new ThrowStatement(new SimpleName(caughtException)));
    node.addCatchClause(new CatchClause().setException(new SingleVariableDeclaration(caughtException)).setBody(catchBlock));
    Statement closeResource = new ExpressionStatement(new MethodInvocation(closeMethod, typeUtil.getVoid(), new SimpleName(resourceVar)));
    VariableElement suppressedException = GeneratedVariableElement.newLocalVar("e", throwableType, null);
    node.setFinally(new Block().addStatement(new IfStatement().setExpression(new InfixExpression(typeUtil.getBoolean(), InfixExpression.Operator.NOT_EQUALS, new SimpleName(resourceVar), new NullLiteral(typeUtil.getNull()))).setThenStatement(new Block().addStatement(new IfStatement().setExpression(new InfixExpression(typeUtil.getBoolean(), InfixExpression.Operator.NOT_EQUALS, new SimpleName(primaryException), new NullLiteral(typeUtil.getNull()))).setThenStatement(new Block().addStatement(new TryStatement().setBody(new Block().addStatement(closeResource)).addCatchClause(new CatchClause().setException(new SingleVariableDeclaration(suppressedException)).setBody(new Block().addStatement(new ExpressionStatement(new MethodInvocation(addSuppressedMethod, typeUtil.getVoid(), new SimpleName(primaryException)).addArgument(new SimpleName(suppressedException)))))))).setElseStatement(new Block().addStatement(closeResource.copy()))))));
    // Visit the new block instead of the current node because some of content of the node (eg. the
    // resource initializer) has been moved outside of the try node.
    block.accept(this);
    return false;
}
Also used : ExecutablePair(com.google.devtools.j2objc.types.ExecutablePair) SingleVariableDeclaration(com.google.devtools.j2objc.ast.SingleVariableDeclaration) ExpressionStatement(com.google.devtools.j2objc.ast.ExpressionStatement) ForStatement(com.google.devtools.j2objc.ast.ForStatement) ThrowStatement(com.google.devtools.j2objc.ast.ThrowStatement) TryStatement(com.google.devtools.j2objc.ast.TryStatement) VariableDeclarationStatement(com.google.devtools.j2objc.ast.VariableDeclarationStatement) IfStatement(com.google.devtools.j2objc.ast.IfStatement) Statement(com.google.devtools.j2objc.ast.Statement) VariableDeclarationExpression(com.google.devtools.j2objc.ast.VariableDeclarationExpression) SimpleName(com.google.devtools.j2objc.ast.SimpleName) MethodInvocation(com.google.devtools.j2objc.ast.MethodInvocation) GeneratedVariableElement(com.google.devtools.j2objc.types.GeneratedVariableElement) VariableElement(javax.lang.model.element.VariableElement) CatchClause(com.google.devtools.j2objc.ast.CatchClause) Assignment(com.google.devtools.j2objc.ast.Assignment) IfStatement(com.google.devtools.j2objc.ast.IfStatement) TryStatement(com.google.devtools.j2objc.ast.TryStatement) Expression(com.google.devtools.j2objc.ast.Expression) VariableDeclarationExpression(com.google.devtools.j2objc.ast.VariableDeclarationExpression) InfixExpression(com.google.devtools.j2objc.ast.InfixExpression) ParenthesizedExpression(com.google.devtools.j2objc.ast.ParenthesizedExpression) TreeNode(com.google.devtools.j2objc.ast.TreeNode) VariableDeclarationFragment(com.google.devtools.j2objc.ast.VariableDeclarationFragment) ExpressionStatement(com.google.devtools.j2objc.ast.ExpressionStatement) InfixExpression(com.google.devtools.j2objc.ast.InfixExpression) Block(com.google.devtools.j2objc.ast.Block) VariableDeclarationStatement(com.google.devtools.j2objc.ast.VariableDeclarationStatement) ThrowStatement(com.google.devtools.j2objc.ast.ThrowStatement) NullLiteral(com.google.devtools.j2objc.ast.NullLiteral) DeclaredType(javax.lang.model.type.DeclaredType)

Example 23 with MethodInvocation

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

the class LogSiteInjector method injectConvenienceMethod.

private MethodInvocation injectConvenienceMethod(String name, MethodInvocation node) {
    ExecutableElement method = node.getExecutableElement();
    TypeElement cls = ElementUtil.getDeclaringClass(method);
    // Change method name to logp, specify level, and insert class and method name args.
    List<Expression> logpArgs = Lists.newArrayList();
    logpArgs.add(convenienceLevelName(name));
    logpArgs.add(enclosingClassLiteral(node));
    logpArgs.add(enclosingMethodLiteral(node));
    logpArgs.add(node.getArguments().get(0).copy());
    ExecutableElement injectedMethod = ElementUtil.findMethod(cls, LOGP_METHOD, "java.util.logging.Level", "java.lang.String", "java.lang.String", "java.lang.String");
    MethodInvocation injectedInvocation = new MethodInvocation(new ExecutablePair(injectedMethod), node.getExpression().copy());
    for (int i = 0; i < logpArgs.size(); i++) {
        injectedInvocation.addArgument(logpArgs.get(i));
    }
    return injectedInvocation;
}
Also used : Expression(com.google.devtools.j2objc.ast.Expression) ExecutablePair(com.google.devtools.j2objc.types.ExecutablePair) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) MethodInvocation(com.google.devtools.j2objc.ast.MethodInvocation)

Example 24 with MethodInvocation

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

the class LogSiteInjector method injectLogMethod.

private MethodInvocation injectLogMethod(MethodInvocation node) {
    ExecutableElement method = node.getExecutableElement();
    TypeElement cls = ElementUtil.getDeclaringClass(method);
    List<Expression> args = node.getArguments();
    if (!args.isEmpty() && typeUtil.isSameType(args.get(0).getTypeMirror(), javaUtilLoggingLevelClass.asType())) {
        // Change log to logp, insert class and method name args.
        List<Expression> logpArgs = new ArrayList<>();
        List<String> argTypes = new ArrayList<>();
        logpArgs.add(args.get(0).copy());
        argTypes.add("java.util.logging.Level");
        logpArgs.add(enclosingClassLiteral(node));
        argTypes.add("java.lang.String");
        logpArgs.add(enclosingMethodLiteral(node));
        argTypes.add("java.lang.String");
        for (int i = 1; i < args.size(); i++) {
            Expression arg = args.get(i);
            logpArgs.add(arg.copy());
            argTypes.add(TypeUtil.getQualifiedName(arg.getTypeMirror()));
        }
        ExecutableElement injectedMethod = ElementUtil.findMethod(cls, LOGP_METHOD, argTypes.toArray(new String[0]));
        if (injectedMethod != null) {
            MethodInvocation injectedInvocation = new MethodInvocation(new ExecutablePair(injectedMethod), node.getExpression().copy());
            for (int i = 0; i < logpArgs.size(); i++) {
                injectedInvocation.addArgument(logpArgs.get(i));
            }
            return injectedInvocation;
        }
    }
    return node.copy();
}
Also used : Expression(com.google.devtools.j2objc.ast.Expression) ExecutablePair(com.google.devtools.j2objc.types.ExecutablePair) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) MethodInvocation(com.google.devtools.j2objc.ast.MethodInvocation)

Example 25 with MethodInvocation

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

the class LogSiteInjector method injectLogSite.

private MethodInvocation injectLogSite(MethodInvocation node) {
    // Inject withInjectedLogSite(class, method, line, file) into method expression.
    ExecutableElement injectedMethod = ElementUtil.findMethod(loggingApiClass, WITH_INJECTED_LOG_SITE_METHOD, "java.lang.String", "java.lang.String", "int", "java.lang.String");
    DeclaredType loggingApiClassType = googleLoggerApiClass != null ? (DeclaredType) googleLoggerApiClass.asType() : (DeclaredType) loggingApiClass.asType();
    ExecutableType injectedType = typeUtil.asMemberOf(loggingApiClassType, injectedMethod);
    MethodInvocation injectedInvocation = new MethodInvocation(new ExecutablePair(injectedMethod, injectedType), node.getExpression().copy());
    injectedInvocation.addArgument(enclosingClassLiteral(node));
    injectedInvocation.addArgument(enclosingMethodLiteral(node));
    injectedInvocation.addArgument(lineNumberLiteral(node));
    injectedInvocation.addArgument(sourceFileLiteral());
    MethodInvocation newNode = new MethodInvocation(node.getExecutablePair(), injectedInvocation);
    for (Expression arg : node.getArguments()) {
        newNode.addArgument(arg.copy());
    }
    return newNode;
}
Also used : ExecutableType(javax.lang.model.type.ExecutableType) ExecutablePair(com.google.devtools.j2objc.types.ExecutablePair) Expression(com.google.devtools.j2objc.ast.Expression) ExecutableElement(javax.lang.model.element.ExecutableElement) MethodInvocation(com.google.devtools.j2objc.ast.MethodInvocation) DeclaredType(javax.lang.model.type.DeclaredType)

Aggregations

MethodInvocation (com.google.devtools.j2objc.ast.MethodInvocation)27 ExecutablePair (com.google.devtools.j2objc.types.ExecutablePair)23 ExecutableElement (javax.lang.model.element.ExecutableElement)16 Expression (com.google.devtools.j2objc.ast.Expression)14 TypeElement (javax.lang.model.element.TypeElement)12 SimpleName (com.google.devtools.j2objc.ast.SimpleName)11 GeneratedExecutableElement (com.google.devtools.j2objc.types.GeneratedExecutableElement)11 TypeMirror (javax.lang.model.type.TypeMirror)11 SuperMethodInvocation (com.google.devtools.j2objc.ast.SuperMethodInvocation)10 Block (com.google.devtools.j2objc.ast.Block)6 InfixExpression (com.google.devtools.j2objc.ast.InfixExpression)6 PrefixExpression (com.google.devtools.j2objc.ast.PrefixExpression)6 PostfixExpression (com.google.devtools.j2objc.ast.PostfixExpression)5 ThisExpression (com.google.devtools.j2objc.ast.ThisExpression)5 DeclaredType (javax.lang.model.type.DeclaredType)5 ExpressionStatement (com.google.devtools.j2objc.ast.ExpressionStatement)4 InstanceofExpression (com.google.devtools.j2objc.ast.InstanceofExpression)4 MethodDeclaration (com.google.devtools.j2objc.ast.MethodDeclaration)4 SingleVariableDeclaration (com.google.devtools.j2objc.ast.SingleVariableDeclaration)4 Statement (com.google.devtools.j2objc.ast.Statement)4