diff options
Diffstat (limited to 'src/core/lombok')
26 files changed, 362 insertions, 106 deletions
diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java index 7efe20bd..46c3f770 100644 --- a/src/core/lombok/ConfigurationKeys.java +++ b/src/core/lombok/ConfigurationKeys.java @@ -126,6 +126,13 @@ public class ConfigurationKeys { public static final ConfigurationKey<FlagUsageType> NO_ARGS_CONSTRUCTOR_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.noArgsConstructor.flagUsage", "Emit a warning or error if @NoArgsConstructor is used.") {}; /** + * lombok configuration: {@code lombok.noArgsConstructor.extraPrivate} = {@code true} | {@code false}. + * + * If {@code true} (default), @Data and @Value will also generate a private no-args constructor, if there isn't already one, setting all fields to their default values. + */ + public static final ConfigurationKey<Boolean> NO_ARGS_CONSTRUCTOR_EXTRA_PRIVATE = new ConfigurationKey<Boolean>("lombok.noArgsConstructor.extraPrivate", "Generate a private no-ars constructor for @Data and @Value (default: true).") {}; + + /** * lombok configuration: {@code lombok.requiredArgsConstructor.flagUsage} = {@code WARNING} | {@code ERROR}. * * If set, <em>any</em> usage of {@code @RequiredArgsConstructor} results in a warning / error. @@ -383,6 +390,13 @@ public class ConfigurationKeys { public static final ConfigurationKey<FlagUsageType> LOG_JBOSSLOG_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.log.jbosslog.flagUsage", "Emit a warning or error if @JBossLog is used.") {}; /** + * lombok configuration: {@code lombok.log.flogger.flagUsage} = {@code WARNING} | {@code ERROR}. + * + * If set, <em>any</em> usage of {@code @Flogger} results in a warning / error. + */ + public static final ConfigurationKey<FlagUsageType> LOG_FLOGGER_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.log.flogger.flagUsage", "Emit a warning or error if @Flogger is used.") {}; + + /** * lombok configuration: {@code lombok.log.fieldName} = <String: aJavaIdentifier> (Default: {@code log}). * * If set the various log annotations (which make a log field) will use the stated identifier instead of {@code log} as a name. @@ -507,6 +521,20 @@ public class ConfigurationKeys { */ public static final ConfigurationKey<FlagUsageType> FIELD_NAME_CONSTANTS_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.fieldNameConstants.flagUsage", "Emit a warning or error if @FieldNameConstants is used.") {}; + /** + * lombok configuration: {@code lombok.fieldNameConstants.prefix} = <String: aJavaIdentifierPrefix> (Default: {@code PREFIX_}). + * + * The names of the constants generated by {@code @FieldNameConstants} will be prefixed with this value. + */ + public static final ConfigurationKey<String> FIELD_NAME_CONSTANTS_PREFIX = new ConfigurationKey<String>("lombok.fieldNameConstants.prefix", "names of constants generated by @FieldNameConstants will be prefixed with this value. (default: 'PREFIX_').") {}; + + /** + * lombok configuration: {@code lombok.fieldNameConstants.suffix} = <String: aJavaIdentifierPrefix> (Default: nothing). + * + * The names of the constants generated by {@code @FieldNameConstants} will be suffixed with this value. + */ + public static final ConfigurationKey<String> FIELD_NAME_CONSTANTS_SUFFIX = new ConfigurationKey<String>("lombok.fieldNameConstants.suffix", "names of constants generated by @FieldNameConstants will be suffixed with this value. (default: nothing).") {}; + // ----- Wither ----- /** diff --git a/src/core/lombok/core/AnnotationValues.java b/src/core/lombok/core/AnnotationValues.java index b6e78de4..a24330fa 100644 --- a/src/core/lombok/core/AnnotationValues.java +++ b/src/core/lombok/core/AnnotationValues.java @@ -200,12 +200,12 @@ public class AnnotationValues<A extends Annotation> { public boolean getAsBoolean(String methodName) { AnnotationValue v = values.get(methodName); if (v == null || v.valueGuesses.size() != 1) { - return getDefaultIf(methodName, Boolean.class, false); + return getDefaultIf(methodName, boolean.class, false); } - Object guess = guessToType(v.valueGuesses.get(0), Boolean.class, v, 0); + Object guess = guessToType(v.valueGuesses.get(0), boolean.class, v, 0); if (guess instanceof Boolean) return ((Boolean) guess).booleanValue(); - return getDefaultIf(methodName, Boolean.class, false); + return getDefaultIf(methodName, boolean.class, false); } public <T> T getDefaultIf(String methodName, Class<T> type, T defaultValue) { @@ -286,19 +286,19 @@ public class AnnotationValues<A extends Annotation> { } private Object guessToType(Object guess, Class<?> expected, AnnotationValue v, int pos) { - if (expected == int.class) { + if (expected == int.class || expected == Integer.class) { if (guess instanceof Integer || guess instanceof Short || guess instanceof Byte) { return ((Number) guess).intValue(); } } - if (expected == long.class) { + if (expected == long.class || expected == Long.class) { if (guess instanceof Long || guess instanceof Integer || guess instanceof Short || guess instanceof Byte) { return ((Number) guess).longValue(); } } - if (expected == short.class) { + if (expected == short.class || expected == Short.class) { if (guess instanceof Integer || guess instanceof Short || guess instanceof Byte) { int intVal = ((Number) guess).intValue(); int shortVal = ((Number) guess).shortValue(); @@ -306,7 +306,7 @@ public class AnnotationValues<A extends Annotation> { } } - if (expected == byte.class) { + if (expected == byte.class || expected == Byte.class) { if (guess instanceof Integer || guess instanceof Short || guess instanceof Byte) { int intVal = ((Number) guess).intValue(); int byteVal = ((Number) guess).byteValue(); @@ -314,19 +314,19 @@ public class AnnotationValues<A extends Annotation> { } } - if (expected == double.class) { + if (expected == double.class || expected == Double.class) { if (guess instanceof Number) return ((Number) guess).doubleValue(); } - if (expected == float.class) { + if (expected == float.class || expected == Float.class) { if (guess instanceof Number) return ((Number) guess).floatValue(); } - if (expected == boolean.class) { + if (expected == boolean.class || expected == Boolean.class) { if (guess instanceof Boolean) return ((Boolean) guess).booleanValue(); } - if (expected == char.class) { + if (expected == char.class || expected == Character.class) { if (guess instanceof Character) return ((Character) guess).charValue(); } @@ -346,7 +346,7 @@ public class AnnotationValues<A extends Annotation> { } } - if (Class.class == expected) { + if (expected == Class.class) { if (guess instanceof ClassLiteral) try { String classLit = ((ClassLiteral) guess).getClassName(); return Class.forName(toFQ(classLit)); diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java index 98f1e575..dc0900f6 100644 --- a/src/core/lombok/core/Version.java +++ b/src/core/lombok/core/Version.java @@ -30,15 +30,16 @@ 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.16.21"; + private static final String VERSION = "1.16.23"; private static final String RELEASE_NAME = "Edgy Guinea Pig"; -// private static final String RELEASE_NAME = "Dancing Elephant"; +// private static final String RELEASE_NAME = "Envious Ferret"; // Named version history: // Angry Butterfly // Branching Cobra // Candid Duck // Dancing Elephant + // Envious Ferret private Version() { //Prevent instantiation diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 1758a220..2dce285c 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -1198,6 +1198,12 @@ public class EclipseHandlerUtil { return AnnotationValues.of(Accessors.class, field); } + + public static EclipseNode upToTypeNode(EclipseNode node) { + if (node == null) throw new NullPointerException("node"); + while (node != null && !(node.get() instanceof TypeDeclaration)) node = node.up(); + return node; + } /** * Checks if there is a field with the provided name. @@ -1206,10 +1212,7 @@ public class EclipseHandlerUtil { * @param node Any node that represents the Type (TypeDeclaration) to look in, or any child node thereof. */ public static MemberExistsResult fieldExists(String fieldName, EclipseNode node) { - while (node != null && !(node.get() instanceof TypeDeclaration)) { - node = node.up(); - } - + node = upToTypeNode(node); if (node != null && node.get() instanceof TypeDeclaration) { TypeDeclaration typeDecl = (TypeDeclaration)node.get(); if (typeDecl.fields != null) for (FieldDeclaration def : typeDecl.fields) { @@ -1295,10 +1298,7 @@ public class EclipseHandlerUtil { * @param node Any node that represents the Type (TypeDeclaration) to look in, or any child node thereof. */ public static MemberExistsResult constructorExists(EclipseNode node) { - while (node != null && !(node.get() instanceof TypeDeclaration)) { - node = node.up(); - } - + node = upToTypeNode(node); if (node != null && node.get() instanceof TypeDeclaration) { TypeDeclaration typeDecl = (TypeDeclaration)node.get(); if (typeDecl.methods != null) for (AbstractMethodDeclaration def : typeDecl.methods) { @@ -1854,4 +1854,12 @@ public class EclipseHandlerUtil { private static long[] copy(long[] array) { return array == null ? null : array.clone(); } + + public static boolean isDirectDescendantOfObject(EclipseNode typeNode) { + if (!(typeNode.get() instanceof TypeDeclaration)) throw new IllegalArgumentException("not a type node"); + TypeDeclaration typeDecl = (TypeDeclaration) typeNode.get(); + if (typeDecl.superclass == null) return true; + String p = typeDecl.superclass.toString(); + return p.equals("Object") || p.equals("java.lang.Object"); + } } diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java index 62e2c18c..eb7fd711 100644 --- a/src/core/lombok/eclipse/handlers/HandleConstructor.java +++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java @@ -42,8 +42,10 @@ import lombok.core.AST.Kind; import lombok.core.AnnotationValues; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseNode; +import lombok.eclipse.handlers.EclipseHandlerUtil.MemberExistsResult; import org.eclipse.jdt.internal.compiler.ast.ASTNode; +import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.Argument; @@ -204,6 +206,20 @@ public class HandleConstructor { return true; } + public enum SkipIfConstructorExists { + YES, NO, I_AM_BUILDER; + } + + public void generateExtraNoArgsConstructor(EclipseNode typeNode, EclipseNode sourceNode) { + if (!isDirectDescendantOfObject(typeNode)) return; + + Boolean v = typeNode.getAst().readConfiguration(ConfigurationKeys.NO_ARGS_CONSTRUCTOR_EXTRA_PRIVATE); + if (v == null || !v) return; + + List<EclipseNode> fields = findFinalFields(typeNode); + generate(typeNode, AccessLevel.PRIVATE, fields, true, null, SkipIfConstructorExists.NO, Collections.<Annotation>emptyList(), sourceNode, true); + } + public void generateRequiredArgsConstructor( EclipseNode typeNode, AccessLevel level, String staticName, SkipIfConstructorExists skipIfConstructorExists, List<Annotation> onConstructor, EclipseNode sourceNode) { @@ -218,14 +234,17 @@ public class HandleConstructor { generateConstructor(typeNode, level, findAllFields(typeNode), false, staticName, skipIfConstructorExists, onConstructor, sourceNode); } - public enum SkipIfConstructorExists { - YES, NO, I_AM_BUILDER; - } - public void generateConstructor( EclipseNode typeNode, AccessLevel level, List<EclipseNode> fields, boolean allToDefault, String staticName, SkipIfConstructorExists skipIfConstructorExists, List<Annotation> onConstructor, EclipseNode sourceNode) { + generate(typeNode, level, fields, allToDefault, staticName, skipIfConstructorExists, onConstructor, sourceNode, false); + } + + public void generate( + EclipseNode typeNode, AccessLevel level, List<EclipseNode> fields, boolean allToDefault, String staticName, SkipIfConstructorExists skipIfConstructorExists, + List<Annotation> onConstructor, EclipseNode sourceNode, boolean noArgs) { + ASTNode source = sourceNode.get(); boolean staticConstrRequired = staticName != null && !staticName.equals(""); @@ -257,6 +276,8 @@ public class HandleConstructor { } } + if (noArgs && noArgsConstructorExists(typeNode)) return; + ConstructorDeclaration constr = createConstructor( staticConstrRequired ? AccessLevel.PRIVATE : level, typeNode, fields, allToDefault, sourceNode, onConstructor); @@ -267,6 +288,29 @@ public class HandleConstructor { } } + private static boolean noArgsConstructorExists(EclipseNode node) { + node = EclipseHandlerUtil.upToTypeNode(node); + + if (node != null && node.get() instanceof TypeDeclaration) { + TypeDeclaration typeDecl = (TypeDeclaration)node.get(); + if (typeDecl.methods != null) for (AbstractMethodDeclaration def : typeDecl.methods) { + if (def instanceof ConstructorDeclaration) { + Argument[] arguments = ((ConstructorDeclaration) def).arguments; + if (arguments == null || arguments.length == 0) return true; + } + } + } + + for (EclipseNode child : node.down()) { + if (annotationTypeMatches(NoArgsConstructor.class, child)) return true; + if (annotationTypeMatches(RequiredArgsConstructor.class, child) && findRequiredFields(node).isEmpty()) return true; + if (annotationTypeMatches(AllArgsConstructor.class, child) && findAllFields(node).isEmpty()) return true; + } + + return false; + } + + private static final char[][] JAVA_BEANS_CONSTRUCTORPROPERTIES = new char[][] { "java".toCharArray(), "beans".toCharArray(), "ConstructorProperties".toCharArray() }; public static Annotation[] createConstructorProperties(ASTNode source, Collection<EclipseNode> fields) { if (fields.isEmpty()) return null; diff --git a/src/core/lombok/eclipse/handlers/HandleData.java b/src/core/lombok/eclipse/handlers/HandleData.java index 5d92cd36..4011890d 100644 --- a/src/core/lombok/eclipse/handlers/HandleData.java +++ b/src/core/lombok/eclipse/handlers/HandleData.java @@ -79,5 +79,6 @@ public class HandleData extends EclipseAnnotationHandler<Data> { handleConstructor.generateRequiredArgsConstructor( typeNode, AccessLevel.PUBLIC, ann.staticConstructor(), SkipIfConstructorExists.YES, Collections.<Annotation>emptyList(), annotationNode); + handleConstructor.generateExtraNoArgsConstructor(typeNode, annotationNode); } } diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java index e30df698..c99b9b5f 100644 --- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java @@ -157,12 +157,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH } } - boolean isDirectDescendantOfObject = true; - - if (typeDecl.superclass != null) { - String p = typeDecl.superclass.toString(); - isDirectDescendantOfObject = p.equals("Object") || p.equals("java.lang.Object"); - } + boolean isDirectDescendantOfObject = isDirectDescendantOfObject(typeNode); if (isDirectDescendantOfObject && callSuper) { errorNode.addError("Generating equals/hashCode with a supercall to java.lang.Object is pointless."); diff --git a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java index 754ddf47..c3a28f7f 100644 --- a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java +++ b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java @@ -49,7 +49,7 @@ import org.mangosdk.spi.ProviderFor; @ProviderFor(EclipseAnnotationHandler.class) public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldNameConstants> { - public void generateFieldNameConstantsForType(EclipseNode typeNode, EclipseNode errorNode, AccessLevel level) { + public void generateFieldNameConstantsForType(EclipseNode typeNode, EclipseNode errorNode, AccessLevel level, String prefix, String suffix) { TypeDeclaration typeDecl = null; if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get(); @@ -62,13 +62,13 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName } for (EclipseNode field : typeNode.down()) { - if (fieldQualifiesForFieldNameConstantsGeneration(field)) generateFieldNameConstantsForField(field, errorNode.get(), level); + if (fieldQualifiesForFieldNameConstantsGeneration(field)) generateFieldNameConstantsForField(field, errorNode.get(), level, prefix, suffix); } } - private void generateFieldNameConstantsForField(EclipseNode fieldNode, ASTNode pos, AccessLevel level) { + private void generateFieldNameConstantsForField(EclipseNode fieldNode, ASTNode pos, AccessLevel level, String prefix, String suffix) { if (hasAnnotation(FieldNameConstants.class, fieldNode)) return; - createFieldNameConstantsForField(level, fieldNode, fieldNode, pos, false); + createFieldNameConstantsForField(level, prefix, suffix, fieldNode, fieldNode, pos, false); } private boolean fieldQualifiesForFieldNameConstantsGeneration(EclipseNode field) { @@ -83,27 +83,33 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName EclipseNode node = annotationNode.up(); FieldNameConstants annotatationInstance = annotation.getInstance(); AccessLevel level = annotatationInstance.level(); + String prefix = annotatationInstance.prefix(); + String suffix = annotatationInstance.suffix(); + if (prefix.equals(" CONFIG DEFAULT ")) prefix = annotationNode.getAst().readConfiguration(ConfigurationKeys.FIELD_NAME_CONSTANTS_PREFIX); + if (suffix.equals(" CONFIG DEFAULT ")) suffix = annotationNode.getAst().readConfiguration(ConfigurationKeys.FIELD_NAME_CONSTANTS_SUFFIX); + if (prefix == null) prefix = "FIELD_"; + if (suffix == null) suffix = ""; if (node == null) return; switch (node.getKind()) { case FIELD: - if (level != AccessLevel.NONE) createFieldNameConstantsForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true); + if (level != AccessLevel.NONE) createFieldNameConstantsForFields(level, prefix, suffix, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true); break; case TYPE: if (level == AccessLevel.NONE) { annotationNode.addWarning("type-level '@FieldNameConstants' does not work with AccessLevel.NONE."); return; } - generateFieldNameConstantsForType(node, annotationNode, level); + generateFieldNameConstantsForType(node, annotationNode, level, prefix, suffix); break; } } - private void createFieldNameConstantsForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists) { - for (EclipseNode fieldNode : fieldNodes) createFieldNameConstantsForField(level, fieldNode, errorNode, source, whineIfExists); + private void createFieldNameConstantsForFields(AccessLevel level, String prefix, String suffix, Collection<EclipseNode> fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists) { + for (EclipseNode fieldNode : fieldNodes) createFieldNameConstantsForField(level, prefix, suffix, fieldNode, errorNode, source, whineIfExists); } - private void createFieldNameConstantsForField(AccessLevel level, EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists) { + private void createFieldNameConstantsForField(AccessLevel level, String prefix, String suffix, EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists) { if (fieldNode.getKind() != Kind.FIELD) { errorNode.addError("@FieldNameConstants is only supported on a class, an enum, or a field"); return; @@ -111,7 +117,7 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName FieldDeclaration field = (FieldDeclaration) fieldNode.get(); String fieldName = new String(field.name); - String constantName = HandlerUtil.camelCaseToConstant(fieldName); + String constantName = prefix + HandlerUtil.camelCaseToConstant(fieldName) + suffix; if (constantName.equals(fieldName)) { fieldNode.addWarning("Not generating constant for this field: The name of the constant would be equal to the name of this field."); return; diff --git a/src/core/lombok/eclipse/handlers/HandleLog.java b/src/core/lombok/eclipse/handlers/HandleLog.java index c49030d8..8c7f7971 100644 --- a/src/core/lombok/eclipse/handlers/HandleLog.java +++ b/src/core/lombok/eclipse/handlers/HandleLog.java @@ -109,7 +109,7 @@ public class HandleLog { private static FieldDeclaration createField(LoggingFramework framework, Annotation source, ClassLiteralAccess loggingType, String logFieldName, boolean useStatic, String loggerTopic) { int pS = source.sourceStart, pE = source.sourceEnd; - long p = (long)pS << 32 | pE; + long p = (long) pS << 32 | pE; // private static final <loggerType> log = <factoryMethod>(<parameter>); FieldDeclaration fieldDecl = new FieldDeclaration(logFieldName.toCharArray(), 0, -1); @@ -126,13 +126,15 @@ public class HandleLog { factoryMethodCall.selector = framework.getLoggerFactoryMethodName().toCharArray(); Expression parameter; - if (loggerTopic == null || loggerTopic.trim().length() == 0) { + if (!framework.passTypeName) { + parameter = null; + } else if (loggerTopic == null || loggerTopic.trim().length() == 0) { parameter = framework.createFactoryParameter(loggingType, source); } else { parameter = new StringLiteral(loggerTopic.toCharArray(), pS, pE, 0); } - factoryMethodCall.arguments = new Expression[] { parameter }; + factoryMethodCall.arguments = parameter != null ? new Expression[] { parameter } : null; factoryMethodCall.nameSourcePosition = p; factoryMethodCall.sourceStart = pS; factoryMethodCall.sourceEnd = factoryMethodCall.statementEnd = pE; @@ -240,6 +242,17 @@ public class HandleLog { } } + /** + * Handles the {@link lombok.extern.flogger.Flogger} annotation for Eclipse. + */ + @ProviderFor(EclipseAnnotationHandler.class) + public static class HandleFloggerLog extends EclipseAnnotationHandler<lombok.extern.flogger.Flogger> { + @Override public void handle(AnnotationValues<lombok.extern.flogger.Flogger> annotation, Annotation source, EclipseNode annotationNode) { + handleFlagUsage(annotationNode, ConfigurationKeys.LOG_FLOGGER_FLAG_USAGE, "@Flogger", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); + processAnnotation(LoggingFramework.FLOGGER, annotation, source, annotationNode, ""); + } + } + enum LoggingFramework { // private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(TargetType.class); COMMONS("org.apache.commons.logging.Log", "org.apache.commons.logging.LogFactory", "getLog", "@CommonsLog"), @@ -278,18 +291,31 @@ public class HandleLog { // private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(TargetType.class); JBOSSLOG("org.jboss.logging.Logger", "org.jboss.logging.Logger", "getLogger", "@JBossLog"), + + // private static final com.google.common.flogger.FluentLogger log = com.google.common.flogger.FluentLogger.forEnclosingClass(); + FLOGGER("com.google.common.flogger.FluentLogger", "com.google.common.flogger.FluentLogger", "forEnclosingClass", "@Flogger", false), ; private final String loggerTypeName; private final String loggerFactoryTypeName; private final String loggerFactoryMethodName; private final String annotationAsString; - + private final boolean passTypeName; + + LoggingFramework(String loggerTypeName, String loggerFactoryTypeName, String loggerFactoryMethodName, String annotationAsString, boolean passTypeName) { + this.loggerTypeName = loggerTypeName; + this.loggerFactoryTypeName = loggerFactoryTypeName; + this.loggerFactoryMethodName = loggerFactoryMethodName; + this.annotationAsString = annotationAsString; + this.passTypeName = passTypeName; + } + LoggingFramework(String loggerTypeName, String loggerFactoryTypeName, String loggerFactoryMethodName, String annotationAsString) { this.loggerTypeName = loggerTypeName; this.loggerFactoryTypeName = loggerFactoryTypeName; this.loggerFactoryMethodName = loggerFactoryMethodName; this.annotationAsString = annotationAsString; + this.passTypeName = true; } final String getAnnotationAsString() { @@ -308,7 +334,7 @@ public class HandleLog { return loggerFactoryMethodName; } - Expression createFactoryParameter(ClassLiteralAccess loggingType, Annotation source){ + Expression createFactoryParameter(ClassLiteralAccess loggingType, Annotation source) { TypeReference copy = copyType(loggingType.type, source); ClassLiteralAccess result = new ClassLiteralAccess(source.sourceEnd, copy); setGeneratedBy(result, source); diff --git a/src/core/lombok/eclipse/handlers/HandleValue.java b/src/core/lombok/eclipse/handlers/HandleValue.java index bd93a547..2e0338a8 100644 --- a/src/core/lombok/eclipse/handlers/HandleValue.java +++ b/src/core/lombok/eclipse/handlers/HandleValue.java @@ -91,5 +91,6 @@ public class HandleValue extends EclipseAnnotationHandler<Value> { handleToString.generateToStringForType(typeNode, annotationNode); handleConstructor.generateAllArgsConstructor(typeNode, AccessLevel.PUBLIC, ann.staticConstructor(), SkipIfConstructorExists.YES, Collections.<Annotation>emptyList(), annotationNode); + handleConstructor.generateExtraNoArgsConstructor(typeNode, annotationNode); } } diff --git a/src/core/lombok/experimental/FieldNameConstants.java b/src/core/lombok/experimental/FieldNameConstants.java index 41b33ac7..31c2970c 100644 --- a/src/core/lombok/experimental/FieldNameConstants.java +++ b/src/core/lombok/experimental/FieldNameConstants.java @@ -35,4 +35,6 @@ import lombok.AccessLevel; @Retention(RetentionPolicy.SOURCE) public @interface FieldNameConstants { lombok.AccessLevel level() default AccessLevel.PUBLIC; + String prefix() default " CONFIG DEFAULT "; + String suffix() default " CONFIG DEFAULT "; } diff --git a/src/core/lombok/extern/apachecommons/CommonsLog.java b/src/core/lombok/extern/apachecommons/CommonsLog.java index 04d5ef93..fa3d6f09 100644 --- a/src/core/lombok/extern/apachecommons/CommonsLog.java +++ b/src/core/lombok/extern/apachecommons/CommonsLog.java @@ -56,6 +56,7 @@ import java.lang.annotation.Target; * @see lombok.extern.slf4j.Slf4j @Slf4j * @see lombok.extern.slf4j.XSlf4j @XSlf4j * @see lombok.extern.jbosslog.JBossLog @JBossLog + * @see lombok.extern.flogger.Flogger @Flogger */ @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) diff --git a/src/core/lombok/extern/flogger/Flogger.java b/src/core/lombok/extern/flogger/Flogger.java new file mode 100644 index 00000000..ecbfd28c --- /dev/null +++ b/src/core/lombok/extern/flogger/Flogger.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2018 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.extern.flogger; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Causes lombok to generate a logger field. + * <p> + * Complete documentation is found at <a href="https://projectlombok.org/features/Log">the project lombok features page for lombok log annotations</a>. + * <p> + * Example: + * <pre> + * @Flogger + * public class LogExample { + * } + * </pre> + * + * will generate: + * + * <pre> + * public class LogExample { + * private static final com.google.common.flogger.FluentLogger log = com.google.common.flogger.FluentLogger.forEnclosingClass(); + * } + * </pre> + * + * This annotation is valid for classes and enumerations.<br> + * @see <a href="https://google.github.io/flogger/">com.google.common.flogger</a> + * @see lombok.extern.apachecommons.CommonsLog @CommonsLog + * @see lombok.extern.java.Log @Log + * @see lombok.extern.log4j.Log4j @Log4j + * @see lombok.extern.log4j.Log4j2 @Log4j2 + * @see lombok.extern.slf4j.Slf4j @Slf4j + * @see lombok.extern.slf4j.XSlf4j @XSlf4j + * @see lombok.extern.jbosslog.JBossLog @JBossLog + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface Flogger { +} diff --git a/src/core/lombok/extern/java/Log.java b/src/core/lombok/extern/java/Log.java index 553b7c4a..9a1ee412 100644 --- a/src/core/lombok/extern/java/Log.java +++ b/src/core/lombok/extern/java/Log.java @@ -55,6 +55,7 @@ import java.lang.annotation.Target; * @see lombok.extern.slf4j.Slf4j @Slf4j * @see lombok.extern.slf4j.XSlf4j @XSlf4j * @see lombok.extern.jbosslog.JBossLog @JBossLog + * @see lombok.extern.flogger.Flogger @Flogger */ @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) diff --git a/src/core/lombok/extern/jbosslog/JBossLog.java b/src/core/lombok/extern/jbosslog/JBossLog.java index ea520aea..684585e0 100644 --- a/src/core/lombok/extern/jbosslog/JBossLog.java +++ b/src/core/lombok/extern/jbosslog/JBossLog.java @@ -53,8 +53,9 @@ import java.lang.annotation.Target; * @see lombok.extern.java.Log @Log * @see lombok.extern.log4j.Log4j @Log4j * @see lombok.extern.log4j.Log4j2 @Log4j2 + * @see lombok.extern.slf4j.Slf4j @Slf4j * @see lombok.extern.slf4j.XSlf4j @XSlf4j - * @see lombok.extern.jbosslog.JBossLog @JBossLog + * @see lombok.extern.flogger.Flogger @Flogger * */ @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) diff --git a/src/core/lombok/extern/log4j/Log4j.java b/src/core/lombok/extern/log4j/Log4j.java index ee719407..249ef71a 100644 --- a/src/core/lombok/extern/log4j/Log4j.java +++ b/src/core/lombok/extern/log4j/Log4j.java @@ -56,6 +56,7 @@ import java.lang.annotation.Target; * @see lombok.extern.slf4j.Slf4j @Slf4j * @see lombok.extern.slf4j.XSlf4j @XSlf4j * @see lombok.extern.jbosslog.JBossLog @JBossLog + * @see lombok.extern.flogger.Flogger @Flogger */ @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) diff --git a/src/core/lombok/extern/log4j/Log4j2.java b/src/core/lombok/extern/log4j/Log4j2.java index 4a5b166c..a6aa90c0 100644 --- a/src/core/lombok/extern/log4j/Log4j2.java +++ b/src/core/lombok/extern/log4j/Log4j2.java @@ -56,6 +56,7 @@ import java.lang.annotation.Target; * @see lombok.extern.slf4j.Slf4j @Slf4j * @see lombok.extern.slf4j.XSlf4j @XSlf4j * @see lombok.extern.jbosslog.JBossLog @JBossLog + * @see lombok.extern.flogger.Flogger @Flogger */ @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) diff --git a/src/core/lombok/extern/slf4j/Slf4j.java b/src/core/lombok/extern/slf4j/Slf4j.java index 24586d43..347d81d2 100644 --- a/src/core/lombok/extern/slf4j/Slf4j.java +++ b/src/core/lombok/extern/slf4j/Slf4j.java @@ -55,6 +55,7 @@ import java.lang.annotation.Target; * @see lombok.extern.log4j.Log4j2 @Log4j2 * @see lombok.extern.slf4j.XSlf4j @XSlf4j * @see lombok.extern.jbosslog.JBossLog @JBossLog + * @see lombok.extern.flogger.Flogger @Flogger */ @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) diff --git a/src/core/lombok/extern/slf4j/XSlf4j.java b/src/core/lombok/extern/slf4j/XSlf4j.java index 85a0fdd8..4d53a1eb 100644 --- a/src/core/lombok/extern/slf4j/XSlf4j.java +++ b/src/core/lombok/extern/slf4j/XSlf4j.java @@ -55,6 +55,7 @@ import java.lang.annotation.Target; * @see lombok.extern.log4j.Log4j2 @Log4j2 * @see lombok.extern.slf4j.Slf4j @Slf4j * @see lombok.extern.jbosslog.JBossLog @JBossLog + * @see lombok.extern.flogger.Flogger @Flogger */ @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index dca25ee7..32eb43b2 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2014 The Project Lombok Authors. + * Copyright (C) 2010-2018 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 @@ -22,22 +22,8 @@ package lombok.javac.handlers; import static lombok.core.handlers.HandlerUtil.*; -import static lombok.javac.handlers.JavacHandlerUtil.*; import static lombok.javac.Javac.*; - -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.ConfigurationKeys; -import lombok.NoArgsConstructor; -import lombok.RequiredArgsConstructor; -import lombok.core.AnnotationValues; -import lombok.core.AST.Kind; -import lombok.delombok.LombokOptionsFactory; -import lombok.javac.Javac; -import lombok.javac.JavacAnnotationHandler; -import lombok.javac.JavacNode; -import lombok.javac.JavacTreeMaker; +import static lombok.javac.handlers.JavacHandlerUtil.*; import org.mangosdk.spi.ProviderFor; @@ -61,6 +47,21 @@ import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Name; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.ConfigurationKeys; +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.core.AST.Kind; +import lombok.core.AnnotationValues; +import lombok.delombok.LombokOptionsFactory; +import lombok.javac.Javac; +import lombok.javac.JavacAnnotationHandler; +import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; +import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult; + public class HandleConstructor { @ProviderFor(JavacAnnotationHandler.class) public static class HandleNoArgsConstructor extends JavacAnnotationHandler<NoArgsConstructor> { @@ -191,19 +192,33 @@ public class HandleConstructor { return true; } - public void generateRequiredArgsConstructor(JavacNode typeNode, AccessLevel level, String staticName, SkipIfConstructorExists skipIfConstructorExists, JavacNode source) { - generateConstructor(typeNode, level, List.<JCAnnotation>nil(), findRequiredFields(typeNode), false, staticName, skipIfConstructorExists, source); - } - public enum SkipIfConstructorExists { YES, NO, I_AM_BUILDER; } + public void generateExtraNoArgsConstructor(JavacNode typeNode, JavacNode source) { + if (!isDirectDescendantOfObject(typeNode)) return; + + Boolean v = typeNode.getAst().readConfiguration(ConfigurationKeys.NO_ARGS_CONSTRUCTOR_EXTRA_PRIVATE); + if (v == null || !v) return; + + List<JavacNode> fields = findFinalFields(typeNode); + generate(typeNode, AccessLevel.PRIVATE, List.<JCAnnotation>nil(), fields, true, null, SkipIfConstructorExists.NO, source, true); + } + + public void generateRequiredArgsConstructor(JavacNode typeNode, AccessLevel level, String staticName, SkipIfConstructorExists skipIfConstructorExists, JavacNode source) { + generateConstructor(typeNode, level, List.<JCAnnotation>nil(), findRequiredFields(typeNode), false, staticName, skipIfConstructorExists, source); + } + public void generateAllArgsConstructor(JavacNode typeNode, AccessLevel level, String staticName, SkipIfConstructorExists skipIfConstructorExists, JavacNode source) { generateConstructor(typeNode, level, List.<JCAnnotation>nil(), findAllFields(typeNode), false, staticName, skipIfConstructorExists, source); } public void generateConstructor(JavacNode typeNode, AccessLevel level, List<JCAnnotation> onConstructor, List<JavacNode> fields, boolean allToDefault, String staticName, SkipIfConstructorExists skipIfConstructorExists, JavacNode source) { + generate(typeNode, level, onConstructor, fields, allToDefault, staticName, skipIfConstructorExists, source, false); + } + + private void generate(JavacNode typeNode, AccessLevel level, List<JCAnnotation> onConstructor, List<JavacNode> fields, boolean allToDefault, String staticName, SkipIfConstructorExists skipIfConstructorExists, JavacNode source, boolean noArgs) { boolean staticConstrRequired = staticName != null && !staticName.equals(""); if (skipIfConstructorExists != SkipIfConstructorExists.NO && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS) return; @@ -232,6 +247,8 @@ public class HandleConstructor { } } + if (noArgs && noArgsConstructorExists(typeNode)) return; + JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, onConstructor, typeNode, fields, allToDefault, source); ListBuffer<Type> argTypes = new ListBuffer<Type>(); for (JavacNode fieldNode : fields) { @@ -252,6 +269,27 @@ public class HandleConstructor { } } + private static boolean noArgsConstructorExists(JavacNode node) { + node = upToTypeNode(node); + + if (node != null && node.get() instanceof JCClassDecl) { + for (JCTree def : ((JCClassDecl) node.get()).defs) { + if (def instanceof JCMethodDecl) { + JCMethodDecl md = (JCMethodDecl) def; + if (md.name.contentEquals("<init>") && md.params.size() == 0) return true; + } + } + } + + for (JavacNode child : node.down()) { + if (annotationTypeMatches(NoArgsConstructor.class, child)) return true; + if (annotationTypeMatches(RequiredArgsConstructor.class, child) && findRequiredFields(node).isEmpty()) return true; + if (annotationTypeMatches(AllArgsConstructor.class, child) && findAllFields(node).isEmpty()) return true; + } + + return false; + } + public static void addConstructorProperties(JCModifiers mods, JavacNode node, List<JavacNode> fields) { if (fields.isEmpty()) return; JavacTreeMaker maker = node.getTreeMaker(); diff --git a/src/core/lombok/javac/handlers/HandleData.java b/src/core/lombok/javac/handlers/HandleData.java index 94b6c3e1..15c9c9e7 100644 --- a/src/core/lombok/javac/handlers/HandleData.java +++ b/src/core/lombok/javac/handlers/HandleData.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2014 The Project Lombok Authors. + * Copyright (C) 2009-2018 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 @@ -61,7 +61,9 @@ public class HandleData extends JavacAnnotationHandler<Data> { String staticConstructorName = annotation.getInstance().staticConstructor(); + // TODO move this to the end OR move it to the top in eclipse. handleConstructor.generateRequiredArgsConstructor(typeNode, AccessLevel.PUBLIC, staticConstructorName, SkipIfConstructorExists.YES, annotationNode); + handleConstructor.generateExtraNoArgsConstructor(typeNode, annotationNode); handleGetter.generateGetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true, List.<JCAnnotation>nil()); handleSetter.generateSetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true, List.<JCAnnotation>nil(), List.<JCAnnotation>nil()); handleEqualsAndHashCode.generateEqualsAndHashCodeForType(typeNode, annotationNode); diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index 12071cfd..aa0fe633 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -21,7 +21,7 @@ */ package lombok.javac.handlers; -import static lombok.core.handlers.HandlerUtil.*; +import static lombok.core.handlers.HandlerUtil.handleFlagUsage; import static lombok.javac.Javac.*; import static lombok.javac.handlers.JavacHandlerUtil.*; @@ -29,20 +29,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import lombok.ConfigurationKeys; -import lombok.EqualsAndHashCode; -import lombok.core.AST.Kind; -import lombok.core.configuration.CallSuperType; -import lombok.core.AnnotationValues; -import lombok.core.handlers.HandlerUtil; -import lombok.core.handlers.InclusionExclusionUtils; -import lombok.core.handlers.InclusionExclusionUtils.Included; -import lombok.javac.Javac; -import lombok.javac.JavacAnnotationHandler; -import lombok.javac.JavacNode; -import lombok.javac.JavacTreeMaker; -import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult; - import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.BoundKind; @@ -67,6 +53,20 @@ import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Name; +import lombok.ConfigurationKeys; +import lombok.EqualsAndHashCode; +import lombok.core.AST.Kind; +import lombok.core.AnnotationValues; +import lombok.core.configuration.CallSuperType; +import lombok.core.handlers.HandlerUtil; +import lombok.core.handlers.HandlerUtil.FieldAccess; +import lombok.core.handlers.InclusionExclusionUtils; +import lombok.core.handlers.InclusionExclusionUtils.Included; +import lombok.javac.JavacAnnotationHandler; +import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; +import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult; + /** * Handles the {@code lombok.EqualsAndHashCode} annotation for javac. */ @@ -122,7 +122,6 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas return; } - boolean isDirectDescendantOfObject = true; boolean implicitCallSuper = callSuper == null; if (callSuper == null) { try { @@ -132,11 +131,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas } } - JCTree extending = Javac.getExtendsClause((JCClassDecl)typeNode.get()); - if (extending != null) { - String p = extending.toString(); - isDirectDescendantOfObject = p.equals("Object") || p.equals("java.lang.Object"); - } + boolean isDirectDescendantOfObject = isDirectDescendantOfObject(typeNode); if (isDirectDescendantOfObject && callSuper) { source.addError("Generating equals/hashCode with a supercall to java.lang.Object is pointless."); diff --git a/src/core/lombok/javac/handlers/HandleFieldNameConstants.java b/src/core/lombok/javac/handlers/HandleFieldNameConstants.java index 089d225d..8ff136fc 100644 --- a/src/core/lombok/javac/handlers/HandleFieldNameConstants.java +++ b/src/core/lombok/javac/handlers/HandleFieldNameConstants.java @@ -49,7 +49,7 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; @ProviderFor(JavacAnnotationHandler.class) public class HandleFieldNameConstants extends JavacAnnotationHandler<FieldNameConstants> { - public void generateFieldNameConstantsForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level) { + public void generateFieldNameConstantsForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, String prefix, String suffix) { JCClassDecl typeDecl = null; if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) typeNode.get(); @@ -62,13 +62,13 @@ public class HandleFieldNameConstants extends JavacAnnotationHandler<FieldNameCo } for (JavacNode field : typeNode.down()) { - if (fieldQualifiesForFieldNameConstantsGeneration(field)) generateFieldNameConstantsForField(field, errorNode.get(), level); + if (fieldQualifiesForFieldNameConstantsGeneration(field)) generateFieldNameConstantsForField(field, errorNode.get(), level, prefix, suffix); } } - private void generateFieldNameConstantsForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level) { + private void generateFieldNameConstantsForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level, String prefix, String suffix) { if (hasAnnotation(FieldNameConstants.class, fieldNode)) return; - createFieldNameConstantsForField(level, fieldNode, fieldNode, false); + createFieldNameConstantsForField(level, prefix, suffix, fieldNode, fieldNode, false); } private boolean fieldQualifiesForFieldNameConstantsGeneration(JavacNode field) { @@ -88,26 +88,32 @@ public class HandleFieldNameConstants extends JavacAnnotationHandler<FieldNameCo JavacNode node = annotationNode.up(); FieldNameConstants annotatationInstance = annotation.getInstance(); AccessLevel level = annotatationInstance.level(); + String prefix = annotatationInstance.prefix(); + String suffix = annotatationInstance.suffix(); + if (prefix.equals(" CONFIG DEFAULT ")) prefix = annotationNode.getAst().readConfiguration(ConfigurationKeys.FIELD_NAME_CONSTANTS_PREFIX); + if (suffix.equals(" CONFIG DEFAULT ")) suffix = annotationNode.getAst().readConfiguration(ConfigurationKeys.FIELD_NAME_CONSTANTS_SUFFIX); + if (prefix == null) prefix = "FIELD_"; + if (suffix == null) suffix = ""; if (node == null) return; switch (node.getKind()) { case FIELD: - if (level != AccessLevel.NONE) createFieldNameConstantsForFields(level, fields, annotationNode, annotationNode, true); + if (level != AccessLevel.NONE) createFieldNameConstantsForFields(level, prefix, suffix, fields, annotationNode, annotationNode, true); break; case TYPE: if (level == AccessLevel.NONE) { annotationNode.addWarning("type-level '@FieldNameConstants' does not work with AccessLevel.NONE."); return; } - generateFieldNameConstantsForType(node, annotationNode, level); + generateFieldNameConstantsForType(node, annotationNode, level, prefix, suffix); break; } } - private void createFieldNameConstantsForFields(AccessLevel level, Collection<JavacNode> fieldNodes, JavacNode annotationNode, JavacNode errorNode, boolean whineIfExists) { - for (JavacNode fieldNode : fieldNodes) createFieldNameConstantsForField(level, fieldNode, errorNode, whineIfExists); + private void createFieldNameConstantsForFields(AccessLevel level, String prefix, String suffix, Collection<JavacNode> fieldNodes, JavacNode annotationNode, JavacNode errorNode, boolean whineIfExists) { + for (JavacNode fieldNode : fieldNodes) createFieldNameConstantsForField(level, prefix, suffix, fieldNode, errorNode, whineIfExists); } - private void createFieldNameConstantsForField(AccessLevel level, JavacNode fieldNode, JavacNode source, boolean whineIfExists) { + private void createFieldNameConstantsForField(AccessLevel level, String prefix, String suffix, JavacNode fieldNode, JavacNode source, boolean whineIfExists) { if (fieldNode.getKind() != Kind.FIELD) { source.addError("@FieldNameConstants is only supported on a class, an enum, or a field"); return; @@ -115,7 +121,7 @@ public class HandleFieldNameConstants extends JavacAnnotationHandler<FieldNameCo JCVariableDecl field = (JCVariableDecl) fieldNode.get(); String fieldName = field.name.toString(); - String constantName = HandlerUtil.camelCaseToConstant(fieldName); + String constantName = prefix + HandlerUtil.camelCaseToConstant(fieldName) + suffix; if (constantName.equals(fieldName)) { fieldNode.addWarning("Not generating constant for this field: The name of the constant would be equal to the name of this field."); return; diff --git a/src/core/lombok/javac/handlers/HandleLog.java b/src/core/lombok/javac/handlers/HandleLog.java index d0d709e3..6d742e76 100644 --- a/src/core/lombok/javac/handlers/HandleLog.java +++ b/src/core/lombok/javac/handlers/HandleLog.java @@ -91,16 +91,18 @@ public class HandleLog { // private static final <loggerType> log = <factoryMethod>(<parameter>); JCExpression loggerType = chainDotsString(typeNode, framework.getLoggerTypeName()); JCExpression factoryMethod = chainDotsString(typeNode, framework.getLoggerFactoryMethodName()); - + JCExpression loggerName; - if (loggerTopic == null || loggerTopic.trim().length() == 0) { + if (!framework.passTypeName) { + loggerName = null; + } else if (loggerTopic == null || loggerTopic.trim().length() == 0) { loggerName = framework.createFactoryParameter(typeNode, loggingType); } else { loggerName = maker.Literal(loggerTopic); } - - JCMethodInvocation factoryMethodCall = maker.Apply(List.<JCExpression>nil(), factoryMethod, List.<JCExpression>of(loggerName)); - + + JCMethodInvocation factoryMethodCall = maker.Apply(List.<JCExpression>nil(), factoryMethod, loggerName != null ? List.<JCExpression>of(loggerName) : List.<JCExpression>nil()); + JCVariableDecl fieldDecl = recursiveSetGeneratedBy(maker.VarDef( maker.Modifiers(Flags.PRIVATE | Flags.FINAL | (useStatic ? Flags.STATIC : 0)), typeNode.toName(logFieldName), loggerType, factoryMethodCall), source, typeNode.getContext()); @@ -186,6 +188,17 @@ public class HandleLog { } } + /** + * Handles the {@link lombok.extern.flogger.Flogger} annotation for javac. + */ + @ProviderFor(JavacAnnotationHandler.class) + public static class HandleFloggerLog extends JavacAnnotationHandler<lombok.extern.flogger.Flogger> { + @Override public void handle(AnnotationValues<lombok.extern.flogger.Flogger> annotation, JCAnnotation ast, JavacNode annotationNode) { + handleFlagUsage(annotationNode, ConfigurationKeys.LOG_FLOGGER_FLAG_USAGE, "@Flogger", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); + processAnnotation(LoggingFramework.FLOGGER, annotation, annotationNode, ""); + } + } + enum LoggingFramework { // private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(TargetType.class); COMMONS(lombok.extern.apachecommons.CommonsLog.class, "org.apache.commons.logging.Log", "org.apache.commons.logging.LogFactory.getLog"), @@ -212,17 +225,29 @@ public class HandleLog { XSLF4J(lombok.extern.slf4j.XSlf4j.class, "org.slf4j.ext.XLogger", "org.slf4j.ext.XLoggerFactory.getXLogger"), // private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(TargetType.class); - JBOSSLOG(lombok.extern.jbosslog.JBossLog.class, "org.jboss.logging.Logger", "org.jboss.logging.Logger.getLogger") + JBOSSLOG(lombok.extern.jbosslog.JBossLog.class, "org.jboss.logging.Logger", "org.jboss.logging.Logger.getLogger"), + + // private static final com.google.common.flogger.FluentLogger log = com.google.common.flogger.FluentLogger.forEnclosingClass(); + FLOGGER(lombok.extern.flogger.Flogger.class, "com.google.common.flogger.FluentLogger", "com.google.common.flogger.FluentLogger.forEnclosingClass", false), ; private final Class<? extends Annotation> annotationClass; private final String loggerTypeName; private final String loggerFactoryName; + private final boolean passTypeName; + + LoggingFramework(Class<? extends Annotation> annotationClass, String loggerTypeName, String loggerFactoryName, boolean passTypeName) { + this.annotationClass = annotationClass; + this.loggerTypeName = loggerTypeName; + this.loggerFactoryName = loggerFactoryName; + this.passTypeName = passTypeName; + } LoggingFramework(Class<? extends Annotation> annotationClass, String loggerTypeName, String loggerFactoryName) { this.annotationClass = annotationClass; this.loggerTypeName = loggerTypeName; this.loggerFactoryName = loggerFactoryName; + this.passTypeName = true; } final Class<? extends Annotation> getAnnotationClass() { diff --git a/src/core/lombok/javac/handlers/HandleValue.java b/src/core/lombok/javac/handlers/HandleValue.java index f85e058e..abc5a5ca 100644 --- a/src/core/lombok/javac/handlers/HandleValue.java +++ b/src/core/lombok/javac/handlers/HandleValue.java @@ -77,6 +77,7 @@ public class HandleValue extends JavacAnnotationHandler<Value> { } handleFieldDefaults.generateFieldDefaultsForType(typeNode, annotationNode, AccessLevel.PRIVATE, true, true); handleConstructor.generateAllArgsConstructor(typeNode, AccessLevel.PUBLIC, staticConstructorName, SkipIfConstructorExists.YES, annotationNode); + handleConstructor.generateExtraNoArgsConstructor(typeNode, annotationNode); handleGetter.generateGetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true, List.<JCAnnotation>nil()); handleEqualsAndHashCode.generateEqualsAndHashCodeForType(typeNode, annotationNode); handleToString.generateToStringForType(typeNode, annotationNode); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index b5bc6e6b..f335cf94 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1813,4 +1813,12 @@ public class JavacHandlerUtil { docComments.put(from.get(), filtered[1]); } } + + public static boolean isDirectDescendantOfObject(JavacNode typeNode) { + if (!(typeNode.get() instanceof JCClassDecl)) throw new IllegalArgumentException("not a type node"); + JCTree extending = Javac.getExtendsClause((JCClassDecl)typeNode.get()); + if (extending == null) return true; + String p = extending.toString(); + return p.equals("Object") || p.equals("java.lang.Object"); + } } |