From 772792c971d49ed6dfa371a54b372ae12d703cdc Mon Sep 17 00:00:00 2001 From: susu <360858329@qq.com> Date: Tue, 7 Feb 2017 22:13:19 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0ivy=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E4=BB=A3=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index f20973cf50..153a8fd841 100644 --- a/build.xml +++ b/build.xml @@ -24,7 +24,7 @@ This buildfile is part of projectlombok.org. It is the main entry point that contains the common tasks and can be called on to run the main aspects of all the sub-scripts. - + From b258eeb2d04797206fe2f774f223d29ab78ea9fd Mon Sep 17 00:00:00 2001 From: susu <360858329@qq.com> Date: Wed, 8 Feb 2017 00:28:46 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E5=90=88=E5=85=A5Boundse?= =?UTF-8?q?tter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 提交修改 --- src/core/lombok/core/util/Names.java | 27 ++++ .../eclipse/handlers/EclipseHandlerUtil.java | 22 +++ .../lombok/eclipse/handlers/HandleSetter.java | 127 ++++++++++++++++-- src/core/lombok/experimental/Accessors.java | 28 +++- .../lombok/javac/handlers/HandleSetter.java | 98 ++++++++++++-- .../javac/handlers/JavacHandlerUtil.java | 24 ++++ .../lombok/eclipse/agent/EclipsePatcher.java | 2 - ...terAccessorsPropertyNameConstantPlain.java | 19 +++ .../after-delombok/SetterBoundPlain.java | 16 +++ ...terAccessorsPropertyNameConstantPlain.java | 19 +++ .../resource/after-ecj/SetterBoundPlain.java | 18 +++ ...terAccessorsPropertyNameConstantPlain.java | 11 ++ .../resource/before/SetterBoundPlain.java | 10 ++ 13 files changed, 392 insertions(+), 29 deletions(-) create mode 100644 src/core/lombok/core/util/Names.java create mode 100644 test/transform/resource/after-delombok/SetterAccessorsPropertyNameConstantPlain.java create mode 100644 test/transform/resource/after-delombok/SetterBoundPlain.java create mode 100644 test/transform/resource/after-ecj/SetterAccessorsPropertyNameConstantPlain.java create mode 100644 test/transform/resource/after-ecj/SetterBoundPlain.java create mode 100644 test/transform/resource/before/SetterAccessorsPropertyNameConstantPlain.java create mode 100644 test/transform/resource/before/SetterBoundPlain.java diff --git a/src/core/lombok/core/util/Names.java b/src/core/lombok/core/util/Names.java new file mode 100644 index 0000000000..57d54fb07f --- /dev/null +++ b/src/core/lombok/core/util/Names.java @@ -0,0 +1,27 @@ +package lombok.core.util; + +import static java.lang.Character.*; + +public class Names { + + private Names() { + }; + + public static String camelCaseToConstant(final String fieldName) { + if (fieldName == null || fieldName.isEmpty()) return ""; + char[] chars = fieldName.toCharArray(); + StringBuilder b = new StringBuilder(); + b.append(toUpperCase(chars[0])); + for (int i = 1, iend = chars.length; i < iend; i++) { + char c = chars[i]; + if (isUpperCase(c)) { + b.append('_'); + } else { + c = toUpperCase(c); + } + b.append(c); + } + return b.toString(); + } + +} diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index f822e09574..63b734818f 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -1010,6 +1010,28 @@ public static String toWitherName(EclipseNode field, boolean isBoolean) { return HandlerUtil.toWitherName(field.getAst(), getAccessorsForField(field), field.getName(), isBoolean); } + public static boolean shouldAddPropertyNameConstant(EclipseNode field) { + if ((((FieldDeclaration) field.get()).modifiers & ClassFileConstants.AccStatic) != 0) return false; + AnnotationValues accessors = EclipseHandlerUtil.getAccessorsForField(field); + Accessors instance = accessors.getInstance(); + return instance.propertyNameConstant() || instance.bound(); + } + + public static boolean shouldAddBoundProperty(EclipseNode field) { + if ((((FieldDeclaration) field.get()).modifiers & ClassFileConstants.AccStatic) != 0) return false; + + AnnotationValues accessors = EclipseHandlerUtil.getAccessorsForField(field); + + Accessors instance = accessors.getInstance(); + return instance.bound(); + } + + public static String propertyChangeSupportFieldName(EclipseNode field) { + AnnotationValues accessors = EclipseHandlerUtil.getAccessorsForField(field); + Accessors instance = accessors.getInstance(); + return instance.propertyChangeSupportFieldName(); + } + /** * When generating a setter, the setter either returns void (beanspec) or Self (fluent). * This method scans for the {@code Accessors} annotation and associated config properties to figure that out. diff --git a/src/core/lombok/eclipse/handlers/HandleSetter.java b/src/core/lombok/eclipse/handlers/HandleSetter.java index 1fcf751d99..d96fd6506e 100644 --- a/src/core/lombok/eclipse/handlers/HandleSetter.java +++ b/src/core/lombok/eclipse/handlers/HandleSetter.java @@ -24,33 +24,32 @@ import static lombok.core.handlers.HandlerUtil.*; import static lombok.eclipse.Eclipse.*; import static lombok.eclipse.handlers.EclipseHandlerUtil.*; +import static lombok.eclipse.handlers.EclipseHandlerUtil.toAllSetterNames; +import static lombok.eclipse.handlers.EclipseHandlerUtil.toSetterName; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; -import lombok.AccessLevel; -import lombok.ConfigurationKeys; -import lombok.Setter; -import lombok.core.AST.Kind; -import lombok.core.AnnotationValues; -import lombok.eclipse.EclipseAnnotationHandler; -import lombok.eclipse.EclipseNode; -import lombok.eclipse.handlers.EclipseHandlerUtil.FieldAccess; - import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.Argument; import org.eclipse.jdt.internal.compiler.ast.Assignment; import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; +import org.eclipse.jdt.internal.compiler.ast.FieldReference; +import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; +import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.NameReference; +import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.ReturnStatement; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.Statement; +import org.eclipse.jdt.internal.compiler.ast.StringLiteral; import org.eclipse.jdt.internal.compiler.ast.ThisReference; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeReference; @@ -58,6 +57,17 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeIds; import org.mangosdk.spi.ProviderFor; +import lombok.AccessLevel; +import lombok.ConfigurationKeys; +import lombok.Setter; +import lombok.core.AST.Kind; +import lombok.core.AnnotationValues; +import lombok.core.util.Names; +import lombok.eclipse.EclipseAnnotationHandler; +import lombok.eclipse.EclipseNode; +import lombok.eclipse.handlers.EclipseHandlerUtil.FieldAccess; +import lombok.eclipse.handlers.EclipseHandlerUtil.MemberExistsResult; + /** * Handles the {@code lombok.Setter} annotation for eclipse. */ @@ -167,11 +177,19 @@ public void createSetterForField( String setterName = toSetterName(fieldNode, isBoolean); boolean shouldReturnThis = shouldReturnThis(fieldNode); + boolean bound = shouldAddBoundProperty(fieldNode); + String propertyChangeSupportFieldName = null; + if (bound) { + propertyChangeSupportFieldName = propertyChangeSupportFieldName(fieldNode); + } + if (setterName == null) { fieldNode.addWarning("Not generating setter for this field: It does not fit your @Accessors prefix list."); return; } + createPropertyNameConstantForField(fieldNode, source); + int modifier = toEclipseModifier(level) | (field.modifiers & ClassFileConstants.AccStatic); for (String altName : toAllSetterNames(fieldNode, isBoolean)) { @@ -192,11 +210,15 @@ public void createSetterForField( } } - MethodDeclaration method = createSetter((TypeDeclaration) fieldNode.up().get(), fieldNode, setterName, shouldReturnThis, modifier, sourceNode, onMethod, onParam); + MethodDeclaration method = createSetter((TypeDeclaration) fieldNode.up().get(), fieldNode, setterName, shouldReturnThis, modifier, sourceNode, onMethod, onParam, bound, propertyChangeSupportFieldName); injectMethod(fieldNode.up(), method); } static MethodDeclaration createSetter(TypeDeclaration parent, EclipseNode fieldNode, String name, boolean shouldReturnThis, int modifier, EclipseNode sourceNode, List onMethod, List onParam) { + return createSetter(parent, fieldNode, name, shouldReturnThis, modifier, sourceNode, onMethod, onParam, false, null); + } + + static MethodDeclaration createSetter(TypeDeclaration parent, EclipseNode fieldNode, String name, boolean shouldReturnThis, int modifier, EclipseNode sourceNode, List onMethod, List onParam, boolean bound, String propertyChangeSupportFieldName) { FieldDeclaration field = (FieldDeclaration) fieldNode.get(); ASTNode source = sourceNode.get(); int pS = source.sourceStart, pE = source.sourceEnd; @@ -235,6 +257,17 @@ static MethodDeclaration createSetter(TypeDeclaration parent, EclipseNode fieldN Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); List statements = new ArrayList(5); + + LocalDeclaration oldValueVarDecl = null; + if (bound) { + oldValueVarDecl = new LocalDeclaration("old".toCharArray(), 0, -1); + oldValueVarDecl.modifiers = Modifier.FINAL; + oldValueVarDecl.type = copyType(field.type, source); + oldValueVarDecl.initialization = fieldRef; + oldValueVarDecl.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; + statements.add(oldValueVarDecl); + } + if (nonNulls.length == 0) { statements.add(assignment); } else { @@ -243,6 +276,29 @@ static MethodDeclaration createSetter(TypeDeclaration parent, EclipseNode fieldN statements.add(assignment); } + if (bound) { + MessageSend firePropChangeMethodCall = new MessageSend(); + + FieldReference propChangeFieldRef = new FieldReference(propertyChangeSupportFieldName.toCharArray(), p); + propChangeFieldRef.receiver = new ThisReference((int) (p >> 32), (int) p); + firePropChangeMethodCall.receiver = propChangeFieldRef; + firePropChangeMethodCall.selector = "firePropertyChange".toCharArray(); + + Expression propNameParam = new SingleNameReference(createPropConstantName(fieldNode.getName()).toCharArray(), p); + Expression oldValueParam = new SingleNameReference(oldValueVarDecl.name, p); + Expression newValueParam = createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source); + ; + + firePropChangeMethodCall.arguments = new Expression[] {propNameParam, oldValueParam, newValueParam}; + firePropChangeMethodCall.nameSourcePosition = p; + firePropChangeMethodCall.sourceStart = pS; + firePropChangeMethodCall.sourceEnd = firePropChangeMethodCall.statementEnd = pE; + firePropChangeMethodCall.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; + + statements.add(firePropChangeMethodCall); + } + + if (shouldReturnThis) { ThisReference thisRef = new ThisReference(pS, pE); ReturnStatement returnThis = new ReturnStatement(thisRef, pS, pE); @@ -254,4 +310,55 @@ static MethodDeclaration createSetter(TypeDeclaration parent, EclipseNode fieldN method.traverse(new SetGeneratedByVisitor(source), parent.scope); return method; } + + private static void createPropertyNameConstantForField(EclipseNode fieldNode, ASTNode source) { + boolean propConstant = shouldAddPropertyNameConstant(fieldNode); + if( propConstant && MemberExistsResult.NOT_EXISTS.equals(fieldExists(createPropConstantName(fieldNode.getName()), fieldNode))) { + FieldDeclaration propConstantFieldDecl = createPropertyNameConstant(fieldNode, source); + injectField(fieldNode.up(), propConstantFieldDecl); + } + } + + private static FieldDeclaration createPropertyNameConstant(EclipseNode fieldNode, ASTNode source) { + String constantValue = fieldNode.getName(); + String constantName = createPropConstantName(constantValue); + FieldDeclaration propConstantFieldDecl = createStringConstant(source, constantName, constantValue); + return propConstantFieldDecl; + } + + private static FieldDeclaration createStringConstant(ASTNode source, String constantName, String constantValue) { + int pS = source.sourceStart, pE = source.sourceEnd; + FieldDeclaration propConstantFieldDecl = new FieldDeclaration(constantName.toCharArray(), 0, -1); + setGeneratedBy(propConstantFieldDecl, source); + propConstantFieldDecl.declarationSourceEnd = -1; + propConstantFieldDecl.modifiers = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL; + propConstantFieldDecl.type = createTypeReference("java.lang.String", source); + propConstantFieldDecl.initialization = new StringLiteral(constantValue.toCharArray(), pS, pE, 0); + propConstantFieldDecl.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; + return propConstantFieldDecl; + } + + private static String createPropConstantName(String fieldNodeName) { + return "PROP_" + Names.camelCaseToConstant(fieldNodeName); + } + + public static TypeReference createTypeReference(String typeName, ASTNode source) { + int pS = source.sourceStart, pE = source.sourceEnd; + long p = (long) pS << 32 | pE; + + TypeReference typeReference; + if (typeName.contains(".")) { + + char[][] typeNameTokens = fromQualifiedName(typeName); + long[] pos = new long[typeNameTokens.length]; + Arrays.fill(pos, p); + + typeReference = new QualifiedTypeReference(typeNameTokens, pos); + } else { + typeReference = null; + } + + setGeneratedBy(typeReference, source); + return typeReference; + } } diff --git a/src/core/lombok/experimental/Accessors.java b/src/core/lombok/experimental/Accessors.java index 7d9fdc5c25..e59c40878e 100644 --- a/src/core/lombok/experimental/Accessors.java +++ b/src/core/lombok/experimental/Accessors.java @@ -51,10 +51,30 @@ boolean chain() default false; /** - * If present, only fields with any of the stated prefixes are given the getter/setter treatment. - * Note that a prefix only counts if the next character is NOT a lowercase character or the last - * letter of the prefix is not a letter (for instance an underscore). If multiple fields - * all turn into the same name when the prefix is stripped, an error will be generated. + * If present, only fields with any of the stated prefixes are given the + * getter/setter treatment. Note that a prefix only counts if the next + * character is NOT a lowercase character or the last letter of the prefix + * is not a letter (for instance an underscore). If multiple fields all turn + * into the same name when the prefix is stripped, an error will be + * generated. */ String[] prefix() default {}; + + /** + * If true, a propertyName constant is generated (e. g. 'public final String + * PROP_FOO = "foo";' for the property foo). + */ + boolean propertyNameConstant() default false; + + /** + * If true, property change support is added to the setter implementation. + * This will also cause the generation of propertyNameConstant(s). + */ + boolean bound() default false; + + /** + * field name to use for bound setters to call firePropertyChange on - + * instance type must be java.beans.PropertyChangeSupport. + */ + String propertyChangeSupportFieldName() default "propertySupport"; } diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index 02cc377551..a8e36e613f 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -21,34 +21,27 @@ */ package lombok.javac.handlers; -import static lombok.javac.Javac.*; import static lombok.core.handlers.HandlerUtil.*; +import static lombok.javac.Javac.CTC_VOID; import static lombok.javac.handlers.JavacHandlerUtil.*; +import static lombok.javac.handlers.JavacHandlerUtil.toAllSetterNames; +import static lombok.javac.handlers.JavacHandlerUtil.toSetterName; import java.util.Collection; -import lombok.AccessLevel; -import lombok.ConfigurationKeys; -import lombok.Setter; -import lombok.core.AST.Kind; -import lombok.core.AnnotationValues; -import lombok.javac.Javac; -import lombok.javac.JavacAnnotationHandler; -import lombok.javac.JavacNode; -import lombok.javac.JavacTreeMaker; -import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; - import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCAssign; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; import com.sun.tools.javac.tree.JCTree.JCReturn; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCTypeParameter; @@ -57,6 +50,20 @@ import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Name; +import lombok.AccessLevel; +import lombok.ConfigurationKeys; +import lombok.Setter; +import lombok.core.AST.Kind; +import lombok.core.AnnotationValues; +import lombok.core.util.Names; +import lombok.javac.Javac; +import lombok.javac.JavacAnnotationHandler; +import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; +import lombok.javac.handlers.JavacHandlerUtil.CopyJavadoc; +import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; +import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult; + /** * Handles the {@code lombok.Setter} annotation for javac. */ @@ -169,6 +176,8 @@ public void createSetterForField(AccessLevel level, JavacNode fieldNode, JavacNo return; } + createPropertyNameConstantForField(fieldNode, sourceNode); + for (String altName : toAllSetterNames(fieldNode)) { switch (methodExists(altName, fieldNode, false, 1)) { case EXISTS_BY_LOMBOK: @@ -203,13 +212,31 @@ public void createSetterForField(AccessLevel level, JavacNode fieldNode, JavacNo injectMethod(fieldNode.up(), createdSetter, fieldType == null ? null : List.of(fieldType), returnType); } + public static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeMaker treeMaker, String setterName, boolean shouldReturnThis, JCTree source, List onMethod, List onParam) { + return null; + } + public static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeMaker treeMaker, JavacNode source, List onMethod, List onParam) { String setterName = toSetterName(field); boolean returnThis = shouldReturnThis(field); - return createSetter(access, field, treeMaker, setterName, returnThis, source, onMethod, onParam); + boolean bound = shouldAddBoundProperty(field); + String propertyChangeSupportFieldName = null; + if (bound) { + propertyChangeSupportFieldName = propertyChangeSupportFieldName(field); + } + return createSetter(access, field, treeMaker, setterName, returnThis, source, onMethod, onParam, bound, propertyChangeSupportFieldName); } public static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeMaker treeMaker, String setterName, boolean shouldReturnThis, JavacNode source, List onMethod, List onParam) { + boolean bound = shouldAddBoundProperty(field); + String propertyChangeSupportFieldName = null; + if (bound) { + propertyChangeSupportFieldName = propertyChangeSupportFieldName(field); + } + return createSetter(access, field, treeMaker, setterName, shouldReturnThis, source, onMethod, onParam, bound, propertyChangeSupportFieldName); + } + + private static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeMaker treeMaker, String setterName, boolean shouldReturnThis, JavacNode source, List onMethod, List onParam, boolean bound, String propertyChangeSupportFieldName) { if (setterName == null) return null; JCVariableDecl fieldDecl = (JCVariableDecl) field.get(); @@ -227,6 +254,12 @@ public static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeM long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext()); JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(flags, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); + JCVariableDecl oldVar = null; + if (bound) { + oldVar = treeMaker.VarDef(treeMaker.Modifiers(Flags.FINAL), field.toName("old"), fieldDecl.vartype, fieldRef); + statements.append(oldVar); + } + if (nonNulls.isEmpty()) { statements.append(treeMaker.Exec(assign)); } else { @@ -246,6 +279,17 @@ public static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeM shouldReturnThis = false; } + if (bound) { + JCExpression callFirePropChanged = chainDotsString(field, "this." + propertyChangeSupportFieldName + ".firePropertyChange"); + JCExpression propNameParam = chainDotsString(field, createPropConstantName(field.getName())); + JCExpression oldValueParam = treeMaker.Ident(oldVar.name); + JCExpression currentValueParam = fieldRef; + + JCMethodInvocation callFire = treeMaker.Apply(List.nil(), callFirePropChanged, List.of(propNameParam, oldValueParam, currentValueParam)); + + statements.append(treeMaker.Exec(callFire)); + } + if (shouldReturnThis) { JCReturn returnStatement = treeMaker.Return(treeMaker.Ident(field.toName("this"))); statements.append(returnStatement); @@ -267,4 +311,32 @@ public static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeM copyJavadoc(field, decl, CopyJavadoc.SETTER); return decl; } + + private void createPropertyNameConstantForField(JavacNode fieldNode, JavacNode sourceNode) { + boolean propConstant = shouldAddPropertyNameConstant(fieldNode); + String propConstantName = createPropConstantName(fieldNode.getName()); + if (propConstant && MemberExistsResult.NOT_EXISTS.equals(fieldExists(propConstantName, fieldNode))) { + JCVariableDecl propConstantDecl = createPropConstant(fieldNode.up(), sourceNode, fieldNode.getName()); + injectField(fieldNode.up(), propConstantDecl); + } + } + + private static JCVariableDecl createPropConstant(JavacNode typeNode, JavacNode source, String propertyName) { + String constantName = createPropConstantName(propertyName); + return createStringConstant(typeNode, source, constantName, propertyName); + } + + private static JCVariableDecl createStringConstant(JavacNode typeNode, JavacNode source, String constantName, String constantValue) { + JavacTreeMaker maker = typeNode.getTreeMaker(); + + JCExpression propConstantType = chainDotsString(typeNode, "java.lang.String"); + JCExpression initValue = maker.Literal(constantValue); + + JCVariableDecl fieldDecl = recursiveSetGeneratedBy(maker.VarDef(maker.Modifiers(Flags.PUBLIC | Flags.FINAL | Flags.STATIC), typeNode.toName(constantName), propConstantType, initValue), source.get(), typeNode.getContext()); + return fieldDecl; + } + + private static String createPropConstantName(String propertyName) { + return "PROP_" + Names.camelCaseToConstant(propertyName); + } } diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 0b4e839d98..cd4f466706 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -466,6 +466,30 @@ public static boolean shouldReturnThis(JavacNode field) { return HandlerUtil.shouldReturnThis0(accessors, field.getAst()); } + public static boolean shouldAddPropertyNameConstant(JavacNode field) { + if ((((JCVariableDecl) field.get()).mods.flags & Flags.STATIC) != 0) return false; + + AnnotationValues accessors = JavacHandlerUtil.getAccessorsForField(field); + + Accessors instance = accessors.getInstance(); + return instance.propertyNameConstant() || instance.bound(); + } + + public static boolean shouldAddBoundProperty(JavacNode field) { + if ((((JCVariableDecl) field.get()).mods.flags & Flags.STATIC) != 0) return false; + + AnnotationValues accessors = JavacHandlerUtil.getAccessorsForField(field); + + Accessors instance = accessors.getInstance(); + return instance.bound(); + } + + public static String propertyChangeSupportFieldName(JavacNode field) { + AnnotationValues accessors = JavacHandlerUtil.getAccessorsForField(field); + Accessors instance = accessors.getInstance(); + return instance.propertyChangeSupportFieldName(); + } + public static JCExpression cloneSelfType(JavacNode childOfType) { JavacNode typeNode = childOfType; JavacTreeMaker maker = childOfType.getTreeMaker(); diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index 77f615b551..135b5c7722 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -30,8 +30,6 @@ import java.util.Collections; import java.util.List; -import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup; - import lombok.core.AgentLauncher; import lombok.patcher.Filter; import lombok.patcher.Hook; diff --git a/test/transform/resource/after-delombok/SetterAccessorsPropertyNameConstantPlain.java b/test/transform/resource/after-delombok/SetterAccessorsPropertyNameConstantPlain.java new file mode 100644 index 0000000000..1edce11bac --- /dev/null +++ b/test/transform/resource/after-delombok/SetterAccessorsPropertyNameConstantPlain.java @@ -0,0 +1,19 @@ +class SetterAccessorsPropertyNameConstantPlain { + @java.lang.SuppressWarnings("all") + public static final java.lang.String PROP_FOO = "foo"; + @java.lang.SuppressWarnings("all") + public static final java.lang.String PROP_CAMEL_CASE = "camelCase"; + + int foo; + String camelCase; + + @java.lang.SuppressWarnings("all") + public void setFoo(final int foo) { + this.foo = foo; + } + + @java.lang.SuppressWarnings("all") + public void setCamelCase(final String camelCase) { + this.camelCase = camelCase; + } +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/SetterBoundPlain.java b/test/transform/resource/after-delombok/SetterBoundPlain.java new file mode 100644 index 0000000000..1784bd93c4 --- /dev/null +++ b/test/transform/resource/after-delombok/SetterBoundPlain.java @@ -0,0 +1,16 @@ +import java.beans.PropertyChangeSupport; + +class SetterBoundPlain { + @java.lang.SuppressWarnings("all") + public static final java.lang.String PROP_FOO = "foo"; + + private final PropertyChangeSupport propertySupport = new PropertyChangeSupport(this); + int foo; + + @java.lang.SuppressWarnings("all") + public void setFoo(final int foo) { + final int old = this.foo; + this.foo = foo; + this.propertySupport.firePropertyChange(PROP_FOO, old, this.foo); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/SetterAccessorsPropertyNameConstantPlain.java b/test/transform/resource/after-ecj/SetterAccessorsPropertyNameConstantPlain.java new file mode 100644 index 0000000000..5db1bff59e --- /dev/null +++ b/test/transform/resource/after-ecj/SetterAccessorsPropertyNameConstantPlain.java @@ -0,0 +1,19 @@ +import lombok.Setter; +import lombok.experimental.Accessors; +class SetterAccessorsPropertyNameConstantPlain { + public static final java.lang.String PROP_FOO = "foo"; + public static final java.lang.String PROP_CAMEL_CASE = "camelCase"; + @Setter @Accessors(propertyNameConstant = true) int foo; + @Setter @Accessors(propertyNameConstant = true) String camelCase; + () { + } + SetterAccessorsPropertyNameConstantPlain() { + super(); + } + public @java.lang.SuppressWarnings("all") void setFoo(final int foo) { + this.foo = foo; + } + public @java.lang.SuppressWarnings("all") void setCamelCase(final String camelCase) { + this.camelCase = camelCase; + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/SetterBoundPlain.java b/test/transform/resource/after-ecj/SetterBoundPlain.java new file mode 100644 index 0000000000..ad65b28a11 --- /dev/null +++ b/test/transform/resource/after-ecj/SetterBoundPlain.java @@ -0,0 +1,18 @@ +import java.beans.PropertyChangeSupport; +import lombok.Setter; +import lombok.experimental.Accessors; +class SetterBoundPlain { + public static final java.lang.String PROP_FOO = "foo"; + private final PropertyChangeSupport propertySupport = new PropertyChangeSupport(this); + @Setter @Accessors(bound = true) int foo; + () { + } + SetterBoundPlain() { + super(); + } + public @java.lang.SuppressWarnings("all") void setFoo(final int foo) { + final int old = this.foo; + this.foo = foo; + this.propertySupport.firePropertyChange(PROP_FOO, old, this.foo); + } +} \ No newline at end of file diff --git a/test/transform/resource/before/SetterAccessorsPropertyNameConstantPlain.java b/test/transform/resource/before/SetterAccessorsPropertyNameConstantPlain.java new file mode 100644 index 0000000000..731d8622cf --- /dev/null +++ b/test/transform/resource/before/SetterAccessorsPropertyNameConstantPlain.java @@ -0,0 +1,11 @@ +import lombok.Setter; +import lombok.experimental.Accessors; +class SetterAccessorsPropertyNameConstantPlain { + @Setter + @Accessors( propertyNameConstant=true ) + int foo; + + @Setter + @Accessors( propertyNameConstant=true ) + String camelCase; +} \ No newline at end of file diff --git a/test/transform/resource/before/SetterBoundPlain.java b/test/transform/resource/before/SetterBoundPlain.java new file mode 100644 index 0000000000..4e25b935c9 --- /dev/null +++ b/test/transform/resource/before/SetterBoundPlain.java @@ -0,0 +1,10 @@ +import java.beans.PropertyChangeSupport; +import lombok.Setter; +import lombok.experimental.Accessors; +class SetterBoundPlain { + private final PropertyChangeSupport propertySupport = new PropertyChangeSupport(this); + + @Setter + @Accessors( bound=true ) + int foo; +} \ No newline at end of file From 8b9c060b2f552548553495c1c8bb488b5c741c25 Mon Sep 17 00:00:00 2001 From: susu <360858329@qq.com> Date: Wed, 8 Feb 2017 21:25:55 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=9B=9E=E9=80=80=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 153a8fd841..f20973cf50 100644 --- a/build.xml +++ b/build.xml @@ -24,7 +24,7 @@ This buildfile is part of projectlombok.org. It is the main entry point that contains the common tasks and can be called on to run the main aspects of all the sub-scripts. - + From 377921220ec8b44b511b9d2fb50f3372baf22684 Mon Sep 17 00:00:00 2001 From: susu <360858329@qq.com> Date: Wed, 8 Feb 2017 21:33:30 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E5=9B=9E=E9=80=80=E4=B8=8D=E9=87=8D?= =?UTF-8?q?=E8=A6=81=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/lombok/experimental/Accessors.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/core/lombok/experimental/Accessors.java b/src/core/lombok/experimental/Accessors.java index e59c40878e..f84aac44c8 100644 --- a/src/core/lombok/experimental/Accessors.java +++ b/src/core/lombok/experimental/Accessors.java @@ -51,12 +51,10 @@ boolean chain() default false; /** - * If present, only fields with any of the stated prefixes are given the - * getter/setter treatment. Note that a prefix only counts if the next - * character is NOT a lowercase character or the last letter of the prefix - * is not a letter (for instance an underscore). If multiple fields all turn - * into the same name when the prefix is stripped, an error will be - * generated. + * If present, only fields with any of the stated prefixes are given the getter/setter treatment. + * Note that a prefix only counts if the next character is NOT a lowercase character or the last + * letter of the prefix is not a letter (for instance an underscore). If multiple fields + * all turn into the same name when the prefix is stripped, an error will be generated. */ String[] prefix() default {};