diff options
Diffstat (limited to 'src')
38 files changed, 889 insertions, 360 deletions
diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java index dda0b54b..ef433d8d 100644 --- a/src/core/lombok/ConfigurationKeys.java +++ b/src/core/lombok/ConfigurationKeys.java @@ -24,6 +24,7 @@ package lombok; import java.util.List; import lombok.core.configuration.CallSuperType; +import lombok.core.configuration.CheckerFrameworkVersion; import lombok.core.configuration.ConfigurationKey; import lombok.core.configuration.LogDeclaration; import lombok.core.configuration.FlagUsageType; @@ -353,6 +354,15 @@ public class ConfigurationKeys { public static final ConfigurationKey<FlagUsageType> VAL_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.val.flagUsage", "Emit a warning or error if 'val' is used.") {}; public static final ConfigurationKey<FlagUsageType> VAR_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.var.flagUsage", "Emit a warning or error if 'var' is used.") {}; + // ----- With ----- + + /** + * lombok configuration: {@code lombok.with.flagUsage} = {@code WARNING} | {@code ERROR}. + * + * If set, <em>any</em> usage of {@code @With} results in a warning / error. + */ + public static final ConfigurationKey<FlagUsageType> WITH_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.with.flagUsage", "Emit a warning or error if @With is used.") {}; + // ##### Extern ##### // ----- Logging ----- @@ -592,15 +602,6 @@ public class ConfigurationKeys { */ public static final ConfigurationKey<Boolean> FIELD_NAME_CONSTANTS_UPPERCASE = new ConfigurationKey<Boolean>("lombok.fieldNameConstants.uppercase", "The default name of the constants inside the inner type generated by @FieldNameConstants follow the variable name precisely. If this config key is true, lombok will uppercase them as best it can. (default: false).") {}; - // ----- Wither ----- - - /** - * lombok configuration: {@code lombok.wither.flagUsage} = {@code WARNING} | {@code ERROR}. - * - * If set, <em>any</em> usage of {@code @Wither} results in a warning / error. - */ - public static final ConfigurationKey<FlagUsageType> WITHER_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.wither.flagUsage", "Emit a warning or error if @Wither is used.") {}; - // ----- SuperBuilder ----- /** @@ -624,8 +625,17 @@ public class ConfigurationKeys { /** * lombok configuration: {@code lombok.copyableAnnotations} += <TypeName: fully-qualified annotation class name>. * - * Copy these annotations to getters, setters, withers, builder-setters, etc. + * Copy these annotations to getters, setters, with methods, builder-setters, etc. + */ + public static final ConfigurationKey<List<TypeName>> COPYABLE_ANNOTATIONS = new ConfigurationKey<List<TypeName>>("lombok.copyableAnnotations", "Copy these annotations to getters, setters, with methods, builder-setters, etc.") {}; + + /** + * lombok configuration: {@code checkerframework} = {@code true} | {@code false} | <String: MajorVer.MinorVer> (Default: false). + * + * If set, lombok will generate appropriate annotations from checkerframework.org on generated code. If set to {@code true}, all relevant annotations from the most recent version of + * checkerframework.org that lombok supports will be generated. If set to a specific major/minor version number, only checkerframework annotations introduced on or before the stated + * checkerframework.org version will be generated. */ - public static final ConfigurationKey<List<TypeName>> COPYABLE_ANNOTATIONS = new ConfigurationKey<List<TypeName>>("lombok.copyableAnnotations", "Copy these annotations to getters, setters, withers, builder-setters, etc.") {}; + public static final ConfigurationKey<CheckerFrameworkVersion> CHECKER_FRAMEWORK = new ConfigurationKey<CheckerFrameworkVersion>("checkerframework", "If set with the version of checkerframework.org (in major.minor, or just 'true' for the latest supported version), create relevant checkerframework.org annotations for code lombok generates (default: false).") {}; } diff --git a/src/core/lombok/With.java b/src/core/lombok/With.java new file mode 100644 index 00000000..141d1fa6 --- /dev/null +++ b/src/core/lombok/With.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2012-2019 The Project Lombok Authors. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import lombok.AccessLevel; + +/** + * Put on any field to make lombok build a 'with' - a withX method which produces a clone of this object (except for 1 field which gets a new value). + * <p> + * Complete documentation is found at <a href="https://projectlombok.org/features/With">the project lombok features page for @With</a>. + * <p> + * Example: + * <pre> + * private @With final int foo; + * </pre> + * + * will generate: + * + * <pre> + * public SELF_TYPE withFoo(int foo) { + * return this.foo == foo ? this : new SELF_TYPE(otherField1, otherField2, foo); + * } + * </pre> + * <p> + * This annotation can also be applied to a class, in which case it'll be as if all non-static fields that don't already have + * a {@code With} annotation have the annotation. + */ +@Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RetentionPolicy.SOURCE) +public @interface With { + /** + * If you want your with method to be non-public, you can specify an alternate access level here. + * + * @return The method will be generated with this access modifier. + */ + AccessLevel value() default AccessLevel.PUBLIC; + + /** + * Any annotations listed here are put on the generated method. + * The syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).<br> + * up to JDK7:<br> + * {@code @With(onMethod=@__({@AnnotationsGoHere}))}<br> + * from JDK8:<br> + * {@code @With(onMethod_={@AnnotationsGohere})} // note the underscore after {@code onMethod}. + * + * @return List of annotations to apply to the generated method. + */ + AnyAnnotation[] onMethod() default {}; + + /** + * Any annotations listed here are put on the generated method's parameter. + * The syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).<br> + * up to JDK7:<br> + * {@code @With(onParam=@__({@AnnotationsGoHere}))}<br> + * from JDK8:<br> + * {@code @With(onParam_={@AnnotationsGohere})} // note the underscore after {@code onParam}. + * + * @return List of annotations to apply to the generated parameter in the method. + */ + AnyAnnotation[] onParam() default {}; + + /** + * Placeholder annotation to enable the placement of annotations on the generated code. + * @deprecated Don't use this annotation, ever - Read the documentation. + */ + @Deprecated + @Retention(RetentionPolicy.SOURCE) + @Target({}) + @interface AnyAnnotation {} +} diff --git a/src/core/lombok/core/LombokInternalAliasing.java b/src/core/lombok/core/LombokInternalAliasing.java index c1089580..68ced84f 100644 --- a/src/core/lombok/core/LombokInternalAliasing.java +++ b/src/core/lombok/core/LombokInternalAliasing.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2018 The Project Lombok Authors. + * Copyright (C) 2013-2019 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -21,6 +21,7 @@ */ package lombok.core; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -30,6 +31,7 @@ public class LombokInternalAliasing { /** Maps a package name to a space separated list of packages. If the key package is star-imported, assume all packages in the 'value' part of the MapEntry are too. */ public static final Map<String, Collection<String>> IMPLIED_EXTRA_STAR_IMPORTS; public static final Map<String, String> ALIASES; + public static final Map<String, Collection<String>> REVERSE_ALIASES; /** * Provide a fully qualified name (FQN), and the canonical version of this is returned. @@ -51,6 +53,26 @@ public class LombokInternalAliasing { m2.put("lombok.experimental.Builder", "lombok.Builder"); m2.put("lombok.experimental.var", "lombok.var"); m2.put("lombok.Delegate", "lombok.experimental.Delegate"); + m2.put("lombok.experimental.Wither", "lombok.With"); ALIASES = Collections.unmodifiableMap(m2); + + Map<String, Collection<String>> m3 = new HashMap<String, Collection<String>>(); + for (Map.Entry<String, String> e : m2.entrySet()) { + Collection<String> c = m3.get(e.getValue()); + if (c == null) { + m3.put(e.getValue(), Collections.singleton(e.getKey())); + } else if (c.size() == 1) { + Collection<String> newC = new ArrayList<String>(2); + newC.addAll(c); + m3.put(e.getValue(), c); + } else { + c.add(e.getKey()); + } + } + for (Map.Entry<String, Collection<String>> e : m3.entrySet()) { + Collection<String> c = e.getValue(); + if (c.size() > 1) e.setValue(Collections.unmodifiableList((ArrayList<String>) c)); + } + REVERSE_ALIASES = Collections.unmodifiableMap(m3); } } diff --git a/src/core/lombok/core/TypeLibrary.java b/src/core/lombok/core/TypeLibrary.java index ceaf5f90..113ce67e 100644 --- a/src/core/lombok/core/TypeLibrary.java +++ b/src/core/lombok/core/TypeLibrary.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2015 The Project Lombok Authors. + * Copyright (C) 2009-2019 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -21,6 +21,7 @@ */ package lombok.core; +import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -75,6 +76,14 @@ public class TypeLibrary { } public static TypeLibrary createLibraryForSingleType(String fqnSingleton) { + if (LombokInternalAliasing.REVERSE_ALIASES.containsKey(fqnSingleton)) { + // Internal aliasing is a little too complex to handle with the map-less 'efficient' implementation. + TypeLibrary tl = new TypeLibrary(); + tl.addType(fqnSingleton); + tl.lock(); + return tl; + } + return new TypeLibrary(fqnSingleton); } @@ -89,7 +98,7 @@ public class TypeLibrary { if (locked) throw new IllegalStateException("locked"); int idx = fullyQualifiedTypeName.lastIndexOf('.'); if (idx == -1) throw new IllegalArgumentException( - "Only fully qualified types are allowed (and stuff in the default package is not palatable to us either!)"); + "Only fully qualified types are allowed (types in the default package cannot be added here either)"); String unqualified = fullyQualifiedTypeName.substring(idx + 1); if (unqualifiedToQualifiedMap == null) throw new IllegalStateException("SingleType library"); @@ -97,8 +106,11 @@ public class TypeLibrary { unqualifiedToQualifiedMap.put(unqualified, dotBased); unqualifiedToQualifiedMap.put(fullyQualifiedTypeName, dotBased); unqualifiedToQualifiedMap.put(dotBased, dotBased); - for (Map.Entry<String, String> e : LombokInternalAliasing.ALIASES.entrySet()) { - if (fullyQualifiedTypeName.equals(e.getValue())) unqualifiedToQualifiedMap.put(e.getKey(), dotBased); + Collection<String> oldNames = LombokInternalAliasing.REVERSE_ALIASES.get(fullyQualifiedTypeName); + if (oldNames != null) for (String oldName : oldNames) { + unqualifiedToQualifiedMap.put(oldName, dotBased); + int li = oldName.lastIndexOf('.'); + if (li != -1) unqualifiedToQualifiedMap.put(oldName.substring(li + 1), dotBased); } int idx2 = fullyQualifiedTypeName.indexOf('$', idx + 1); @@ -119,9 +131,6 @@ public class TypeLibrary { public String toQualified(String typeReference) { if (unqualifiedToQualifiedMap == null) { if (typeReference.equals(unqualified) || typeReference.equals(qualified)) return qualified; - for (Map.Entry<String, String> e : LombokInternalAliasing.ALIASES.entrySet()) { - if (e.getKey().equals(typeReference)) return e.getValue(); - } return null; } return unqualifiedToQualifiedMap.get(typeReference); diff --git a/src/core/lombok/core/TypeResolver.java b/src/core/lombok/core/TypeResolver.java index 60ac6b6a..06c91138 100644 --- a/src/core/lombok/core/TypeResolver.java +++ b/src/core/lombok/core/TypeResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2015 The Project Lombok Authors. + * Copyright (C) 2009-2019 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -45,7 +45,7 @@ public class TypeResolver { public String typeRefToFullyQualifiedName(LombokNode<?, ?, ?> context, TypeLibrary library, String typeRef) { typeRef = LombokInternalAliasing.processAliases(typeRef); - // When asking if 'Foo' could possibly be referring to 'bar.Baz', the answer is obviously no. + // When asking if 'Foo' could possibly be referring to 'bar.Baz', the answer is obviously no. String qualified = library.toQualified(typeRef); if (qualified == null) return null; diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java index 0a4f7e3d..28c79ac2 100644 --- a/src/core/lombok/core/Version.java +++ b/src/core/lombok/core/Version.java @@ -30,7 +30,7 @@ public class Version { // ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries). // Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example. // Official builds always end in an even number. (Since 0.10.2). - private static final String VERSION = "1.18.9"; + private static final String VERSION = "1.18.11"; private static final String RELEASE_NAME = "Edgy Guinea Pig"; // private static final String RELEASE_NAME = "Envious Ferret"; diff --git a/src/core/lombok/core/configuration/CheckerFrameworkVersion.java b/src/core/lombok/core/configuration/CheckerFrameworkVersion.java new file mode 100644 index 00000000..68fc05a7 --- /dev/null +++ b/src/core/lombok/core/configuration/CheckerFrameworkVersion.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2019 The Project Lombok Authors. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.core.configuration; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public final class CheckerFrameworkVersion implements ConfigurationValueType { + private final int version; + private static final int MAX_SUPPORTED = 3000; + + public static final String NAME__SIDE_EFFECT_FREE = "org.checkerframework.dataflow.qual.SideEffectFree"; + public static final String NAME__UNIQUE = "org.checkerframework.common.aliasing.qual.Unique"; + public static final String NAME__RETURNS_RECEIVER = "org.checkerframework.checker.builder.qual.ReturnsReceiver"; + public static final String NAME__NOT_CALLED = "org.checkerframework.checker.builder.qual.NotCalledMethods"; + public static final String NAME__CALLED = "org.checkerframework.checker.builder.qual.CalledMethods"; + + public static final CheckerFrameworkVersion NONE = new CheckerFrameworkVersion(0); + + private CheckerFrameworkVersion(int v) { + this.version = v; + } + + private static final Pattern VERSION = Pattern.compile("^(\\d+)(?:\\.(\\d+))?(?:\\.\\d+)*$"); + + public boolean generateSideEffectFree() { + return version > 0; + } + + public boolean generateUnique() { + return version > 0; + } + + public boolean generateReturnsReceiver() { + return version > 2999; + } + + public boolean generateCalledMethods() { + return version > 2999; + } + + public static CheckerFrameworkVersion valueOf(String versionString) { + if (versionString != null) versionString = versionString.trim(); + if (versionString == null || versionString.equalsIgnoreCase("false") || versionString.equals("0")) return new CheckerFrameworkVersion(0); + if (versionString.equalsIgnoreCase("true")) return new CheckerFrameworkVersion(MAX_SUPPORTED); + Matcher m = VERSION.matcher(versionString); + if (!m.matches()) throw new IllegalArgumentException("Expected 'true' or 'false' or a major/minor version, such as '2.9'"); + int major = Integer.parseInt(m.group(1)); + int minor = (m.group(2) != null && !m.group(2).isEmpty()) ? Integer.parseInt(m.group(2)) : 0; + if (minor > 999) throw new IllegalArgumentException("Minor version must be between 0 and 999"); + int v = major * 1000 + minor; + if (v > MAX_SUPPORTED) { + String s = (v / 1000) + "." + (v % 1000); + throw new IllegalArgumentException("Lombok supports at most v" + s + "; reduce the value of key 'checkerframework' to " + s); + } + return new CheckerFrameworkVersion(v); + } + + public static String description() { + return "checkerframework-version"; + } + + public static String exampleValue() { + String s = (MAX_SUPPORTED / 1000) + "." + (MAX_SUPPORTED % 1000); + return "major.minor (example: 2.9 - and no higher than " + s + ") or true or false"; + } +} diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java index 21a3a216..be32e101 100644 --- a/src/core/lombok/core/handlers/HandlerUtil.java +++ b/src/core/lombok/core/handlers/HandlerUtil.java @@ -38,6 +38,7 @@ import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.ToString; import lombok.Value; +import lombok.With; import lombok.core.AST; import lombok.core.AnnotationValues; import lombok.core.JavaIdentifiers; @@ -47,7 +48,6 @@ import lombok.core.configuration.ConfigurationKey; import lombok.core.configuration.FlagUsageType; import lombok.experimental.Accessors; import lombok.experimental.FieldDefaults; -import lombok.experimental.Wither; /** * Container for static utility methods useful for some of the standard lombok handlers, regardless of @@ -406,7 +406,7 @@ public class HandlerUtil { @SuppressWarnings({"all", "unchecked", "deprecation"}) public static final List<String> INVALID_ON_BUILDERS = Collections.unmodifiableList( Arrays.<String>asList( - Getter.class.getName(), Setter.class.getName(), Wither.class.getName(), + Getter.class.getName(), Setter.class.getName(), With.class.getName(), "lombok.experimental.Wither", ToString.class.getName(), EqualsAndHashCode.class.getName(), RequiredArgsConstructor.class.getName(), AllArgsConstructor.class.getName(), NoArgsConstructor.class.getName(), Data.class.getName(), Value.class.getName(), "lombok.experimental.Value", FieldDefaults.class.getName())); @@ -502,7 +502,7 @@ public class HandlerUtil { } /** - * Generates a wither name from a given field name. + * Generates a with name from a given field name. * * Strategy: * <ul> @@ -518,9 +518,9 @@ public class HandlerUtil { * @param accessors Accessors configuration. * @param fieldName the name of the field. * @param isBoolean if the field is of type 'boolean'. For fields of type {@code java.lang.Boolean}, you should provide {@code false}. - * @return The wither name for this field, or {@code null} if this field does not fit expected patterns and therefore cannot be turned into a getter name. + * @return The with name for this field, or {@code null} if this field does not fit expected patterns and therefore cannot be turned into a getter name. */ - public static String toWitherName(AST<?, ?, ?> ast, AnnotationValues<Accessors> accessors, CharSequence fieldName, boolean isBoolean) { + public static String toWithName(AST<?, ?, ?> ast, AnnotationValues<Accessors> accessors, CharSequence fieldName, boolean isBoolean) { return toAccessorName(ast, accessors, fieldName, isBoolean, "with", "with", false); } @@ -582,7 +582,7 @@ public class HandlerUtil { } /** - * Returns all names of methods that would represent the wither for a field with the provided name. + * Returns all names of methods that would represent the with for a field with the provided name. * * For example if {@code isBoolean} is true, then a field named {@code isRunning} would produce:<br /> * {@code [withRunning, withIsRunning]} @@ -591,7 +591,7 @@ public class HandlerUtil { * @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 {@code false}. */ - public static List<String> toAllWitherNames(AST<?, ?, ?> ast, AnnotationValues<Accessors> accessors, CharSequence fieldName, boolean isBoolean) { + public static List<String> toAllWithNames(AST<?, ?, ?> ast, AnnotationValues<Accessors> accessors, CharSequence fieldName, boolean isBoolean) { return toAllAccessorNames(ast, accessors, fieldName, isBoolean, "with", "with", false); } diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 11a2b9bd..0955dba6 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -111,6 +111,7 @@ import lombok.core.AnnotationValues; import lombok.core.AnnotationValues.AnnotationValue; import lombok.core.LombokImmutableList; import lombok.core.TypeResolver; +import lombok.core.configuration.CheckerFrameworkVersion; import lombok.core.configuration.NullCheckExceptionType; import lombok.core.configuration.TypeName; import lombok.core.debug.ProblemReporter; @@ -184,6 +185,23 @@ public class EclipseHandlerUtil { return ma; } + public static MarkerAnnotation generateNamedAnnotation(ASTNode source, String typeName) { + char[][] cc = fromQualifiedName(typeName); + QualifiedTypeReference qtr = new QualifiedTypeReference(cc, poss(source, cc.length)); + setGeneratedBy(qtr, source); + MarkerAnnotation ma = new MarkerAnnotation(qtr, source.sourceStart); + // No matter what value you input for sourceEnd, the AST->DOM converter of eclipse will reparse to find the end, and will fail as + // it can't find code that isn't really there. This results in the end position being set to 2 or 0 or some weird magic value, and thus, + // length, as calculated by end-start, is all screwed up, resulting in IllegalArgumentException during a setSourceRange call MUCH later in the process. + // We solve it by going with a voodoo magic source start value such that the calculated length so happens to exactly be 0. 0 lengths are accepted + // by eclipse. For some reason. + // TL;DR: Don't change 1. 1 is sacred. Trust the 1. + // issue: #408. + ma.sourceStart = 1; + setGeneratedBy(ma, source); + return ma; + } + public static boolean isFieldDeprecated(EclipseNode fieldNode) { if (!(fieldNode.get() instanceof FieldDeclaration)) return false; FieldDeclaration field = (FieldDeclaration) fieldNode.get(); @@ -199,6 +217,11 @@ public class EclipseHandlerUtil { return false; } + public static CheckerFrameworkVersion getCheckerFrameworkVersion(EclipseNode node) { + CheckerFrameworkVersion cfv = node.getAst().readConfiguration(ConfigurationKeys.CHECKER_FRAMEWORK); + return cfv != null ? cfv : CheckerFrameworkVersion.NONE; + } + /** * Checks if the given TypeReference node is likely to be a reference to the provided class. * @@ -652,15 +675,6 @@ public class EclipseHandlerUtil { return result == null ? null : result.toArray(new Annotation[0]); } - public static Annotation[] mergeAnnotations(Annotation[] a, Annotation[] b) { - if (a == null || a.length == 0) return (b == null || b.length == 0) ? null : b; - if (b == null || b.length == 0) return a.length == 0 ? null : a; - Annotation[] c = new Annotation[a.length + b.length]; - System.arraycopy(a, 0, c, 0, a.length); - System.arraycopy(b, 0, c, a.length, b.length); - return c; - } - public static boolean hasAnnotation(Class<? extends java.lang.annotation.Annotation> type, EclipseNode node) { if (node == null) return false; if (type == null) return false; @@ -1403,20 +1417,20 @@ public class EclipseHandlerUtil { } /** - * Translates the given field into all possible wither names. - * Convenient wrapper around {@link TransformationsUtil#toAllWitherNames(lombok.core.AnnotationValues, CharSequence, boolean)}. + * Translates the given field into all possible with names. + * Convenient wrapper around {@link TransformationsUtil#toAllWithNames(lombok.core.AnnotationValues, CharSequence, boolean)}. */ - public static java.util.List<String> toAllWitherNames(EclipseNode field, boolean isBoolean) { - return HandlerUtil.toAllWitherNames(field.getAst(), getAccessorsForField(field), field.getName(), isBoolean); + public static java.util.List<String> toAllWithNames(EclipseNode field, boolean isBoolean) { + return HandlerUtil.toAllWithNames(field.getAst(), getAccessorsForField(field), field.getName(), isBoolean); } /** - * @return the likely wither name for the stated field. (e.g. private boolean foo; to withFoo). + * @return the likely with name for the stated field. (e.g. private boolean foo; to withFoo). * - * Convenient wrapper around {@link TransformationsUtil#toWitherName(lombok.core.AnnotationValues, CharSequence, boolean)}. + * Convenient wrapper around {@link TransformationsUtil#toWithName(lombok.core.AnnotationValues, CharSequence, boolean)}. */ - public static String toWitherName(EclipseNode field, boolean isBoolean) { - return HandlerUtil.toWitherName(field.getAst(), getAccessorsForField(field), field.getName(), isBoolean); + public static String toWithName(EclipseNode field, boolean isBoolean) { + return HandlerUtil.toWithName(field.getAst(), getAccessorsForField(field), field.getName(), isBoolean); } /** @@ -1908,11 +1922,13 @@ public class EclipseHandlerUtil { * Create an annotation of the given name, and is marked as being generated by the given source. */ |
