Skip to content

Commit

Permalink
Do not generate static accessor methods when they are already provided.
Browse files Browse the repository at this point in the history
	Change on 2018/07/27 by antoniocortes <antoniocortes@google.com>

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=206377606
  • Loading branch information
antonio-cortes-perez authored and Tom Ball committed Jul 31, 2018
1 parent fd3208e commit 5f16e55
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 36 deletions.
Expand Up @@ -247,10 +247,17 @@ protected void printStaticAccessors() {
if (ElementUtil.hasAnnotation(var, Property.class)) { if (ElementUtil.hasAnnotation(var, Property.class)) {
continue; continue;
} }
TypeMirror type = var.asType();
String accessorName = nameTable.getStaticAccessorName(var); String accessorName = nameTable.getStaticAccessorName(var);
String objcType = nameTable.getObjCType(var.asType()); String objcType = nameTable.getObjCType(type);
printf("\n+ (%s)%s;\n", objcType, accessorName); TypeElement declaringClass = ElementUtil.getDeclaringClass(var);
if (!ElementUtil.isFinal(var)) { String baseName = nameTable.getVariableBaseName(var);
ExecutableElement getter = ElementUtil.findGetterMethod(baseName, type, declaringClass);
if (getter == null) {
printf("\n+ (%s)%s;\n", objcType, accessorName);
}
ExecutableElement setter = ElementUtil.findSetterMethod(baseName, type, declaringClass);
if (setter == null && !ElementUtil.isFinal(var)) {
printf("\n+ (void)set%s:(%s)value;\n", NameTable.capitalize(accessorName), objcType); printf("\n+ (void)set%s:(%s)value;\n", NameTable.capitalize(accessorName), objcType);
} }
} }
Expand Down Expand Up @@ -320,30 +327,6 @@ protected void printInstanceVariables() {
println("}"); println("}");
} }


/**
* Locate method which matches either Java or Objective C getter name patterns.
*/
public static ExecutableElement findGetterMethod(
String propertyName, TypeMirror propertyType, TypeElement declaringClass) {
// Try Objective-C getter naming convention.
ExecutableElement getter = ElementUtil.findMethod(declaringClass, propertyName);
if (getter == null) {
// Try Java getter naming conventions.
String prefix = TypeUtil.isBoolean(propertyType) ? "is" : "get";
getter = ElementUtil.findMethod(declaringClass, prefix + NameTable.capitalize(propertyName));
}
return getter;
}

/**
* Locate method which matches the Java/Objective C setter name pattern.
*/
public static ExecutableElement findSetterMethod(
String propertyName, TypeMirror type, TypeElement declaringClass) {
return ElementUtil.findMethod(declaringClass, "set" + NameTable.capitalize(propertyName),
TypeUtil.getQualifiedName(type));
}

protected void printProperties() { protected void printProperties() {
Iterable<VariableDeclarationFragment> fields = getAllFields(); Iterable<VariableDeclarationFragment> fields = getAllFields();
for (VariableDeclarationFragment fragment : fields) { for (VariableDeclarationFragment fragment : fields) {
Expand All @@ -360,7 +343,8 @@ protected void printProperties() {
// to support its unique accessors. // to support its unique accessors.
Set<String> attributes = property.getPropertyAttributes(); Set<String> attributes = property.getPropertyAttributes();
TypeElement declaringClass = ElementUtil.getDeclaringClass(varElement); TypeElement declaringClass = ElementUtil.getDeclaringClass(varElement);
ExecutableElement getter = findGetterMethod(propertyName, varType, declaringClass); ExecutableElement getter =
ElementUtil.findGetterMethod(propertyName, varType, declaringClass);
if (getter != null) { if (getter != null) {
// Update getter from its Java name to its selector. This is normally the // Update getter from its Java name to its selector. This is normally the
// same since getters have no parameters, but the name may be reserved. // same since getters have no parameters, but the name may be reserved.
Expand All @@ -370,7 +354,8 @@ protected void printProperties() {
attributes.add("nonatomic"); attributes.add("nonatomic");
} }
} }
ExecutableElement setter = findSetterMethod(propertyName, varType, declaringClass); ExecutableElement setter =
ElementUtil.findSetterMethod(propertyName, varType, declaringClass);
if (setter != null) { if (setter != null) {
// Update setter from its Java name to its selector. // Update setter from its Java name to its selector.
attributes.remove("setter=" + property.getSetter()); attributes.remove("setter=" + property.getSetter());
Expand Down
Expand Up @@ -38,6 +38,7 @@
import java.util.Optional; import java.util.Optional;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement; import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeMirror;


Expand Down Expand Up @@ -183,13 +184,20 @@ protected void printStaticAccessors() {
String varName = nameTable.getVariableQualifiedName(varElement); String varName = nameTable.getVariableQualifiedName(varElement);
String objcType = nameTable.getObjCType(type); String objcType = nameTable.getObjCType(type);
String typeSuffix = isPrimitive ? NameTable.capitalize(TypeUtil.getName(type)) : "Id"; String typeSuffix = isPrimitive ? NameTable.capitalize(TypeUtil.getName(type)) : "Id";
if (isVolatile) { TypeElement declaringClass = ElementUtil.getDeclaringClass(varElement);
printf("\n+ (%s)%s {\n return JreLoadVolatile%s(&%s);\n}\n", String baseName = nameTable.getVariableBaseName(varElement);
objcType, accessorName, typeSuffix, varName); ExecutableElement getter = ElementUtil.findGetterMethod(baseName, type, declaringClass);
} else { if (getter == null) {
printf("\n+ (%s)%s {\n return %s;\n}\n", objcType, accessorName, varName); if (isVolatile) {
printf(
"\n+ (%s)%s {\n return JreLoadVolatile%s(&%s);\n}\n",
objcType, accessorName, typeSuffix, varName);
} else {
printf("\n+ (%s)%s {\n return %s;\n}\n", objcType, accessorName, varName);
}
} }
if (!ElementUtil.isFinal(varElement)) { ExecutableElement setter = ElementUtil.findSetterMethod(baseName, type, declaringClass);
if (setter == null && !ElementUtil.isFinal(varElement)) {
String setterFunc = isVolatile String setterFunc = isVolatile
? (isPrimitive ? "JreAssignVolatile" + typeSuffix : "JreVolatileStrongAssign") ? (isPrimitive ? "JreAssignVolatile" + typeSuffix : "JreVolatileStrongAssign")
: (isPrimitive | options.useARC() ? null : "JreStrongAssign"); : (isPrimitive | options.useARC() ? null : "JreStrongAssign");
Expand Down
Expand Up @@ -475,6 +475,28 @@ public static ExecutableElement findMethod(TypeElement type, String name, String
method -> getName(method).equals(name) && paramsMatch(method, paramTypes)), null); method -> getName(method).equals(name) && paramsMatch(method, paramTypes)), null);
} }


/** Locate method which matches either Java or Objective C getter name patterns. */
public static ExecutableElement findGetterMethod(
String propertyName, TypeMirror propertyType, TypeElement declaringClass) {
// Try Objective-C getter naming convention.
ExecutableElement getter = ElementUtil.findMethod(declaringClass, propertyName);
if (getter == null) {
// Try Java getter naming conventions.
String prefix = TypeUtil.isBoolean(propertyType) ? "is" : "get";
getter = ElementUtil.findMethod(declaringClass, prefix + NameTable.capitalize(propertyName));
}
return getter;
}

/** Locate method which matches the Java/Objective C setter name pattern. */
public static ExecutableElement findSetterMethod(
String propertyName, TypeMirror type, TypeElement declaringClass) {
return ElementUtil.findMethod(
declaringClass,
"set" + NameTable.capitalize(propertyName),
TypeUtil.getQualifiedName(type));
}

public static ExecutableElement findConstructor(TypeElement type, String... paramTypes) { public static ExecutableElement findConstructor(TypeElement type, String... paramTypes) {
return Iterables.getFirst(Iterables.filter( return Iterables.getFirst(Iterables.filter(
getConstructors(type), getConstructors(type),
Expand Down
Expand Up @@ -97,6 +97,23 @@ public void testNoStaticFieldAccessorMethods() throws IOException {
assertNotInTranslation(translation, "+ (void)setDEFAULT:(Test *)value"); assertNotInTranslation(translation, "+ (void)setDEFAULT:(Test *)value");
} }


// Verify that accessor methods for static vars and constants are not generated when they are
// already provided.
public void testNoStaticFieldAccessorMethodsWhenAlreadyProvided() throws IOException {
options.setStaticAccessorMethods(true);
String source =
"class Test { "
+ " static String ID; "
+ " static String getID() { return ID; } "
+ " static void setID(String ID) { Test.ID = ID; } "
+ "}";
String translation = translateSourceFile(source, "Test", "Test.h");
assertNotInTranslation(translation, "+ (NSString *)ID;");
assertNotInTranslation(translation, "+ (void)setID:(NSString *)value;");
assertTranslation(translation, "+ (NSString *)getID;");
assertTranslation(translation, "+ (void)setIDWithNSString:(NSString *)ID;");
}

// Verify that accessor methods for enum constants are generated on request. // Verify that accessor methods for enum constants are generated on request.
public void testEnumConstantAccessorMethods() throws IOException { public void testEnumConstantAccessorMethods() throws IOException {
options.setStaticAccessorMethods(true); options.setStaticAccessorMethods(true);
Expand Down
Expand Up @@ -15,7 +15,6 @@
package com.google.devtools.j2objc.gen; package com.google.devtools.j2objc.gen;


import com.google.devtools.j2objc.GenerationTest; import com.google.devtools.j2objc.GenerationTest;

import java.io.IOException; import java.io.IOException;


/** /**
Expand Down Expand Up @@ -111,6 +110,23 @@ public void testNoStaticFieldAccessorMethods() throws IOException {
assertNotInTranslation(translation, "+ (Test *)DEFAULT"); assertNotInTranslation(translation, "+ (Test *)DEFAULT");
} }


// Verify that accessor methods for static vars and constants are not generated when they are
// already provided.
public void testNoStaticFieldAccessorMethodsWhenAlreadyProvided() throws IOException {
options.setStaticAccessorMethods(true);
String source =
"class Test { "
+ " static String ID; "
+ " static String getID() { return ID; } "
+ " static void setID(String ID) { Test.ID = ID; } "
+ "}";
String translation = translateSourceFile(source, "Test", "Test.m");
assertNotInTranslation(translation, "+ (NSString *)ID {");
assertNotInTranslation(translation, "+ (void)setID:(NSString *)value {");
assertTranslation(translation, "+ (NSString *)getID {");
assertTranslation(translation, "+ (void)setIDWithNSString:(NSString *)ID {");
}

// Verify that accessor methods for enum constants are generated on request. // Verify that accessor methods for enum constants are generated on request.
public void testEnumConstantAccessorMethods() throws IOException { public void testEnumConstantAccessorMethods() throws IOException {
options.setStaticAccessorMethods(true); options.setStaticAccessorMethods(true);
Expand Down

0 comments on commit 5f16e55

Please sign in to comment.