Merge branch 'standard-exception' of git://github.com/ttzn/lombok into ttzn-standard-exception

This commit is contained in:
Reinier Zwitserloot committed 2021-04-16 03:30:34 +02:00
commit 2e212de523
12 files changed
+615 -1

No files matched your search

+1
View File
@@ -2,6 +2,7 @@ Lombok contributors in alphabetical order:
Adam Juraszek <juriad@gmail.com>
Aleksandr Zhelezniak <lekan1992@gmail.com>
Amine Touzani <ttzn.dev@gmail.com>
Andre Brait <andrebrait@gmail.com>
Bulgakov Alexander <buls@yandex.ru>
Caleb Brinkman <floralvikings@gmail.com>
+6
View File
@@ -695,4 +695,10 @@ public class ConfigurationKeys {
*/
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).") {};
/**
* lombok configuration: {@code lombok.standardException.flagUsage} = {@code WARNING} | {@code ERROR}.
*
* If set, <em>any</em> usage of {@code @StandardException} results in a warning / error.
*/
public static final ConfigurationKey<FlagUsageType> STANDARD_EXCEPTION_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.standardException.flagUsage", "Emit a warning or error if @StandardException is used.") {};
}
@@ -0,0 +1,248 @@
/*
* Copyright (C) 2010-2020 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.eclipse.handlers;
import lombok.AccessLevel;
import lombok.ConfigurationKeys;
import lombok.experimental.StandardException;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
import lombok.eclipse.Eclipse;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
import lombok.eclipse.handlers.EclipseHandlerUtil.*;
import lombok.spi.Provides;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import java.lang.reflect.Modifier;
import java.util.*;
import static lombok.core.handlers.HandlerUtil.handleFlagUsage;
import static lombok.eclipse.Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
import static lombok.eclipse.Eclipse.pos;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
@Provides
public class HandleStandardException extends EclipseAnnotationHandler<StandardException> {
private static final String NAME = StandardException.class.getSimpleName();
@Override
public void handle(AnnotationValues<StandardException> annotation, Annotation ast, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.STANDARD_EXCEPTION_FLAG_USAGE, "@StandardException");
EclipseNode typeNode = annotationNode.up();
if (!checkLegality(typeNode, annotationNode)) return;
SuperParameter message = new SuperParameter("message", new SingleTypeReference("String".toCharArray(), pos(typeNode.get())));
SuperParameter cause = new SuperParameter("cause", new SingleTypeReference("Throwable".toCharArray(), pos(typeNode.get())));
boolean skip = true;
generateConstructor(
typeNode, AccessLevel.PUBLIC, Collections.<SuperParameter>emptyList(), skip, annotationNode);
generateConstructor(
typeNode, AccessLevel.PUBLIC, Collections.singletonList(message), skip, annotationNode);
generateConstructor(
typeNode, AccessLevel.PUBLIC, Collections.singletonList(cause), skip, annotationNode);
generateConstructor(
typeNode, AccessLevel.PUBLIC, Arrays.asList(message, cause), skip, annotationNode);
}
private static boolean checkLegality(EclipseNode typeNode, EclipseNode errorNode) {
TypeDeclaration typeDecl = null;
if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get();
int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
boolean notAClass = (modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0;
if (typeDecl == null || notAClass) {
errorNode.addError(HandleStandardException.NAME + " is only supported on a class or an enum.");
return false;
}
return true;
}
public void generateConstructor(
EclipseNode typeNode, AccessLevel level, List<SuperParameter> parameters, boolean skipIfConstructorExists,
EclipseNode sourceNode) {
generate(typeNode, level, parameters, skipIfConstructorExists, sourceNode);
}
public void generate(
EclipseNode typeNode, AccessLevel level, List<SuperParameter> parameters, boolean skipIfConstructorExists,
EclipseNode sourceNode) {
if (!(skipIfConstructorExists
&& constructorExists(typeNode, parameters) != MemberExistsResult.NOT_EXISTS)) {
ConstructorDeclaration constr = createConstructor(level, typeNode, parameters, sourceNode);
injectMethod(typeNode, constr);
}
}
/**
* Checks if a constructor with the provided parameters exists under the type node.
*/
public static MemberExistsResult constructorExists(EclipseNode node, List<SuperParameter> parameters) {
node = upToTypeNode(node);
SuperParameter[] parameterArray = parameters.toArray(new SuperParameter[0]);
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) {
if (!paramsMatch(node, def.arguments, parameterArray)) continue;
return getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK;
}
}
}
return MemberExistsResult.NOT_EXISTS;
}
private static boolean paramsMatch(EclipseNode node, Argument[] arguments, SuperParameter[] parameters) {
if (arguments == null) {
return parameters.length == 0;
} else if (arguments.length != parameters.length) {
return false;
} else {
for (int i = 0; i < parameters.length; i++) {
String fieldTypeName = Eclipse.toQualifiedName(parameters[i].type.getTypeName());
String argTypeName = Eclipse.toQualifiedName(arguments[i].type.getTypeName());
if (!typeNamesMatch(node, fieldTypeName, argTypeName))
return false;
}
}
return true;
}
private static boolean typeNamesMatch(EclipseNode node, String a, String b) {
boolean isFqn = node.getImportListAsTypeResolver().typeMatches(node, a, b);
boolean reverseIsFqn = node.getImportListAsTypeResolver().typeMatches(node, b, a);
return isFqn || reverseIsFqn;
}
private static final char[][] JAVA_BEANS_CONSTRUCTORPROPERTIES = new char[][] { "java".toCharArray(), "beans".toCharArray(), "ConstructorProperties".toCharArray() };
public static Annotation[] createConstructorProperties(ASTNode source, Collection<SuperParameter> fields) {
if (fields.isEmpty()) return null;
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
long[] poss = new long[3];
Arrays.fill(poss, p);
QualifiedTypeReference constructorPropertiesType = new QualifiedTypeReference(JAVA_BEANS_CONSTRUCTORPROPERTIES, poss);
setGeneratedBy(constructorPropertiesType, source);
SingleMemberAnnotation ann = new SingleMemberAnnotation(constructorPropertiesType, pS);
ann.declarationSourceEnd = pE;
ArrayInitializer fieldNames = new ArrayInitializer();
fieldNames.sourceStart = pS;
fieldNames.sourceEnd = pE;
fieldNames.expressions = new Expression[fields.size()];
int ctr = 0;
for (SuperParameter field : fields) {
char[] fieldName = field.name.toCharArray();
fieldNames.expressions[ctr] = new StringLiteral(fieldName, pS, pE, 0);
setGeneratedBy(fieldNames.expressions[ctr], source);
ctr++;
}
ann.memberValue = fieldNames;
setGeneratedBy(ann, source);
setGeneratedBy(ann.memberValue, source);
return new Annotation[] { ann };
}
@SuppressWarnings("deprecation") public static ConstructorDeclaration createConstructor(
AccessLevel level, EclipseNode type, Collection<SuperParameter> parameters, EclipseNode sourceNode) {
ASTNode source = sourceNode.get();
TypeDeclaration typeDeclaration = ((TypeDeclaration) type.get());
boolean isEnum = (((TypeDeclaration) type.get()).modifiers & ClassFileConstants.AccEnum) != 0;
if (isEnum) level = AccessLevel.PRIVATE;
boolean addConstructorProperties;
if (parameters.isEmpty()) {
addConstructorProperties = false;
} else {
Boolean v = type.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_ADD_CONSTRUCTOR_PROPERTIES);
addConstructorProperties = v != null ? v.booleanValue() :
Boolean.FALSE.equals(type.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_SUPPRESS_CONSTRUCTOR_PROPERTIES));
}
ConstructorDeclaration constructor = new ConstructorDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
constructor.modifiers = toEclipseModifier(level);
constructor.selector = typeDeclaration.name;
constructor.thrownExceptions = null;
constructor.typeParameters = null;
constructor.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
constructor.bodyStart = constructor.declarationSourceStart = constructor.sourceStart = source.sourceStart;
constructor.bodyEnd = constructor.declarationSourceEnd = constructor.sourceEnd = source.sourceEnd;
constructor.arguments = null;
List<Argument> params = new ArrayList<Argument>();
List<Expression> superArgs = new ArrayList<Expression>();
for (SuperParameter fieldNode : parameters) {
char[] fieldName = fieldNode.name.toCharArray();
long fieldPos = (((long) type.get().sourceStart) << 32) | type.get().sourceEnd;
Argument parameter = new Argument(fieldName, fieldPos, copyType(fieldNode.type, source), Modifier.FINAL);
params.add(parameter);
superArgs.add(new SingleNameReference(fieldName, 0));
}
// Super constructor call
constructor.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.Super);
constructor.constructorCall.arguments = superArgs.toArray(new Expression[0]);
constructor.constructorCall.sourceStart = source.sourceStart;
constructor.constructorCall.sourceEnd = source.sourceEnd;
constructor.arguments = params.isEmpty() ? null : params.toArray(new Argument[0]);
Annotation[] constructorProperties = null;
if (addConstructorProperties && !isLocalType(type)) constructorProperties = createConstructorProperties(source, parameters);
constructor.annotations = copyAnnotations(source,
constructorProperties);
constructor.traverse(new SetGeneratedByVisitor(source), typeDeclaration.scope);
return constructor;
}
public static boolean isLocalType(EclipseNode type) {
Kind kind = type.up().getKind();
if (kind == Kind.COMPILATION_UNIT) return false;
if (kind == Kind.TYPE) return isLocalType(type.up());
return true;
}
private static class SuperParameter {
private final String name;
private final TypeReference type;
private SuperParameter(String name, TypeReference type) {
this.name = name;
this.type = type;
}
}
}
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2010-2017 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.experimental;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface StandardException {
}
@@ -0,0 +1,215 @@
/*
* Copyright (C) 2010-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.javac.handlers;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
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.ConfigurationKeys;
import lombok.experimental.StandardException;
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.*;
import lombok.spi.Provides;
import static lombok.core.handlers.HandlerUtil.handleFlagUsage;
import static lombok.javac.Javac.CTC_VOID;
import static lombok.javac.handlers.JavacHandlerUtil.*;
@Provides
public class HandleStandardException extends JavacAnnotationHandler<StandardException> {
private static final String NAME = StandardException.class.getSimpleName();
@Override
public void handle(AnnotationValues<StandardException> annotation, JCAnnotation ast, JavacNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.STANDARD_EXCEPTION_FLAG_USAGE, "@StandardException");
deleteAnnotationIfNeccessary(annotationNode, StandardException.class);
JavacNode typeNode = annotationNode.up();
if (!checkLegality(typeNode, annotationNode)) return;
SuperParameter messageField = new SuperParameter("message", typeNode.getSymbolTable().stringType);
SuperParameter causeField = new SuperParameter("cause", typeNode.getSymbolTable().throwableType);
boolean skip = true;
generateConstructor(typeNode, AccessLevel.PUBLIC, List.<SuperParameter>nil(), skip, annotationNode);
generateConstructor(typeNode, AccessLevel.PUBLIC, List.of(messageField), skip, annotationNode);
generateConstructor(typeNode, AccessLevel.PUBLIC, List.of(causeField), skip, annotationNode);
generateConstructor(typeNode, AccessLevel.PUBLIC, List.of(messageField, causeField), skip, annotationNode);
}
private static boolean checkLegality(JavacNode typeNode, JavacNode errorNode) {
JCClassDecl typeDecl = null;
if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) typeNode.get();
long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags;
boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION)) != 0;
if (typeDecl == null || notAClass) {
errorNode.addError(NAME + " is only supported on a class or an enum.");
return false;
}
return true;
}
public void generateConstructor(JavacNode typeNode, AccessLevel level, List<SuperParameter> fields,
boolean skipIfConstructorExists, JavacNode source) {
generate(typeNode, level, fields, skipIfConstructorExists, source);
}
private void generate(JavacNode typeNode, AccessLevel level, List<SuperParameter> fields, boolean skipIfConstructorExists,
JavacNode source) {
ListBuffer<Type> argTypes = new ListBuffer<Type>();
for (SuperParameter field : fields) {
Type mirror = field.type;
if (mirror == null) {
argTypes = null;
break;
}
argTypes.append(mirror);
}
List<Type> argTypes_ = argTypes == null ? null : argTypes.toList();
if (!(skipIfConstructorExists && constructorExists(typeNode, fields) != MemberExistsResult.NOT_EXISTS)) {
JCMethodDecl constr = createConstructor(level, typeNode, fields, source);
injectMethod(typeNode, constr, argTypes_, Javac.createVoidType(typeNode.getSymbolTable(), CTC_VOID));
}
}
public static MemberExistsResult constructorExists(JavacNode node, List<SuperParameter> parameters) {
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.mods.flags & Flags.GENERATEDCONSTR) == 0) {
if (!paramsMatch(md.params, parameters)) continue;
return getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK;
}
}
}
}
return MemberExistsResult.NOT_EXISTS;
}
private static boolean paramsMatch(List<JCVariableDecl> params, List<SuperParameter> superParams) {
if (params == null) {
return superParams.size() == 0;
} else if (params.size() != superParams.size()) {
return false;
} else {
for (int i = 0; i < superParams.size(); i++) {
SuperParameter field = superParams.get(i);
JCVariableDecl param = params.get(i);
if (!param.getType().type.equals(field.type))
return false;
}
}
return true;
}
public static void addConstructorProperties(JCModifiers mods, JavacNode node, List<SuperParameter> fields) {
if (fields.isEmpty()) return;
JavacTreeMaker maker = node.getTreeMaker();
JCExpression constructorPropertiesType = chainDots(node, "java", "beans", "ConstructorProperties");
ListBuffer<JCExpression> fieldNames = new ListBuffer<JCExpression>();
for (SuperParameter field : fields) {
Name fieldName = node.toName(field.name);
fieldNames.append(maker.Literal(fieldName.toString()));
}
JCExpression fieldNamesArray = maker.NewArray(null, List.<JCExpression>nil(), fieldNames.toList());
JCAnnotation annotation = maker.Annotation(constructorPropertiesType, List.of(fieldNamesArray));
mods.annotations = mods.annotations.append(annotation);
}
@SuppressWarnings("deprecation") public static JCMethodDecl createConstructor(AccessLevel level, JavacNode typeNode,
List<SuperParameter> fieldsToParam, JavacNode source) {
JavacTreeMaker maker = typeNode.getTreeMaker();
boolean isEnum = (((JCClassDecl) typeNode.get()).mods.flags & Flags.ENUM) != 0;
if (isEnum) level = AccessLevel.PRIVATE;
boolean addConstructorProperties;
if (fieldsToParam.isEmpty()) {
addConstructorProperties = false;
} else {
Boolean v = typeNode.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_ADD_CONSTRUCTOR_PROPERTIES);
addConstructorProperties = v != null ? v.booleanValue() :
Boolean.FALSE.equals(typeNode.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_SUPPRESS_CONSTRUCTOR_PROPERTIES));
}
ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
ListBuffer<JCExpression> superArgs = new ListBuffer<JCExpression>();
for (SuperParameter fieldNode : fieldsToParam) {
Name fieldName = source.toName(fieldNode.name);
long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext());
JCExpression pType = maker.getUnderlyingTreeMaker().Ident(fieldNode.type.tsym);
JCVariableDecl param = maker.VarDef(maker.Modifiers(flags), fieldName, pType, null);
params.append(param);
superArgs.append(maker.Ident(fieldName));
}
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(),
maker.Ident(typeNode.toName("super")),
superArgs.toList());
statements.add(maker.Exec(callToSuper));
JCModifiers mods = maker.Modifiers(toJavacModifier(level), List.<JCAnnotation>nil());
if (addConstructorProperties && !isLocalType(typeNode) && LombokOptionsFactory.getDelombokOptions(typeNode.getContext()).getFormatPreferences().generateConstructorProperties()) {
addConstructorProperties(mods, typeNode, fieldsToParam);
}
return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("<init>"),
null, List.<JCTypeParameter>nil(), params.toList(), List.<JCExpression>nil(),
maker.Block(0L, statements.toList()), null), source);
}
public static boolean isLocalType(JavacNode type) {
Kind kind = type.up().getKind();
if (kind == Kind.COMPILATION_UNIT) return false;
if (kind == Kind.TYPE) return isLocalType(type.up());
return true;
}
private static class SuperParameter {
private final String name;
private final Type type;
private SuperParameter(String name, Type type) {
this.name = name;
this.type = type;
}
}
}
@@ -16,7 +16,9 @@ public class Symtab {
public static Symtab instance(Context context) {return null;}
public Type unknownType;
public TypeSymbol noSymbol;
public Type stringType;
public Type throwableType;
// JDK 9
public ModuleSymbol unnamedModule;
}
@@ -0,0 +1,39 @@
class EmptyException extends Exception {
@java.lang.SuppressWarnings("all")
public EmptyException() {
}
@java.lang.SuppressWarnings("all")
public EmptyException(final String message) {
super(message);
}
@java.lang.SuppressWarnings("all")
public EmptyException(final Throwable cause) {
super(cause);
}
@java.lang.SuppressWarnings("all")
public EmptyException(final String message, final Throwable cause) {
super(message, cause);
}
}
class NoArgsException extends Exception {
public NoArgsException() {
}
@java.lang.SuppressWarnings("all")
public NoArgsException(final String message) {
super(message);
}
@java.lang.SuppressWarnings("all")
public NoArgsException(final Throwable cause) {
super(cause);
}
@java.lang.SuppressWarnings("all")
public NoArgsException(final String message, final Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,8 @@
import lombok.experimental.StandardException;
@StandardException class EmptyException extends Exception {
}
@StandardException class NoArgsException extends Exception {
public NoArgsException() {
}
}
@@ -0,0 +1,36 @@
<#import "../_features.html" as f>
<@f.scaffold title="@StandardException"
logline="TODO">
<@f.history>
<p>
<code>@StandardException</code> was introduced as an experimental feature in lombok v1.18.21.
</p>
</@f.history>
<@f.overview>
<p>
This annotation is intended to be used on subclasses of <code>java.util.Throwable</code>. For each of the four constructors in <code>Throwable</code>, it will generate a corresponding constructor in the target class, that simply forwards its argument to its super-counterpart.
</p><p>
If any of those constructors is manually overriden, it is simply skipped. This allows applying special treatment such as annotations.
</p>
</@f.overview>
<@f.snippets name="StandardException" />
<@f.confKeys>
<dt>
<code>lombok.standardException.addConstructorProperties</code> = [<code>true</code> | <code>false</code>] (default: <code>false</code>)
</dt><dt>
<code>lombok.standardException.flagUsage</code> = [<code>warning</code> | <code>error</code>] (default: not set)
</dt><dd>
Lombok will flag any usage of <code>@StandardException</code> as a warning or error if configured.
</dd>
</@f.confKeys>
<@f.smallPrint>
<p>
Although such situation is unlikely to occur, this annotation can technically be applied to any class for which all four expected constructors are defined in a superclass.
</p>
</@f.smallPrint>
</@f.scaffold>
@@ -75,6 +75,10 @@
<@main.feature title="@Jacksonized" href="Jacksonized">
Bob, meet Jackson. Lets make sure you become fast friends.
</@main.feature>
<@main.feature title="@StandardException" href="StandardException">
TODO
</@main.feature>
</div>
<@f.confKeys>
@@ -0,0 +1,16 @@
public class ExampleException extends Exception {
public ExampleException() {
}
public ExampleException(String message) {
super(message);
}
public ExampleException(Throwable cause) {
super(cause);
}
public ExampleException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,5 @@
import lombok.experimental.StandardException;
@StandardException
public class ExampleException extends Exception {
}