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