// We generate the runtime debug method -memDebugStrongReferences. // This method will return an array of information about a strong reference, // including pointer to object and name. private void printStrongReferencesMethod(List<VariableDeclarationFragment> properties) { if (Options.memoryDebug()) { if (!Options.useReferenceCounting()) { println("- (NSArray *)memDebugStrongReferences {"); println(" return nil;"); println("}"); return; } println("- (NSArray *)memDebugStrongReferences {"); println(" NSMutableArray *result ="); println(" [[[super memDebugStrongReferences] mutableCopy] autorelease];"); for (VariableDeclarationFragment property : properties) { String propName = NameTable.getName(property.getName()); String objCFieldName = NameTable.javaFieldToObjC(propName); if (isStrongReferenceProperty(property)) { println( String.format( " [result addObject:[JreMemDebugStrongReference " + "strongReferenceWithObject:%s name:@\"%s\"]];", objCFieldName, propName)); } } println(" return result;"); println("}\n"); } }
private void printAnnotations(List<Annotation> runtimeAnnotations) { boolean first = true; for (Annotation annotation : runtimeAnnotations) { if (first) { first = false; } else { print(", "); } if (Options.useReferenceCounting()) { print('['); } printf("[[%s alloc] init", NameTable.getFullName(Types.getTypeBinding(annotation))); printAnnotationParameters(annotation); print(']'); if (Options.useReferenceCounting()) { print(" autorelease]"); } } }
@Override protected void printStaticFieldSetter(IVariableBinding var) { String fieldName = NameTable.getStaticVarQualifiedName(var); String paramName = NameTable.getName(var); String signature = staticFieldSetterSignature(var); if (Options.useReferenceCounting()) { printf( "%s {\n JreOperatorRetainedAssign(&%s, nil, %s);\n}\n\n", signature, fieldName, paramName); } else { printf("%s {\n %s = %s;\n}\n\n", signature, fieldName, paramName); } }
// We generate the runtime debug method +memDebugStaticReferences. // This method will return an array of NSNumber containing pointers (casted into unsigned long) // to the objects referenced by a class variable with a strong reference. // It will be useful for debug purpose. // // Arrays returned by -memDebugStaticReferences and -memDebugStaticReferencesNames (see below) // must be the same size. // // In case of a Java enum, valuesVarNameis the name of the array of enum values. private void printStaticReferencesMethod(List<FieldDeclaration> fields, String valuesVarName) { if (Options.memoryDebug()) { if (!Options.useReferenceCounting()) { println("+ (NSArray *)memDebugStaticReferences {"); println(" return nil;"); println("}"); return; } println("+ (NSArray *)memDebugStaticReferences {"); println(" NSMutableArray *result = [NSMutableArray array];"); for (FieldDeclaration f : fields) { if (Modifier.isStatic(f.getModifiers())) { for (VariableDeclarationFragment var : ASTUtil.getFragments(f)) { IVariableBinding binding = Types.getVariableBinding(var); // All non-primitive static variables are strong references. if (!binding.getType().isPrimitive()) { String name = NameTable.getStaticVarQualifiedName(binding); println( String.format( " [result addObject:[JreMemDebugStrongReference " + "strongReferenceWithObject:%s name:@\"%s\"]];", name, name)); } } } } if (valuesVarName != null) { println( String.format( " [result addObject:[JreMemDebugStrongReference " + "strongReferenceWithObject:%s name:@\"enumValues\"]];", valuesVarName)); } println(" return result;"); println("}\n"); } }
@Override protected void generate(EnumDeclaration node) { List<EnumConstantDeclaration> constants = ASTUtil.getEnumConstants(node); List<MethodDeclaration> methods = Lists.newArrayList(); List<FieldDeclaration> fields = Lists.newArrayList(); MethodDeclaration initializeMethod = null; for (BodyDeclaration decl : ASTUtil.getBodyDeclarations(node)) { if (decl instanceof FieldDeclaration) { fields.add((FieldDeclaration) decl); } else if (decl instanceof MethodDeclaration) { MethodDeclaration md = (MethodDeclaration) decl; if (md.getName().getIdentifier().equals("initialize")) { initializeMethod = md; } else { methods.add(md); } } } syncLineNumbers(node.getName()); // avoid doc-comment String typeName = NameTable.getFullName(node); newline(); for (EnumConstantDeclaration constant : constants) { IVariableBinding var = Types.getVariableBinding(constant.getName()); printf("static %s *%s;\n", typeName, NameTable.getStaticVarQualifiedName(var)); } printf("IOSObjectArray *%s_values;\n", typeName); newline(); printf("@implementation %s\n\n", typeName); printStaticVars(fields, /* isInterface */ false); printStaticReferencesMethod(fields, typeName + "_values"); for (EnumConstantDeclaration constant : constants) { String name = NameTable.getName(constant.getName()); printf("+ (%s *)%s {\n", typeName, name); printf(" return %s_%s;\n", typeName, name); println("}"); } newline(); // Enum constants needs to implement NSCopying. Being singletons, they // can just return self, as long the retain count is incremented. String selfString = Options.useReferenceCounting() ? "[self retain]" : "self"; printf("- (id)copyWithZone:(NSZone *)zone {\n return %s;\n}\n\n", selfString); printStaticFieldAccessors(fields, methods, /* isInterface */ false); printMethodsAndOcni(node, methods, blockComments.get(node)); printf("+ (void)initialize {\n if (self == [%s class]) {\n", typeName); for (int i = 0; i < constants.size(); i++) { EnumConstantDeclaration constant = constants.get(i); List<Expression> args = ASTUtil.getArguments(constant); String name = NameTable.getName(constant.getName()); String constantTypeName = NameTable.getFullName(Types.getMethodBinding(constant).getDeclaringClass()); printf(" %s_%s = [[%s alloc] init", typeName, name, constantTypeName); if (args.isEmpty()) { print("With"); } else { print( StatementGenerator.generateArguments( Types.getMethodBinding(constant), args, fieldHiders, getBuilder().getSourcePosition())); print(" with"); } printf("NSString:@\"%s\" withInt:%d];\n", name, i); } printf(" %s_values = [[IOSObjectArray alloc] initWithObjects:(id[]){ ", typeName); for (EnumConstantDeclaration constant : constants) { printf("%s_%s, ", typeName, NameTable.getName(constant.getName())); } printf( "nil } count:%d type:[IOSClass classWithClass:[%s class]]];\n", constants.size(), typeName); if (initializeMethod != null) { for (Statement s : ASTUtil.getStatements(initializeMethod.getBody())) { printf( " %s", StatementGenerator.generate(s, fieldHiders, false, getBuilder().getSourcePosition())); } } println(" }\n}\n"); // Print generated values and valueOf methods. println("+ (IOSObjectArray *)values {"); printf(" return [IOSObjectArray arrayWithArray:%s_values];\n", typeName); println("}\n"); printf("+ (%s *)valueOfWithNSString:(NSString *)name {\n", typeName); printf(" for (int i = 0; i < [%s_values count]; i++) {\n", typeName); printf(" %s *e = %s_values->buffer_[i];\n", typeName, typeName); printf(" if ([name isEqual:[e name]]) {\n"); printf(" return e;\n"); printf(" }\n"); printf(" }\n"); if (Options.useReferenceCounting()) { printf( " @throw [[[JavaLangIllegalArgumentException alloc] initWithNSString:name]" + " autorelease];\n"); } else { printf(" @throw [[JavaLangIllegalArgumentException alloc] initWithNSString:name];\n"); } printf(" return nil;\n"); println("}\n"); if (!Options.stripReflection()) { printTypeAnnotationsMethod(node); printMetadata(node); } println("@end"); }