From a9d29896887ee35903bcb847eb4307637801bcc2 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Sun, 26 Jul 2009 09:15:28 +0200 Subject: Addresses issue #4: If boolean fields already start with a typical getter prefix (is, has, or get), lombok's @Getter will no longer generate its own prefix as well, so a field named 'hasFoo' will result in a getter named 'hasFoo()', not 'isHasFoo()'. Also, if any likely getter name already exists for a boolean, a getter will not be generated. Thus, if your field is called 'hasFoo', and you already have a method named 'isFoo', then @Getter will not generate anything (and warn, unless the getter is being generated due to @Data). This last mechanism works by taking the field name *AND* any other likely base names (defined by the field name being named as prefix+baseName, with prefix being is/has/get), and then prefixing all the likely fieldnames with is/has/get, and checking if any method with that name exists. Of course, this means weird things are going to happen if you have 2 fields named 'isFoo' and 'hasFoo', but then, you'd be a real idiot if you did that. --- src/lombok/core/TransformationsUtil.java | 57 ++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'src/lombok/core') diff --git a/src/lombok/core/TransformationsUtil.java b/src/lombok/core/TransformationsUtil.java index bc30fecc..12b90d0e 100644 --- a/src/lombok/core/TransformationsUtil.java +++ b/src/lombok/core/TransformationsUtil.java @@ -21,6 +21,13 @@ */ package lombok.core; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + /** * Container for static utility methods useful for some of the standard lombok transformations, regardless of * target platform (e.g. useful for both javac and Eclipse lombok implementations). @@ -30,6 +37,10 @@ public class TransformationsUtil { //Prevent instantiation } + private static final List KNOWN_BOOLEAN_PREFIXES = Collections.unmodifiableList(Arrays.asList( + "is", "has", "get" + )); + /** * Generates a getter name from a given field name. * @@ -42,6 +53,10 @@ public class TransformationsUtil { * * return the prefix plus the possibly title/uppercased first character, and the rest of the field name. * + * Note that for boolean fields, if the field starts with 'has', 'get', or 'is', and the character after that is + * not a lowercase character, the field name is returned without changing any character's case and without + * any prefix. + * * @param fieldName the name of the field. * @param isBoolean if the field is of type 'boolean'. For fields of type 'java.lang.Boolean', you should provide false. */ @@ -50,6 +65,17 @@ public class TransformationsUtil { if ( fieldName.length() == 0 ) return prefix; + for ( String knownBooleanPrefix : KNOWN_BOOLEAN_PREFIXES ) { + if ( !fieldName.toString().startsWith(knownBooleanPrefix) ) continue; + if ( fieldName.length() > knownBooleanPrefix.length() && + !Character.isLowerCase(fieldName.charAt(knownBooleanPrefix.length())) ) { + //The field is called something like 'isFoo' or 'hasFoo' or 'getFoo', so we shouldn't + //prefix with 'is' but instead just use the field name as is. The isLowerCase check is so we don't turn + //hashCodeGenerated, which so happens to start with 'has', into hasHCodeGenerated instead of isHashCodeGenerated. + return fieldName.toString(); + } + } + return buildName(prefix, fieldName.toString()); } @@ -82,4 +108,35 @@ public class TransformationsUtil { } return String.format("%s%s", prefix, suffix); } + + public static List toAllGetterNames(CharSequence fieldName, boolean isBoolean) { + if ( !isBoolean ) return Collections.singletonList(toGetterName(fieldName, false)); + + List baseNames = new ArrayList(); + baseNames.add(fieldName.toString()); + for ( String knownBooleanPrefix : KNOWN_BOOLEAN_PREFIXES ) { + if ( !fieldName.toString().startsWith(knownBooleanPrefix) ) continue; + if ( fieldName.length() > knownBooleanPrefix.length() && + !Character.isLowerCase(fieldName.charAt(knownBooleanPrefix.length())) ) { + //The field is called something like 'isFoo' or 'hasFoo' or 'getFoo', so the practical fieldname + //could also be 'foo'. + baseNames.add(fieldName.toString().substring(knownBooleanPrefix.length())); + //prefix with 'is' but instead just use the field name as is. The isLowerCase check is so we don't turn + //hashCodeGenerated, which so happens to start with 'has', into hasHCodeGenerated instead of isHashCodeGenerated. + } + } + + Set names = new HashSet(); + for ( String baseName : baseNames ) { + if ( baseName.length() > 0 && Character.isLowerCase(baseName.charAt(0)) ) { + baseName = Character.toTitleCase(baseName.charAt(0)) + baseName.substring(1); + } + + for ( String prefix : KNOWN_BOOLEAN_PREFIXES ) { + names.add(prefix + baseName); + } + } + + return new ArrayList(names); + } } -- cgit