Skip to content

Commit

Permalink
Merge branch 'Adrodoc-fix/#156'
Browse files Browse the repository at this point in the history
  • Loading branch information
mkarneim committed Mar 10, 2019
2 parents c821148 + 03da524 commit 2b578f3
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 60 deletions.
55 changes: 31 additions & 24 deletions src/main/java/net/karneim/pojobuilder/model/ImportTypesM.java
Original file line number Diff line number Diff line change
@@ -1,51 +1,58 @@
package net.karneim.pojobuilder.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

public class ImportTypesM {
private final Set<TypeM> types = new HashSet<>();
private final SortedSet<String> classnames = new TreeSet<>();
private final Set<String> simpleNames = new HashSet<>();

public void add(Class<?> aClass) {
add(new TypeM(aClass));
}

public boolean add(TypeM e) {
if (simpleNames.contains(e.getSimpleName())) {
public boolean add(TypeM type) {
if (!simpleNames.contains(type.getSimpleName())) {
types.add(type);
if (!type.isTypeVariable() && !type.isPrimitive()) {
classnames.add(type.getName());
}
simpleNames.add(type.getSimpleName());
return true;
} else {
return false;
}
simpleNames.add(e.getSimpleName());
return types.add(e);
}

public boolean canAdd(TypeM typeM) {
return !types.contains(typeM) && !simpleNames.contains(typeM.getSimpleName());
public void remove(TypeM type) {
types.remove(type);
classnames.remove(type.getName());
simpleNames.remove(type.getSimpleName());
}

public List<String> getSortedDistinctClassnames() {
Set<String> resultSet = new HashSet<String>();
for (TypeM t : this.types) {
if (!t.isTypeVariable() && !t.isPrimitive()) {
resultSet.add(t.getName());
}
}
List<String> result = new ArrayList<String>(resultSet);
Collections.sort(result);
return result;
public SortedSet<String> getSortedDistinctClassnames() {
return classnames;
}

public void removePackage(String packageName) {
Iterator<TypeM> it = this.types.iterator();
while (it.hasNext()) {
TypeM t = it.next();
if (t.isInPackage(packageName)) {
it.remove();
for (TypeM type : new ArrayList<>(types)) {
if (type.isInPackage(packageName)) {
remove(type);
}
}
}

public String getCompressedTypeName(TypeM type) {
add(type);
if (classnames.contains(type.getName())) {
return type.getSimpleName();
} else {
return type.getName();
}
}

}
9 changes: 5 additions & 4 deletions src/main/java/net/karneim/pojobuilder/model/OptionalM.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ public String getAbsentMethodName() {
return absentMethodName;
}

public String absent() {
return type.getSimpleName() + "." + absentMethodName + "()";
public String absent(ImportTypesM importTypes) {
return importTypes.getCompressedTypeName(type) + "." + absentMethodName + "()";

}

public String of(String string) {
return type.getSimpleName() + "." + OF_METHOD_NAME + "(" + string + ")";
public String of(String string, ImportTypesM importTypes) {
return importTypes.getCompressedTypeName(type) + "." + OF_METHOD_NAME + "(" + string + ")";
}
}
4 changes: 1 addition & 3 deletions src/main/java/net/karneim/pojobuilder/model/TypeM.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,7 @@ public String getGenericType() {
}

public ImportTypesM addToImportTypes(ImportTypesM result) {
if (result.canAdd(this)) {
result.add(this);
}
result.add(this);
typeParameters.addToImportTypes(result);
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private void generateSource(TypeM builderType, boolean isAbstract, TypeM selfTyp
}

for (PropertyM prop : properties) {
emitPropertyFields(prop, interfaceType, hasBuilderProperties, optional);
emitPropertyFields(prop, interfaceType, hasBuilderProperties, optional, importTypes);
}

if (staticFactoryMethod != null) {
Expand All @@ -142,12 +142,12 @@ private void generateSource(TypeM builderType, boolean isAbstract, TypeM selfTyp
emitConstructor(builderType, selfType, constructorVisibility);

for (PropertyM prop : properties) {
emitWithMethod(builderType, selfType, pojoType, prop, optional);
emitWithMethod(builderType, selfType, pojoType, prop, optional, importTypes);
if (optional != null) {
emitWithOptionalMethod(builderType, selfType, pojoType, prop, optional);
}
if (interfaceType != null && hasBuilderProperties) {
emitWithMethodUsingBuilderInterface(builderType, selfType, interfaceType, pojoType, prop, optional);
emitWithMethodUsingBuilderInterface(builderType, selfType, interfaceType, pojoType, prop, optional, importTypes);
}
}
emitCloneMethod(selfType, cloneMethod);
Expand All @@ -159,7 +159,7 @@ private void generateSource(TypeM builderType, boolean isAbstract, TypeM selfTyp
addWarning("[PojoBuilder] Skipping the generation of %s method because none of the writable properties are readable!", copyMethodM.getName());
}
}
emitBuildMethod(builderType, pojoType, interfaceType, hasBuilderProperties, optional, properties, factoryMethod, buildMethod, validator);
emitBuildMethod(builderType, pojoType, interfaceType, hasBuilderProperties, optional, properties, factoryMethod, buildMethod, validator, importTypes);
writer.endType();
// @formatter:on
}
Expand Down Expand Up @@ -229,7 +229,7 @@ private void emitCopyMethod(TypeM builderType, TypeM selfType, TypeM pojoType, P

private void emitBuildMethod(TypeM builderType, TypeM pojoType, TypeM interfaceType, boolean hasBuilderProperties,
OptionalM optional, PropertyListM properties, FactoryMethodM factoryMethod, BuildMethodM buildMethod,
ValidatorM validator) throws IOException {
ValidatorM validator, ImportTypesM importTypes) throws IOException {
properties = new PropertyListM(properties);
String pojoTypeDeclaration = writer.compressType(pojoType.getGenericType());
String pojoClassname = writer.compressType(pojoType.getName());
Expand Down Expand Up @@ -257,11 +257,11 @@ private void emitBuildMethod(TypeM builderType, TypeM pojoType, TypeM interfaceT
} else {
if (factoryMethod == null) {
ArgumentListM argumentMs = properties.filterOutPropertiesWritableViaConstructorParameter(builderType);
String arguments = emitParameterAssignments(hasBuilderProperties, optional, buildMethod, argumentMs);
String arguments = emitParameterAssignments(hasBuilderProperties, optional, buildMethod, argumentMs, importTypes);
writer.emitStatement("%s result = new %s(%s)", pojoTypeDeclaration, pojoTypeDeclaration, arguments);
} else {
ArgumentListM argumentMs = properties.filterOutPropertiesWritableViaFactoryMethodParameter(builderType);
String arguments = emitParameterAssignments(hasBuilderProperties, optional, buildMethod, argumentMs);
String arguments = emitParameterAssignments(hasBuilderProperties, optional, buildMethod, argumentMs, importTypes);
String factoryClass = writer.compressType(factoryMethod.getDeclaringClass().getName());
writer.emitStatement("%s result = %s.%s(%s)", pojoTypeDeclaration, factoryClass, factoryMethod.getName(),
arguments);
Expand All @@ -271,13 +271,13 @@ private void emitBuildMethod(TypeM builderType, TypeM pojoType, TypeM interfaceT
PropertyListM setterProperties = properties.filterOutPropertiesWritableBy(Type.SETTER, builderType);
for (PropertyM prop : setterProperties) {
String setTemplate = "result." + prop.getSetterMethod().getName() + "(%s)";
emitBuildPropertyStatement(hasBuilderProperties, buildMethod, optional, prop, setTemplate);
emitBuildPropertyStatement(hasBuilderProperties, buildMethod, optional, prop, setTemplate, importTypes);
}

PropertyListM writableProperties = properties.filterOutPropertiesWritableBy(Type.FIELD, builderType);
for (PropertyM prop : writableProperties) {
String setTemplate = "result." + prop.getPropertyName() + " = %s";
emitBuildPropertyStatement(hasBuilderProperties, buildMethod, optional, prop, setTemplate);
emitBuildPropertyStatement(hasBuilderProperties, buildMethod, optional, prop, setTemplate, importTypes);
}
// TODO inform user about any properties leftover
if (validator != null) {
Expand All @@ -289,11 +289,11 @@ private void emitBuildMethod(TypeM builderType, TypeM pojoType, TypeM interfaceT
}

private String emitParameterAssignments(boolean hasBuilderProperties, OptionalM optional, BuildMethodM buildMethod,
ArgumentListM factoryMethodArguments) throws IOException {
ArgumentListM factoryMethodArguments, ImportTypesM importTypes) throws IOException {
StringBuilder arguments = new StringBuilder();
for (PropertyM prop : factoryMethodArguments.sortByPosition().getPropertyList()) {
String parameterFieldName = "_" + prop.getPropertyName();
emitParameterAssignment(prop, parameterFieldName, optional, hasBuilderProperties, buildMethod);
emitParameterAssignment(prop, parameterFieldName, optional, hasBuilderProperties, buildMethod, importTypes);
if (arguments.length() > 0) {
arguments.append(", ");
}
Expand All @@ -303,7 +303,7 @@ private String emitParameterAssignments(boolean hasBuilderProperties, OptionalM
}

private void emitBuildPropertyStatement(boolean hasBuilderProperties, BuildMethodM buildMethod, OptionalM optional,
PropertyM prop, String setTemplate) throws IOException {
PropertyM prop, String setTemplate, ImportTypesM importTypes) throws IOException {
TypeM type = prop.getPropertyType();
String compressedType = writer.compressType(type.getGenericType());
if (optional == null) { // ohne Optionals
Expand Down Expand Up @@ -333,15 +333,15 @@ private void emitBuildPropertyStatement(boolean hasBuilderProperties, BuildMetho
writer.beginControlFlow("if (%s == null)", tempFieldName);
writer.emitStatement(setTemplate, "(" + compressedType + ") null");
writer.nextControlFlow("else");
writer.emitStatement(setTemplate, optional.of(tempFieldName));
writer.emitStatement(setTemplate, optional.of(tempFieldName, importTypes));
writer.endControlFlow();
}
}
writer.endControlFlow();
}

private void emitParameterAssignment(PropertyM prop, String parameterFieldName, OptionalM optional,
boolean hasBuilderProperties, BuildMethodM buildMethod) throws IOException {
boolean hasBuilderProperties, BuildMethodM buildMethod, ImportTypesM importTypes) throws IOException {
TypeM propertyType = prop.getPropertyType();
String compressedType = writer.compressType(propertyType.getGenericType());
String builderFieldName = prop.getBuilderFieldName();
Expand All @@ -365,7 +365,7 @@ private void emitParameterAssignment(PropertyM prop, String parameterFieldName,
String tempFieldName = "builtValue";
writer.emitStatement("%s %s = %s", basicType, tempFieldName, callBuild);
writer.beginControlFlow("if (%s != null)", tempFieldName);
writer.emitStatement("%s = %s", parameterFieldName, optional.of(tempFieldName));
writer.emitStatement("%s = %s", parameterFieldName, optional.of(tempFieldName, importTypes));
writer.endControlFlow();
writer.endControlFlow();
}
Expand Down Expand Up @@ -400,7 +400,7 @@ private void emitParameterAssignment(PropertyM prop, String parameterFieldName,
}

private void emitWithMethodUsingBuilderInterface(TypeM builderType, TypeM selfType, TypeM interfaceType,
TypeM pojoType, PropertyM prop, OptionalM optional) throws IOException {
TypeM pojoType, PropertyM prop, OptionalM optional, ImportTypesM importTypes) throws IOException {
String withMethodName = prop.getWithMethodName();
String pojoTypeStr = writer.compressType(pojoType.getName());
String parameterTypeStr = prop.getParameterizedBuilderInterfaceType(interfaceType, optional).getGenericType();
Expand All @@ -418,12 +418,12 @@ private void emitWithMethodUsingBuilderInterface(TypeM builderType, TypeM selfTy
if (optional == null) {
writer.emitStatement("this.%s = false", prop.getIsSetFieldName());
} else {
writer.emitStatement("this.%s = %s", prop.getValueFieldName(), optional.absent());
writer.emitStatement("this.%s = %s", prop.getValueFieldName(), optional.absent(importTypes));
}
writer.emitStatement("return self").endMethod();
}

private void emitWithMethod(TypeM builderType, TypeM selfType, TypeM pojoType, PropertyM prop, OptionalM optional)
private void emitWithMethod(TypeM builderType, TypeM selfType, TypeM pojoType, PropertyM prop, OptionalM optional, ImportTypesM importTypes)
throws IOException {
String valueFieldName = prop.getValueFieldName();
String isSetFieldName = prop.getIsSetFieldName();
Expand Down Expand Up @@ -455,14 +455,14 @@ private void emitWithMethod(TypeM builderType, TypeM selfType, TypeM pojoType, P
writer.emitStatement("this.%s = value", valueFieldName);
writer.emitStatement("this.%s = true", isSetFieldName);
} else if (propertyType.isPrimitive()) {
writer.emitStatement("this.%s = %s", valueFieldName, optional.of("value"));
writer.emitStatement("this.%s = %s", valueFieldName, optional.of("value", importTypes));
} else {
// @formatter:off
writer
.beginControlFlow("if (%s)", "value == null")
.emitStatement("this.%s = null", valueFieldName)
.nextControlFlow("else")
.emitStatement("this.%s = %s", valueFieldName, optional.of("value"))
.emitStatement("this.%s = %s", valueFieldName, optional.of("value", importTypes))
.endControlFlow();
// @formatter:on
}
Expand Down Expand Up @@ -512,7 +512,7 @@ private void emitConstructor(TypeM builderType, TypeM selfType, Visibility visib
// @formatter:on
}

private void emitPropertyFields(PropertyM prop, TypeM interfaceType, boolean hasBuilderProperties, OptionalM optional)
private void emitPropertyFields(PropertyM prop, TypeM interfaceType, boolean hasBuilderProperties, OptionalM optional, ImportTypesM importTypes)
throws IOException {
String valueFieldName = prop.getValueFieldName();
if (optional == null) {
Expand All @@ -522,7 +522,7 @@ private void emitPropertyFields(PropertyM prop, TypeM interfaceType, boolean has
writer.emitField("boolean", isSetFieldName, EnumSet.of(PROTECTED));
} else {
writer.emitField(prop.getOptionalPropertyType(optional).getGenericType(), valueFieldName, EnumSet.of(PROTECTED),
optional.absent());
optional.absent(importTypes));
}
if (interfaceType != null && hasBuilderProperties) {
writer.emitField(prop.getParameterizedBuilderInterfaceType(interfaceType, optional).getGenericType(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import net.karneim.pojobuilder.processor.with.ProcessorTestSupport;
import net.karneim.pojobuilder.processor.with.ambiguousimports.innerclasses.PojoWithAmbiguousInnerClassImports;
import net.karneim.pojobuilder.processor.with.ambiguousimports.innerclasses.PojoWithAmbiguousInnerClassImportsBuilder;
import net.karneim.pojobuilder.processor.with.ambiguousimports.optional.PojoWithAmbiguousOptionalImports;
import net.karneim.pojobuilder.processor.with.ambiguousimports.optional.PojoWithAmbiguousOptionalImportsBuilder;
import net.karneim.pojobuilder.testenv.JavaProject.Compilation;
import org.junit.Test;

Expand All @@ -25,9 +27,7 @@ public void testShouldGenerateBuilderWithAppropriateImportProperties() {
// When:
prj.compile();
// Then:
assertThat(prj)
.generatedSameSourceAs(PojoBuilder.class)
.compiled(PojoBuilder.class)
assertThat(prj).generatedSameSourceAs(PojoBuilder.class).compiled(PojoBuilder.class)
.reported(Compilation.Success);
}

Expand All @@ -43,10 +43,24 @@ public void test_ambiguous_inner_class_imports() {
prj.compile();

// then:
assertThat(prj)
.generatedSameSourceAs(PojoWithAmbiguousInnerClassImportsBuilder.class)
.compiled(PojoWithAmbiguousInnerClassImportsBuilder.class)
.reported(Compilation.Success);
assertThat(prj).generatedSameSourceAs(PojoWithAmbiguousInnerClassImportsBuilder.class)
.compiled(PojoWithAmbiguousInnerClassImportsBuilder.class).reported(Compilation.Success);
}

/**
* * Test for issue <a href="https://github.com/mkarneim/pojobuilder/issues/156">#156</a>.
*/
@Test
public void test_ambiguous_optional_import() {
// given:
sourceFor(PojoWithAmbiguousOptionalImports.class);

// when:
prj.compile();

// then:
assertThat(prj).generatedSameSourceAs(PojoWithAmbiguousOptionalImportsBuilder.class)
.compiled(PojoWithAmbiguousOptionalImportsBuilder.class).reported(Compilation.Success);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package net.karneim.pojobuilder.processor.with.ambiguousimports.optional;

import net.karneim.pojobuilder.GeneratePojoBuilder;

@GeneratePojoBuilder(withOptionalProperties=java.util.Optional.class)
public class PojoWithAmbiguousOptionalImports {
public com.google.common.base.Optional<String> field;
}
Loading

0 comments on commit 2b578f3

Please sign in to comment.