Skip to content

Commit

Permalink
added validation for ObtainVia
Browse files Browse the repository at this point in the history
updated inspection tests for builder
updated test lombok library
projectlombok#134
  • Loading branch information
mplushnikov committed Aug 27, 2017
1 parent c17d677 commit b2ca23a
Show file tree
Hide file tree
Showing 12 changed files with 150 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public class BuilderHandler {
private static final String BUILDER_OBTAIN_VIA_FIELD = "field";
private static final String BUILDER_OBTAIN_VIA_METHOD = "method";
private static final String BUILDER_OBTAIN_VIA_STATIC = "isStatic";
public static final String BUILDER_OBTAIN_VIA_ANNOTATION = Builder.ObtainVia.class.getName().replace("$", ".");


private final ToStringProcessor toStringProcessor;
Expand Down Expand Up @@ -119,7 +120,8 @@ public boolean validate(@NotNull PsiClass psiClass, @NotNull PsiAnnotation psiAn
final String builderClassName = getBuilderClassName(psiClass, psiAnnotation);
result = validateBuilderClassName(builderClassName, psiAnnotation.getProject(), problemBuilder) &&
validateExistingBuilderClass(builderClassName, psiClass, problemBuilder) &&
validateSingular(psiClass, problemBuilder);
validateSingular(psiClass, problemBuilder) &&
validateObtainViaAnnotations(getBuilderFields(psiClass, Collections.<PsiField>emptySet(), AccessorsInfo.EMPTY), problemBuilder);
}
return result;
}
Expand Down Expand Up @@ -152,7 +154,7 @@ private boolean validateSingular(@NotNull PsiClass psiClass, @NotNull ProblemBui
private boolean validateBuilderClassName(@NotNull String builderClassName, @NotNull Project project, @NotNull ProblemBuilder builder) {
final PsiNameHelper psiNameHelper = PsiNameHelper.getInstance(project);
if (!psiNameHelper.isIdentifier(builderClassName)) {
builder.addError("%s ist not a valid identifier", builderClassName);
builder.addError("%s is not a valid identifier", builderClassName);
return false;
}
return true;
Expand Down Expand Up @@ -184,7 +186,30 @@ public boolean validate(@NotNull PsiMethod psiMethod, @NotNull PsiAnnotation psi
if (result) {
final String builderClassName = getBuilderClassName(psiClass, psiAnnotation, psiMethod);
result = validateBuilderClassName(builderClassName, psiAnnotation.getProject(), problemBuilder) &&
validateExistingBuilderClass(builderClassName, psiClass, problemBuilder);
validateExistingBuilderClass(builderClassName, psiClass, problemBuilder) &&
validateObtainViaAnnotations(getBuilderParameters(psiMethod, Collections.<PsiField>emptySet()), problemBuilder);
}
return result;
}

private boolean validateObtainViaAnnotations(@NotNull Collection<? extends PsiVariable> psiVaraibles, @NotNull ProblemBuilder problemBuilder) {
boolean result = true;
for (PsiVariable psiVariable : psiVaraibles) {
final PsiAnnotation obtainViaAnnotation = PsiAnnotationSearchUtil.findAnnotation(psiVariable, BUILDER_OBTAIN_VIA_ANNOTATION);
if (null != obtainViaAnnotation) {
final String viaFieldName = PsiAnnotationUtil.getStringAnnotationValue(obtainViaAnnotation, BUILDER_OBTAIN_VIA_FIELD);
final String viaMethodName = PsiAnnotationUtil.getStringAnnotationValue(obtainViaAnnotation, BUILDER_OBTAIN_VIA_METHOD);
final boolean viaStaticCall = PsiAnnotationUtil.getBooleanAnnotationValue(obtainViaAnnotation, BUILDER_OBTAIN_VIA_STATIC, false);

if (StringUtils.isEmpty(viaFieldName) == StringUtils.isEmpty(viaMethodName)) {
problemBuilder.addError("The syntax is either @ObtainVia(field = \"fieldName\") or @ObtainVia(method = \"methodName\").");
result = false;
}
if (StringUtils.isEmpty(viaMethodName) && viaStaticCall) {
problemBuilder.addError("@ObtainVia(isStatic = true) is not valid unless 'method' has been set.");
result = false;
}
}
}
return result;
}
Expand Down Expand Up @@ -330,7 +355,7 @@ private PsiCodeBlock createToBuilderMethodCodeBlock(@NotNull PsiClass psiClass,
methodCalls.append(accessorsInfo.removePrefix(psiVariable.getName()));
methodCalls.append('(');

final PsiAnnotation obtainViaAnnotation = PsiAnnotationSearchUtil.findAnnotation(psiVariable, Builder.ObtainVia.class.getName().replace("$", "."));
final PsiAnnotation obtainViaAnnotation = PsiAnnotationSearchUtil.findAnnotation(psiVariable, BUILDER_OBTAIN_VIA_ANNOTATION);
if (null != obtainViaAnnotation) {
final String viaFieldName = PsiAnnotationUtil.getStringAnnotationValue(obtainViaAnnotation, BUILDER_OBTAIN_VIA_FIELD);
final String viaMethodName = PsiAnnotationUtil.getStringAnnotationValue(obtainViaAnnotation, BUILDER_OBTAIN_VIA_METHOD);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,6 @@ public void testIssue37() throws Exception {
doTest();
}

public void testBuilderRightType() throws Exception {
doTest();
}

public void testBuilderInvalidIdentifier() throws Exception {
doTest();
}

public void testDelegateConcreteType() throws Exception {
doTest();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package de.plushnikov.intellij.plugin.inspection;

import com.intellij.codeInspection.InspectionProfileEntry;

public class BuilderInspectionTest extends LombokInspectionTest {

@Override
protected String getTestDataPath() {
return TEST_DATA_INSPECTION_DIRECTORY + "/builder";
}

@Override
protected InspectionProfileEntry getInspection() {
return new LombokInspection();
}

public void testBuilderInvalidIdentifier() throws Exception {
doTest();
}

public void testBuilderRightType() throws Exception {
doTest();
}

public void testBuilderInvalidUse() throws Exception {
doTest();
}

public void testBuilderObtainVia() throws Exception {
doTest();
}

public void testBuilderDefaultsWarnings() throws Exception {
//TODO implement test after adding support for Builder.Default
doTest();
}
}
15 changes: 15 additions & 0 deletions testData/inspection/builder/BuilderDefaultsWarnings.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@lombok.Builder
public class BuilderDefaultsWarnings {
long x = System.currentTimeMillis();
final int y = 5;
@lombok.Builder.Default int z;
@lombok.Builder.Default @lombok.Singular java.util.List<String> items;
}

class NoBuilderButHasDefaults {
@lombok.Builder.Default private final long z = 5;

@lombok.Builder
public NoBuilderButHasDefaults() {
}
}
4 changes: 4 additions & 0 deletions testData/inspection/builder/BuilderInvalidIdentifier.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<error descr="invalid^identifier is not a valid identifier">@lombok.Builder(builderClassName = "invalid^identifier")</error>
public class BuilderInvalidIdentifier {
private String field;
}
19 changes: 19 additions & 0 deletions testData/inspection/builder/BuilderInvalidUse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//skip compare content
<error descr="Lombok annotations are not allowed on builder class.">@lombok.Builder</error>
class BuilderInvalidUse {
private int something;

@lombok.Getter @lombok.Setter @lombok.experimental.FieldDefaults(makeFinal = true) @lombok.experimental.Wither @lombok.Data @lombok.ToString @lombok.EqualsAndHashCode
@lombok.AllArgsConstructor
public static class BuilderInvalidUseBuilder {

}
}

<error descr="Lombok annotations are not allowed on builder class.">@lombok.Builder</error>
class AlsoInvalid {
@lombok.Value
public static class AlsoInvalidBuilder {

}
}
39 changes: 39 additions & 0 deletions testData/inspection/builder/BuilderObtainVia.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<error descr="The syntax is either @ObtainVia(field = \"fieldName\") or @ObtainVia(method = \"methodName\").">@lombok.Builder</error>
class BuilderObtainVia {

private String field1;

@lombok.Builder.ObtainVia
private String field2;

public String someMethod() {
return "someValue";
}
}

<error descr="The syntax is either @ObtainVia(field = \"fieldName\") or @ObtainVia(method = \"methodName\").">@lombok.Builder</error>
class BuilderObtainViaFieldAndMethod {

private String field1;

@lombok.Builder.ObtainVia(field = "field1", method = "someMethod")
private String field2;

public String someMethod() {
return "someValue";
}
}

<error descr="@ObtainVia(isStatic = true) is not valid unless 'method' has been set.">@lombok.Builder</error>
class BuilderObtainViaFieldStatic {

private static String field1;

@lombok.Builder.ObtainVia(field = "field1", isStatic=true)
private String field2;

public String someMethod() {
return "someValue";
}
}

Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
@lombok.Builder
<error descr="@lombok.Builder can be used on classes only">@lombok.Builder</error>
enum BuilderEnumError {
}

@lombok.Builder
<error descr="@lombok.Builder can be used on classes only">@lombok.Builder</error>
interface BuilderInterfaceError {
}

@lombok.Builder
<error descr="@lombok.Builder can be used on classes only">@lombok.Builder</error>
@interface BuilderAnnotationError {
}

Expand Down Expand Up @@ -36,16 +36,16 @@ public void makeMe(int x) {
System.out.println(x);
}
}
import lombok.ToString;
@lombok.Builder

<error descr="Lombok annotations are not allowed on builder class.">@lombok.Builder</error>
class BuilderWithPredefinedClassAnnotation {
private int x;
private Float y;
private String z;

@ToString
@lombok.ToString
static class BuilderWithPredefinedClassAnnotationBuilder {
private int x;
}

}
}
8 changes: 0 additions & 8 deletions testData/inspection/builderInvalidIdentifier/expected.xml

This file was deleted.

3 changes: 0 additions & 3 deletions testData/inspection/builderInvalidIdentifier/src/Test.java

This file was deleted.

23 changes: 0 additions & 23 deletions testData/inspection/builderRightType/expected.xml

This file was deleted.

Binary file modified testData/inspection/lib/lombok.jar
Binary file not shown.

0 comments on commit b2ca23a

Please sign in to comment.