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;
}
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;
}
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;
}
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();
}
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;
}
Aggregations