Skip to content

Commit

Permalink
Give generated code meaningful parameter names (#2970)
Browse files Browse the repository at this point in the history
* Give generated code meaningful parameter names

Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
SUPERCILEX authored and sjudd committed Mar 30, 2018

Verified

This commit was signed with the committer’s verified signature. The key has expired.
MylesBorins Myles Borins
1 parent 5212e95 commit 58bcf53
Showing 40 changed files with 3,193 additions and 3,068 deletions.
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.MethodSpec.Builder;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.TypeSpec;
import java.util.ArrayList;
import java.util.List;
@@ -16,7 +17,6 @@
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.Elements;

/**
@@ -138,7 +138,7 @@ public MethodSpec apply(ExecutableElement input) {
}

private MethodSpec overrideGlideStaticMethod(ExecutableElement methodToOverride) {
List<? extends VariableElement> parameters = methodToOverride.getParameters();
List<ParameterSpec> parameters = ProcessorUtil.getParameters(methodToOverride);

TypeElement element =
(TypeElement) processingEnv.getTypeUtils().asElement(methodToOverride.getReturnType());
@@ -147,7 +147,7 @@ private MethodSpec overrideGlideStaticMethod(ExecutableElement methodToOverride)
MethodSpec.methodBuilder(methodToOverride.getSimpleName().toString())
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addJavadoc(processorUtil.generateSeeMethodJavadoc(methodToOverride))
.addParameters(ProcessorUtil.getParameters(methodToOverride));
.addParameters(parameters);

addReturnAnnotations(builder, methodToOverride);

@@ -162,9 +162,9 @@ private MethodSpec overrideGlideStaticMethod(ExecutableElement methodToOverride)
args.add(ClassName.get(glideType));
args.add(methodToOverride.getSimpleName());
if (!parameters.isEmpty()) {
for (VariableElement param : parameters) {
for (ParameterSpec param : parameters) {
code.append("$L, ");
args.add(param.getSimpleName());
args.add(param.name);
}
code = new StringBuilder(code.substring(0, code.length() - 2));
}
@@ -210,20 +210,20 @@ private MethodSpec overrideGlideWithMethod(
String packageName, TypeSpec generatedRequestManager, ExecutableElement methodToOverride) {
ClassName generatedRequestManagerClassName =
ClassName.get(packageName, generatedRequestManager.name);
List<? extends VariableElement> parameters = methodToOverride.getParameters();
List<ParameterSpec> parameters = ProcessorUtil.getParameters(methodToOverride);
Preconditions.checkArgument(
parameters.size() == 1, "Expected size of 1, but got %s", methodToOverride);
VariableElement parameter = parameters.iterator().next();
ParameterSpec parameter = parameters.iterator().next();

Builder builder = MethodSpec.methodBuilder(methodToOverride.getSimpleName().toString())
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addJavadoc(processorUtil.generateSeeMethodJavadoc(methodToOverride))
.addParameters(ProcessorUtil.getParameters(methodToOverride))
.addParameters(parameters)
.returns(generatedRequestManagerClassName)
.addStatement("return ($T) $T.$N($L)",
generatedRequestManagerClassName, glideType,
methodToOverride.getSimpleName().toString(),
parameter.getSimpleName());
parameter.name);

return addReturnAnnotations(builder, methodToOverride).build();
}
Original file line number Diff line number Diff line change
@@ -256,15 +256,15 @@ void warnLog(String toLog) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, toLog);
}

static CodeBlock generateCastingSuperCall(TypeName toReturn, ExecutableElement method) {
static CodeBlock generateCastingSuperCall(TypeName toReturn, MethodSpec method) {
return CodeBlock.builder()
.add("return ($T) super.$N(", toReturn, method.getSimpleName())
.add("return ($T) super.$N(", toReturn, method.name)
.add(
FluentIterable.from(method.getParameters())
.transform(new Function<VariableElement, String>() {
FluentIterable.from(method.parameters)
.transform(new Function<ParameterSpec, String>() {
@Override
public String apply(VariableElement input) {
return input.getSimpleName().toString();
public String apply(ParameterSpec input) {
return input.name;
}
})
.join(Joiner.on(",")))
@@ -317,18 +317,119 @@ static List<ParameterSpec> getParameters(List<? extends VariableElement> paramet
for (VariableElement parameter : parameters) {
result.add(getParameter(parameter));
}
return result;
return dedupedParameters(result);
}

private static List<ParameterSpec> dedupedParameters(List<ParameterSpec> parameters) {
boolean hasDupes = false;
Set<String> names = new HashSet<>();
for (ParameterSpec parameter : parameters) {
String name = parameter.name;
if (names.contains(name)) {
hasDupes = true;
} else {
names.add(name);
}
}

if (hasDupes) {
List<ParameterSpec> copy = parameters;
parameters = new ArrayList<>();
for (int i = 0; i < copy.size(); i++) {
ParameterSpec parameter = copy.get(i);
parameters.add(ParameterSpec.builder(parameter.type, parameter.name + i)
.addModifiers(parameter.modifiers)
.addAnnotations(parameter.annotations)
.build());
}
}

return parameters;
}

private static ParameterSpec getParameter(VariableElement method) {
TypeName type = TypeName.get(method.asType());
String name = method.getSimpleName().toString();
return ParameterSpec.builder(type, name)
.addModifiers(method.getModifiers())
.addAnnotations(getAnnotations(method))
private static ParameterSpec getParameter(VariableElement parameter) {
TypeName type = TypeName.get(parameter.asType());
return ParameterSpec.builder(type, computeParameterName(parameter, type))
.addModifiers(parameter.getModifiers())
.addAnnotations(getAnnotations(parameter))
.build();
}

private static String computeParameterName(VariableElement parameter, TypeName type) {
String rawClassName = type.withoutAnnotations().toString();

String name;

if (type.isPrimitive() || type.isBoxedPrimitive()) {
name = getSmartPrimitiveParameterName(parameter);
} else {
if (rawClassName.contains("<") && rawClassName.contains(">")) {
String[] preGenericSplit = rawClassName.split("<");
String preGeneric = preGenericSplit[0];
String[] postGenericSplit = rawClassName.split(">");
String postGeneric = postGenericSplit[postGenericSplit.length - 1];
if (postGenericSplit.length > 1) {
rawClassName = preGeneric + postGeneric;
} else {
rawClassName = preGeneric;
}
}

String[] qualifiers = rawClassName.split("\\.");
rawClassName = qualifiers[qualifiers.length - 1];

rawClassName = applySmartParameterNameReplacements(rawClassName);

boolean allCaps = true;
for (char c : rawClassName.toCharArray()) {
if (Character.isLowerCase(c)) {
allCaps = false;
break;
}
}
if (allCaps) {
name = rawClassName.toLowerCase();
} else {
int indexOfLastWordStart = 0;
char[] chars = rawClassName.toCharArray();
for (int i = 0, charArrayLength = chars.length; i < charArrayLength; i++) {
char c = chars[i];
if (Character.isUpperCase(c)) {
indexOfLastWordStart = i;
}
}
rawClassName = rawClassName.substring(indexOfLastWordStart, rawClassName.length());

name = Character.toLowerCase(rawClassName.charAt(0))
+ rawClassName.substring(1, rawClassName.length());
}
}

return name;
}

private static String getSmartPrimitiveParameterName(VariableElement parameter) {
for (AnnotationMirror annotation : parameter.getAnnotationMirrors()) {
String annotationName = annotation.getAnnotationType().toString().toUpperCase();
if (annotationName.endsWith("RES")) {
// Catch annotations like StringRes
return "id";
} else if (annotationName.endsWith("RANGE")) {
// Catch annotations like IntRange
return "value";
}
}

return parameter.getSimpleName().toString();
}

private static String applySmartParameterNameReplacements(String name) {
name = name.replace("[]", "s");
name = name.replace(Class.class.getSimpleName(), "clazz");
name = name.replace(Object.class.getSimpleName(), "o");
return name;
}

private static List<AnnotationSpec> getAnnotations(VariableElement element) {
List<AnnotationSpec> result = new ArrayList<>();
for (AnnotationMirror mirror : element.getAnnotationMirrors()) {
Original file line number Diff line number Diff line change
@@ -33,7 +33,6 @@
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;

@@ -214,20 +213,20 @@ private MethodSpec generateRequestBuilderOverride(ExecutableElement methodToOver
ParameterizedTypeName.get(generatedRequestBuilderClassName, ClassName.get(typeArgument));

MethodSpec.Builder builder = ProcessorUtil.overriding(methodToOverride)
.returns(generatedRequestBuilderOfType)
.addCode(CodeBlock.builder()
.add("return ($T) super.$N(",
generatedRequestBuilderOfType, methodToOverride.getSimpleName())
.add(FluentIterable.from(methodToOverride.getParameters())
.transform(new Function<VariableElement, String>() {
@Override
public String apply(VariableElement input) {
return input.getSimpleName().toString();
}
})
.join(Joiner.on(", ")))
.add(");\n")
.build());
.returns(generatedRequestBuilderOfType);
builder.addCode(CodeBlock.builder()
.add("return ($T) super.$N(",
generatedRequestBuilderOfType, methodToOverride.getSimpleName())
.add(FluentIterable.from(builder.build().parameters)
.transform(new Function<ParameterSpec, String>() {
@Override
public String apply(ParameterSpec input) {
return input.name;
}
})
.join(Joiner.on(", ")))
.add(");\n")
.build());

for (AnnotationMirror mirror : methodToOverride.getAnnotationMirrors()) {
builder = builder.addAnnotation(AnnotationSpec.get(mirror));
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.MethodSpec.Builder;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeSpec;
@@ -192,10 +193,12 @@ private MethodSpec generateRequestManagerRequestManagerMethodOverride(
String generatedPackageName, ExecutableElement method) {
ClassName generatedRequestManagerName =
ClassName.get(generatedPackageName, GENERATED_REQUEST_MANAGER_SIMPLE_NAME);
return ProcessorUtil.overriding(method)
Builder returns = ProcessorUtil.overriding(method)
.addAnnotation(nonNull())
.returns(generatedRequestManagerName)
.addCode(ProcessorUtil.generateCastingSuperCall(generatedRequestManagerName, method))
.returns(generatedRequestManagerName);
return returns
.addCode(ProcessorUtil.generateCastingSuperCall(
generatedRequestManagerName, returns.build()))
.build();
}

@@ -240,10 +243,9 @@ private MethodSpec generateRequestManagerRequestBuilderMethodOverride(
ParameterizedTypeName.get(generatedRequestBuilderClassName, ClassName.get(typeArgument));

MethodSpec.Builder builder = ProcessorUtil.overriding(methodToOverride)
.returns(generatedRequestBuilderOfType)
.addCode(
ProcessorUtil.generateCastingSuperCall(
generatedRequestBuilderOfType, methodToOverride));
.returns(generatedRequestBuilderOfType);
builder.addCode(
ProcessorUtil.generateCastingSuperCall(generatedRequestBuilderOfType, builder.build()));

for (AnnotationMirror mirror : methodToOverride.getAnnotationMirrors()) {
builder.addAnnotation(AnnotationSpec.get(mirror));
Loading

0 comments on commit 58bcf53

Please sign in to comment.