Skip to content
This repository has been archived by the owner on Nov 3, 2024. It is now read-only.

Commit

Permalink
Fixed #95 Fluent Setter Override Error
Browse files Browse the repository at this point in the history
  • Loading branch information
Michail Plushnikov committed Apr 11, 2015
1 parent 25bc07c commit c03e13b
Show file tree
Hide file tree
Showing 21 changed files with 1,007 additions and 193 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,15 @@
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.containers.ContainerUtil;
import de.plushnikov.intellij.plugin.processor.field.AccessorsInfo;
import de.plushnikov.intellij.plugin.processor.field.SetterFieldProcessor;
import de.plushnikov.intellij.plugin.thirdparty.LombokUtils;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;

import java.util.Set;

public class LombokFieldFindUsagesHandlerFactory extends JavaFindUsagesHandlerFactory {
private final SetterFieldProcessor setterFieldProcessor;

public LombokFieldFindUsagesHandlerFactory(Project project) {
super(project);
setterFieldProcessor = new SetterFieldProcessor();
}

@Override
Expand All @@ -48,8 +45,8 @@ public PsiElement[] getSecondaryElements() {
if (!fieldName.equals(psiFieldName)) {
final boolean isBoolean = PsiType.BOOLEAN.equals(psiField.getType());

final String getterName = setterFieldProcessor.getGetterName(accessorsInfo, psiFieldName, isBoolean, containingClass);
final String setterName = setterFieldProcessor.getSetterName(accessorsInfo, psiFieldName, isBoolean);
final String getterName = LombokUtils.toGetterName(accessorsInfo, psiFieldName, isBoolean);
final String setterName = LombokUtils.toSetterName(accessorsInfo, psiFieldName, isBoolean);

final PsiMethod[] psiGetterMethods = containingClass.findMethodsByName(getterName, false);
final PsiMethod[] psiSetterMethods = containingClass.findMethodsByName(setterName, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,14 @@
import com.intellij.psi.PsiType;
import com.intellij.refactoring.rename.RenameJavaVariableProcessor;
import de.plushnikov.intellij.plugin.processor.field.AccessorsInfo;
import de.plushnikov.intellij.plugin.processor.field.SetterFieldProcessor;
import de.plushnikov.intellij.plugin.thirdparty.LombokUtils;
import org.jetbrains.annotations.NotNull;

import java.util.Map;

public class LombokRenameFieldReferenceProcessor extends RenameJavaVariableProcessor {

private final SetterFieldProcessor setterFieldProcessor;

public LombokRenameFieldReferenceProcessor() {
setterFieldProcessor = new SetterFieldProcessor();
}

@Override
Expand All @@ -44,18 +41,18 @@ public void prepareRenaming(PsiElement element, String newName, Map<PsiElement,
final String psiFieldName = psiField.getName();
final boolean isBoolean = PsiType.BOOLEAN.equals(psiField.getType());

final String getterName = setterFieldProcessor.getGetterName(accessorsInfo, psiFieldName, isBoolean, containingClass);
final String setterName = setterFieldProcessor.getSetterName(accessorsInfo, psiFieldName, isBoolean);
final String getterName = LombokUtils.toGetterName(accessorsInfo, psiFieldName, isBoolean);
final String setterName = LombokUtils.toSetterName(accessorsInfo, psiFieldName, isBoolean);

final PsiMethod[] psiGetterMethods = containingClass.findMethodsByName(getterName, false);
final PsiMethod[] psiSetterMethods = containingClass.findMethodsByName(setterName, false);

for (PsiMethod psiMethod : psiGetterMethods) {
allRenames.put(psiMethod, setterFieldProcessor.getGetterName(accessorsInfo, newName, isBoolean, containingClass));
allRenames.put(psiMethod, LombokUtils.toGetterName(accessorsInfo, newName, isBoolean));
}

for (PsiMethod psiMethod : psiSetterMethods) {
allRenames.put(psiMethod, setterFieldProcessor.getSetterName(accessorsInfo, newName, isBoolean));
allRenames.put(psiMethod, LombokUtils.toSetterName(accessorsInfo, newName, isBoolean));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import de.plushnikov.intellij.plugin.language.LombokConfigLanguage;
import org.jetbrains.annotations.NotNull;

import javax.swing.Icon;
import javax.swing.*;

public class LombokConfigFile extends PsiFileBase {
public LombokConfigFile(@NotNull FileViewProvider viewProvider) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,31 +94,20 @@ public List<? super PsiElement> process(@NotNull PsiClass psiClass) {
@NotNull
public abstract Collection<PsiAnnotation> collectProcessedAnnotations(@NotNull PsiClass psiClass);

protected String getGetterName(final @NotNull PsiField psiField, final @NotNull PsiClass psiClass) {
protected String getGetterName(final @NotNull PsiField psiField) {
final AccessorsInfo accessorsInfo = AccessorsInfo.build(psiField);

final String psiFieldName = psiField.getName();
final boolean isBoolean = PsiType.BOOLEAN.equals(psiField.getType());

return getGetterName(accessorsInfo, psiFieldName, isBoolean, psiClass);
return LombokUtils.toGetterName(accessorsInfo, psiFieldName, isBoolean);
}

public String getGetterName(AccessorsInfo accessorsInfo, String psiFieldName, boolean isBoolean, PsiClass psiClass) {
final String fieldNameWithoutPrefix = accessorsInfo.removePrefix(psiFieldName);
if (accessorsInfo.isFluent()) {
return LombokUtils.decapitalize(fieldNameWithoutPrefix);
}

final boolean useBooleanPrefix = isBoolean && !ConfigDiscovery.getInstance().getBooleanLombokConfigProperty(ConfigKeys.GETTER_NO_IS_PREFIX, psiClass);

return LombokUtils.toGetterName(fieldNameWithoutPrefix, useBooleanPrefix);
}

protected void filterToleratedElements(@NotNull Collection<? extends PsiModifierListOwner> definedConstructors) {
final Iterator<? extends PsiModifierListOwner> methodIterator = definedConstructors.iterator();
protected void filterToleratedElements(@NotNull Collection<? extends PsiModifierListOwner> definedMethods) {
final Iterator<? extends PsiModifierListOwner> methodIterator = definedMethods.iterator();
while (methodIterator.hasNext()) {
PsiModifierListOwner definedConstructor = methodIterator.next();
if (PsiAnnotationUtil.isAnnotatedWith(definedConstructor, Tolerate.class)) {
PsiModifierListOwner definedMethod = methodIterator.next();
if (PsiAnnotationUtil.isAnnotatedWith(definedMethod, Tolerate.class)) {
methodIterator.remove();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ protected String buildAttributeNameString(boolean doNotUseGetters, @NotNull PsiF
if (doNotUseGetters) {
return fieldName;
} else {
final String getterName = getGetterName(classField, psiClass);
final String getterName = getGetterName(classField);

boolean hasGetter = PsiMethodUtil.hasMethodByName(PsiClassUtil.collectClassMethodsIntern(psiClass), getterName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.intellij.psi.PsiModifierList;
import com.intellij.psi.PsiType;
import de.plushnikov.intellij.plugin.problem.ProblemBuilder;
import de.plushnikov.intellij.plugin.processor.field.AccessorsInfo;
import de.plushnikov.intellij.plugin.processor.field.GetterFieldProcessor;
import de.plushnikov.intellij.plugin.thirdparty.LombokUtils;
import de.plushnikov.intellij.plugin.util.LombokProcessorUtil;
Expand Down Expand Up @@ -85,7 +86,8 @@ public Collection<PsiMethod> createFieldGetters(@NotNull PsiClass psiClass, @Not
//Skip fields that start with $
createGetter &= !psiField.getName().startsWith(LombokUtils.LOMBOK_INTERN_FIELD_MARKER);
//Skip fields if a method with same name and arguments count already exists
final Collection<String> methodNames = LombokUtils.toAllGetterNames(psiField.getName(), PsiType.BOOLEAN.equals(psiField.getType()));
final AccessorsInfo accessorsInfo = AccessorsInfo.build(psiField);
final Collection<String> methodNames = LombokUtils.toAllGetterNames(accessorsInfo, psiField.getName(), PsiType.BOOLEAN.equals(psiField.getType()));
for (String methodName : methodNames) {
createGetter &= !PsiMethodUtil.hasSimilarMethod(classMethods, methodName, 0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiField;
import de.plushnikov.intellij.plugin.lombokconfig.ConfigDiscovery;
import de.plushnikov.intellij.plugin.lombokconfig.ConfigKeys;
import de.plushnikov.intellij.plugin.processor.AbstractProcessor;
import de.plushnikov.intellij.plugin.util.PsiAnnotationUtil;
Expand All @@ -15,8 +16,6 @@
import java.util.Collection;

/**
* Date: 19.07.13 Time: 23:46
*
* @author Plushnikov Michail
*/
public class AccessorsInfo {
Expand All @@ -25,17 +24,19 @@ public class AccessorsInfo {
private final boolean fluent;
private final boolean chain;
private final String[] prefixes;
private final boolean dontUseIsPrefix;

protected AccessorsInfo() {
this(false, false);
}

protected AccessorsInfo(boolean fluentValue, boolean chainValue, String... prefixes) {
protected AccessorsInfo(boolean fluentValue, boolean chainValue, boolean dontUseIsPrefix, String... prefixes) {
this.fluent = fluentValue;
this.chain = chainValue;
this.dontUseIsPrefix = dontUseIsPrefix;
this.prefixes = null == prefixes ? new String[0] : prefixes;
}

public static AccessorsInfo build(boolean fluentValue, boolean chainValue, boolean dontUseIsPrefix, String... prefixes) {
return new AccessorsInfo(fluentValue, chainValue, dontUseIsPrefix, prefixes);
}

public static AccessorsInfo build(@NotNull PsiField psiField) {
final PsiAnnotation accessorsFieldAnnotation = AnnotationUtil.findAnnotation(psiField, ACCESSORS_ANNOTATION_NAME);
final PsiClass containingClass = psiField.getContainingClass();
Expand All @@ -55,7 +56,7 @@ public static AccessorsInfo build(@Nullable PsiClass psiClass) {
}
containingClass = containingClass.getContainingClass();
}
return new AccessorsInfo();
return build(false, false, false);
}

private static AccessorsInfo buildFromAnnotation(PsiAnnotation accessorsAnnotation, PsiClass psiClass) {
Expand All @@ -65,8 +66,10 @@ private static AccessorsInfo buildFromAnnotation(PsiAnnotation accessorsAnnotati
Boolean chainDeclaredValue = PsiAnnotationUtil.getDeclaredAnnotationValue(accessorsAnnotation, "chain", Boolean.class);
Collection<String> prefixes = PsiAnnotationUtil.getAnnotationValues(accessorsAnnotation, "prefix", String.class);

final boolean dontUseIsPrefix = ConfigDiscovery.getInstance().getBooleanLombokConfigProperty(ConfigKeys.GETTER_NO_IS_PREFIX, psiClass);

boolean isChainDeclaredOrImplicit = isChained || (isFluent && null == chainDeclaredValue);
return new AccessorsInfo(isFluent, isChainDeclaredOrImplicit, prefixes.toArray(new String[prefixes.size()]));
return new AccessorsInfo(isFluent, isChainDeclaredOrImplicit, dontUseIsPrefix, prefixes.toArray(new String[prefixes.size()]));
}

public boolean isFluent() {
Expand All @@ -77,6 +80,14 @@ public boolean isChain() {
return chain;
}

public boolean isDontUseIsPrefix() {
return dontUseIsPrefix;
}

public String[] getPrefixes() {
return prefixes;
}

public boolean prefixDefinedAndStartsWith(String fieldName) {
if (prefixes.length == 0) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,13 @@ protected boolean validateExistingMethods(@NotNull PsiField psiField, @NotNull P
final PsiClass psiClass = psiField.getContainingClass();
if (null != psiClass) {
final boolean isBoolean = PsiType.BOOLEAN.equals(psiField.getType());
final Collection<String> methodNames = LombokUtils.toAllGetterNames(psiField.getName(), isBoolean);
final AccessorsInfo accessorsInfo = AccessorsInfo.build(psiField);
final Collection<String> methodNames = LombokUtils.toAllGetterNames(accessorsInfo, psiField.getName(), isBoolean);
final Collection<PsiMethod> classMethods = PsiClassUtil.collectClassMethodsIntern(psiClass);

for (String methodName : methodNames) {
if (PsiMethodUtil.hasSimilarMethod(classMethods, methodName, 0)) {
final String setterMethodName = LombokUtils.toGetterName(psiField.getName(), isBoolean);
final String setterMethodName = getGetterName(psiField);

builder.addWarning("Not generated '%s'(): A method with similar name '%s' already exists", setterMethodName, methodName);
result = false;
Expand All @@ -119,7 +120,7 @@ protected boolean validateAccessorPrefix(@NotNull PsiField psiField, @NotNull Pr

@NotNull
public PsiMethod createGetterMethod(@NotNull PsiField psiField, @NotNull PsiClass psiClass, @NotNull String methodModifier) {
final String methodName = getGetterName(psiField, psiClass);
final String methodName = getGetterName(psiField);

LombokLightMethodBuilder method = new LombokLightMethodBuilder(psiField.getManager(), methodName)
.withMethodReturnType(psiField.getType())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,23 +111,15 @@ protected boolean validateAccessorPrefix(@NotNull PsiField psiField, @NotNull Pr
return result;
}

public List<String> getAllSetterNames(@NotNull PsiField psiField, boolean isBoolean) {
return LombokUtils.toAllSetterNames(psiField.getName(), isBoolean);
public Collection<String> getAllSetterNames(@NotNull PsiField psiField, boolean isBoolean) {
final AccessorsInfo accessorsInfo = AccessorsInfo.build(psiField);
return LombokUtils.toAllSetterNames(accessorsInfo, psiField.getName(), isBoolean);
}

protected String getSetterName(@NotNull PsiField psiField, boolean isBoolean) {
final AccessorsInfo accessorsInfo = AccessorsInfo.build(psiField);

final String psiFieldName = psiField.getName();
return getSetterName(accessorsInfo, psiFieldName, isBoolean);
}

public String getSetterName(AccessorsInfo accessorsInfo, String psiFieldName, boolean isBoolean) {
final String fieldNameWithoutPrefix = accessorsInfo.removePrefix(psiFieldName);
if (accessorsInfo.isFluent()) {
return LombokUtils.decapitalize(fieldNameWithoutPrefix);
}
return LombokUtils.toSetterName(fieldNameWithoutPrefix, isBoolean);
return LombokUtils.toSetterName(accessorsInfo, psiField.getName(), isBoolean);
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package de.plushnikov.intellij.plugin.processor.field;

import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
Expand Down Expand Up @@ -34,8 +33,6 @@

public class WitherFieldProcessor extends AbstractFieldProcessor {

private static final String WITHER_PREFIX = "with";

private final RequiredArgsConstructorProcessor requiredArgsConstructorProcessor = new RequiredArgsConstructorProcessor();

public WitherFieldProcessor() {
Expand Down Expand Up @@ -105,18 +102,19 @@ private boolean validIsWitherUnique(@NotNull PsiField psiField, @NotNull final P
if (psiFieldName != null && fieldContainingClass != null) {
final Collection<PsiMethod> classMethods = PsiClassUtil.collectClassMethodsIntern(fieldContainingClass);

final String witherName = getWitherName(psiField);
final String defaultWitherName = defaultWitherName(psiFieldName);

if (PsiMethodUtil.hasSimilarMethod(classMethods, witherName, 1) ||
(!witherName.equals(defaultWitherName) && PsiMethodUtil.hasSimilarMethod(classMethods, defaultWitherName, 1))) {
builder.addWarning("Not generating %s(): A method with that name already exists", witherName);
return false;
final AccessorsInfo accessorsInfo = AccessorsInfo.build(psiField);
final Collection<String> possibleWitherNames = LombokUtils.toAllWitherNames(accessorsInfo, psiFieldName, PsiType.BOOLEAN.equals(psiField.getType()));
for (String witherName : possibleWitherNames) {
if (PsiMethodUtil.hasSimilarMethod(classMethods, witherName, 1)) {
builder.addWarning("Not generating %s(): A method with that name already exists", witherName);
return false;
}
}
}
return true;
}

@SuppressWarnings("deprecation")
public boolean validConstructor(@NotNull PsiClass psiClass, @NotNull ProblemBuilder builder) {
if (PsiAnnotationUtil.isAnnotatedWith(psiClass, AllArgsConstructor.class, Value.class, lombok.experimental.Value.class)) {
return true;
Expand Down Expand Up @@ -177,7 +175,7 @@ public PsiMethod createWitherMethod(@NotNull PsiField psiField, @NotNull String
final String psiFieldName = psiField.getName();
final PsiType psiFieldType = psiField.getType();

result = new LombokLightMethodBuilder(psiField.getManager(), getWitherName(psiField, accessorsInfo))
result = new LombokLightMethodBuilder(psiField.getManager(), getWitherName(accessorsInfo, psiFieldName, psiFieldType))
.withMethodReturnType(returnType)
.withContainingClass(psiFieldContainingClass)
.withNavigationElement(psiField)
Expand All @@ -194,25 +192,8 @@ public PsiMethod createWitherMethod(@NotNull PsiField psiField, @NotNull String
return result;
}

private String getWitherName(@NotNull PsiField psiField) {
AccessorsInfo accessorsInfo = AccessorsInfo.build(psiField);
return getWitherName(psiField, accessorsInfo);
}

private String getWitherName(@NotNull PsiField psiField, @NotNull AccessorsInfo accessorsInfo) {
return witherName(accessorsInfo.removePrefix(psiField.getName()), PsiType.BOOLEAN.equals(psiField.getType()));
}

private String witherName(String fieldName, boolean isBoolean) {
if (isBoolean && fieldName.startsWith("is") && fieldName.length() > 2 && Character.isUpperCase(fieldName.charAt(2))) {
return WITHER_PREFIX + fieldName.substring(2);
} else {
return defaultWitherName(fieldName);
}
}

private String defaultWitherName(String fieldName) {
return WITHER_PREFIX + StringUtil.capitalize(fieldName);
private String getWitherName(@NotNull AccessorsInfo accessorsInfo, String psiFieldName, PsiType psiFieldType) {
return LombokUtils.toWitherName(accessorsInfo, psiFieldName, PsiType.BOOLEAN.equals(psiFieldType));
}

private String getConstructorCall(@NotNull PsiField psiField, @NotNull PsiClass psiClass) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import lombok.FluentSetter;
import org.jetbrains.annotations.NotNull;

import java.util.Arrays;
import java.util.List;
import java.util.Collection;
import java.util.Collections;

/**
* Inspect and validate @FluentSetter lombok-pg annotation on a field
Expand All @@ -25,8 +25,8 @@ public FluentSetterFieldProcessor() {
}

@Override
public List<String> getAllSetterNames(@NotNull PsiField psiField, boolean isBoolean) {
return Arrays.asList(getSetterName(psiField, isBoolean));
public Collection<String> getAllSetterNames(@NotNull PsiField psiField, boolean isBoolean) {
return Collections.singletonList(getSetterName(psiField, isBoolean));
}

@Override
Expand Down
Loading

0 comments on commit c03e13b

Please sign in to comment.