diff options
Diffstat (limited to 'src/core/lombok/javac')
4 files changed, 53 insertions, 90 deletions
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index 7cf78392..fb3b45a4 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -54,11 +54,12 @@ import lombok.Builder; import lombok.Builder.ObtainVia; import lombok.ConfigurationKeys; import lombok.Singular; +import lombok.ToString; import lombok.core.AST.Kind; import lombok.core.AnnotationValues; import lombok.core.HandlerPriority; import lombok.core.handlers.HandlerUtil; -import lombok.core.handlers.InclusionExclusionUtils.ToStringMember; +import lombok.core.handlers.InclusionExclusionUtils.Included; import lombok.experimental.NonFinal; import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; @@ -399,10 +400,10 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { } if (methodExists("toString", builderType, 0) == MemberExistsResult.NOT_EXISTS) { - java.util.List<ToStringMember<JavacNode>> fieldNodes = new ArrayList<ToStringMember<JavacNode>>(); + java.util.List<Included<JavacNode, ToString.Include>> fieldNodes = new ArrayList<Included<JavacNode, ToString.Include>>(); for (BuilderFieldData bfd : builderFields) { for (JavacNode f : bfd.createdFields) { - fieldNodes.add(new ToStringMember<JavacNode>(f, null, true)); + fieldNodes.add(new Included<JavacNode, ToString.Include>(f, null, true)); } } diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index b3650ca6..12071cfd 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.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 @@ -35,6 +35,8 @@ 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; @@ -73,45 +75,23 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas private static final String RESULT_NAME = "result"; private static final String PRIME_NAME = "PRIME"; - public void checkForBogusFieldNames(JavacNode type, AnnotationValues<EqualsAndHashCode> annotation) { - if (annotation.isExplicit("exclude")) { - for (int i : createListOfNonExistentFields(List.from(annotation.getInstance().exclude()), type, true, true)) { - annotation.setWarning("exclude", "This field does not exist, or would have been excluded anyway.", i); - } - } - if (annotation.isExplicit("of")) { - for (int i : createListOfNonExistentFields(List.from(annotation.getInstance().of()), type, false, false)) { - annotation.setWarning("of", "This field does not exist.", i); - } - } - } - @Override public void handle(AnnotationValues<EqualsAndHashCode> annotation, JCAnnotation ast, JavacNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.EQUALS_AND_HASH_CODE_FLAG_USAGE, "@EqualsAndHashCode"); deleteAnnotationIfNeccessary(annotationNode, EqualsAndHashCode.class); EqualsAndHashCode ann = annotation.getInstance(); - List<String> excludes = List.from(ann.exclude()); - List<String> includes = List.from(ann.of()); + java.util.List<Included<JavacNode, EqualsAndHashCode.Include>> members = InclusionExclusionUtils.handleEqualsAndHashCodeMarking(annotationNode.up(), annotation, annotationNode); JavacNode typeNode = annotationNode.up(); List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@EqualsAndHashCode(onParam", annotationNode); - checkForBogusFieldNames(typeNode, annotation); Boolean callSuper = ann.callSuper(); if (!annotation.isExplicit("callSuper")) callSuper = null; - if (!annotation.isExplicit("exclude")) excludes = null; - if (!annotation.isExplicit("of")) includes = null; - - if (excludes != null && includes != null) { - excludes = null; - annotation.setWarning("exclude", "exclude and of are mutually exclusive; the 'exclude' parameter will be ignored."); - } Boolean doNotUseGettersConfiguration = annotationNode.getAst().readConfiguration(ConfigurationKeys.EQUALS_AND_HASH_CODE_DO_NOT_USE_GETTERS); boolean doNotUseGetters = annotation.isExplicit("doNotUseGetters") || doNotUseGettersConfiguration == null ? ann.doNotUseGetters() : doNotUseGettersConfiguration; FieldAccess fieldAccess = doNotUseGetters ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER; - generateMethods(typeNode, annotationNode, excludes, includes, callSuper, true, fieldAccess, onParam); + generateMethods(typeNode, annotationNode, members, callSuper, true, fieldAccess, onParam); } public void generateEqualsAndHashCodeForType(JavacNode typeNode, JavacNode source) { @@ -123,10 +103,12 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas Boolean doNotUseGettersConfiguration = typeNode.getAst().readConfiguration(ConfigurationKeys.EQUALS_AND_HASH_CODE_DO_NOT_USE_GETTERS); FieldAccess access = doNotUseGettersConfiguration == null || !doNotUseGettersConfiguration ? FieldAccess.GETTER : FieldAccess.PREFER_FIELD; - generateMethods(typeNode, source, null, null, null, false, access, List.<JCAnnotation>nil()); + java.util.List<Included<JavacNode, EqualsAndHashCode.Include>> members = InclusionExclusionUtils.handleEqualsAndHashCodeMarking(typeNode, null, null); + + generateMethods(typeNode, source, members, null, false, access, List.<JCAnnotation>nil()); } - public void generateMethods(JavacNode typeNode, JavacNode source, List<String> excludes, List<String> includes, + public void generateMethods(JavacNode typeNode, JavacNode source, java.util.List<Included<JavacNode, EqualsAndHashCode.Include>> members, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess, List<JCAnnotation> onParam) { boolean notAClass = true; @@ -180,29 +162,6 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas } } - ListBuffer<JavacNode> nodesForEquality = new ListBuffer<JavacNode>(); - if (includes != null) { - for (JavacNode child : typeNode.down()) { - if (child.getKind() != Kind.FIELD) continue; - JCVariableDecl fieldDecl = (JCVariableDecl) child.get(); - if (includes.contains(fieldDecl.name.toString())) nodesForEquality.append(child); - } - } else { - for (JavacNode child : typeNode.down()) { - if (child.getKind() != Kind.FIELD) continue; - JCVariableDecl fieldDecl = (JCVariableDecl) child.get(); - //Skip static fields. - if ((fieldDecl.mods.flags & Flags.STATIC) != 0) continue; - //Skip transient fields. - if ((fieldDecl.mods.flags & Flags.TRANSIENT) != 0) continue; - //Skip excluded fields. - if (excludes != null && excludes.contains(fieldDecl.name.toString())) continue; - //Skip fields that start with $ - if (fieldDecl.name.toString().startsWith("$")) continue; - nodesForEquality.append(child); - } - } - boolean isFinal = (((JCClassDecl) typeNode.get()).mods.flags & Flags.FINAL) != 0; boolean needsCanEqual = !isFinal || !isDirectDescendantOfObject; MemberExistsResult equalsExists = methodExists("equals", typeNode, 1); @@ -231,7 +190,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas //fallthrough } - JCMethodDecl equalsMethod = createEquals(typeNode, nodesForEquality.toList(), callSuper, fieldAccess, needsCanEqual, source.get(), onParam); + JCMethodDecl equalsMethod = createEquals(typeNode, members, callSuper, fieldAccess, needsCanEqual, source.get(), onParam); injectMethod(typeNode, equalsMethod); @@ -240,11 +199,11 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas injectMethod(typeNode, canEqualMethod); } - JCMethodDecl hashCodeMethod = createHashCode(typeNode, nodesForEquality.toList(), callSuper, fieldAccess, source.get()); + JCMethodDecl hashCodeMethod = createHashCode(typeNode, members, callSuper, fieldAccess, source.get()); injectMethod(typeNode, hashCodeMethod); } - public JCMethodDecl createHashCode(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, JCTree source) { + public JCMethodDecl createHashCode(JavacNode typeNode, java.util.List<Included<JavacNode, EqualsAndHashCode.Include>> members, boolean callSuper, FieldAccess fieldAccess, JCTree source) { JavacTreeMaker maker = typeNode.getTreeMaker(); JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil()); @@ -257,7 +216,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas long finalFlag = JavacHandlerUtil.addFinalIfNeeded(0L, typeNode.getContext()); /* final int PRIME = X; */ { - if (!fields.isEmpty()) { + if (!members.isEmpty()) { statements.append(maker.VarDef(maker.Modifiers(finalFlag), primeName, maker.TypeIdent(CTC_INT), maker.Literal(HandlerUtil.primeForHashcode()))); } } @@ -267,8 +226,8 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas if (callSuper) { /* ... super.hashCode(); */ init = maker.Apply(List.<JCExpression>nil(), - maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("hashCode")), - List.<JCExpression>nil()); + maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("hashCode")), + List.<JCExpression>nil()); } else { /* ... 1; */ init = maker.Literal(1); @@ -276,10 +235,12 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas statements.append(maker.VarDef(maker.Modifiers(0), resultName, maker.TypeIdent(CTC_INT), init)); } - Name dollar = typeNode.toName("$"); - for (JavacNode fieldNode : fields) { - JCExpression fType = getFieldType(fieldNode, fieldAccess); - JCExpression fieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess); + for (Included<JavacNode, EqualsAndHashCode.Include> member : members) { + JavacNode memberNode = member.getNode(); + JCExpression fType = getFieldType(memberNode, fieldAccess); + boolean isMethod = memberNode.getKind() == Kind.METHOD; + + JCExpression fieldAccessor = isMethod ? createMethodAccessor(maker, memberNode) : createFieldAccessor(maker, memberNode, fieldAccess); if (fType instanceof JCPrimitiveTypeTree) { switch (((JCPrimitiveTypeTree) fType).getPrimitiveTypeKind()) { case BOOLEAN: @@ -288,7 +249,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas maker.Literal(HandlerUtil.primeForTrue()), maker.Literal(HandlerUtil.primeForFalse()))))); break; case LONG: { - Name dollarFieldName = dollar.append(((JCVariableDecl) fieldNode.get()).name); + Name dollarFieldName = memberNode.toName((isMethod ? "$$" : "$") + memberNode.getName()); statements.append(maker.VarDef(maker.Modifiers(finalFlag), dollarFieldName, maker.TypeIdent(CTC_LONG), fieldAccessor)); statements.append(createResultCalculation(typeNode, longToIntForHashCode(maker, maker.Ident(dollarFieldName), maker.Ident(dollarFieldName)))); } @@ -302,7 +263,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas break; case DOUBLE: { /* longToIntForHashCode(Double.doubleToLongBits(this.fieldName)) */ - Name dollarFieldName = dollar.append(((JCVariableDecl) fieldNode.get()).name); + Name dollarFieldName = memberNode.toName((isMethod ? "$$" : "$") + memberNode.getName()); JCExpression init = maker.Apply( List.<JCExpression>nil(), genJavaLangTypeRef(typeNode, "Double", "doubleToLongBits"), @@ -332,7 +293,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas /* final java.lang.Object $fieldName = this.fieldName; */ /* ($fieldName == null ? NULL_PRIME : $fieldName.hashCode()) */ - Name dollarFieldName = dollar.append(((JCVariableDecl) fieldNode.get()).name); + Name dollarFieldName = memberNode.toName((isMethod ? "$$" : "$") + memberNode.getName()); statements.append(maker.VarDef(maker.Modifiers(finalFlag), dollarFieldName, genJavaLangTypeRef(typeNode, "Object"), fieldAccessor)); JCExpression hcCall = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(dollarFieldName), typeNode.toName("hashCode")), @@ -410,7 +371,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas return maker.TypeApply(expr, wildcards.toList()); } - public JCMethodDecl createEquals(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual, JCTree source, List<JCAnnotation> onParam) { + public JCMethodDecl createEquals(JavacNode typeNode, java.util.List<Included<JavacNode, EqualsAndHashCode.Include>> members, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual, JCTree source, List<JCAnnotation> onParam) { JavacTreeMaker maker = typeNode.getTreeMaker(); Name oName = typeNode.toName("o"); @@ -439,7 +400,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas } /* Outer.Inner.MyType<?> other = (Outer.Inner.MyType<?>) o; */ { - if (!fields.isEmpty() || needsCanEqual) { + if (!members.isEmpty() || needsCanEqual) { final JCExpression selfType1 = createTypeReference(typeNode, true), selfType2 = createTypeReference(typeNode, true); statements.append( @@ -468,12 +429,13 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas statements.append(maker.If(superNotEqual, returnBool(maker, false), null)); } - Name thisDollar = typeNode.toName("this$"); - Name otherDollar = typeNode.toName("other$"); - for (JavacNode fieldNode : fields) { - JCExpression fType = getFieldType(fieldNode, fieldAccess); - JCExpression thisFieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess); - JCExpression otherFieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess, maker.Ident(otherName)); + for (Included<JavacNode, EqualsAndHashCode.Include> member : members) { + JavacNode memberNode = member.getNode(); + boolean isMethod = memberNode.getKind() == Kind.METHOD; + + JCExpression fType = getFieldType(memberNode, fieldAccess); + JCExpression thisFieldAccessor = isMethod ? createMethodAccessor(maker, memberNode) : createFieldAccessor(maker, memberNode, fieldAccess); + JCExpression otherFieldAccessor = isMethod ? createMethodAccessor(maker, memberNode, maker.Ident(otherName)) : createFieldAccessor(maker, memberNode, fieldAccess, maker.Ident(otherName)); if (fType instanceof JCPrimitiveTypeTree) { switch (((JCPrimitiveTypeTree)fType).getPrimitiveTypeKind()) { case FLOAT: @@ -504,9 +466,8 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas /* final java.lang.Object this$fieldName = this.fieldName; */ /* final java.lang.Object other$fieldName = other.fieldName; */ /* if (this$fieldName == null ? other$fieldName != null : !this$fieldName.equals(other$fieldName)) return false; */ - Name fieldName = ((JCVariableDecl) fieldNode.get()).name; - Name thisDollarFieldName = thisDollar.append(fieldName); - Name otherDollarFieldName = otherDollar.append(fieldName); + Name thisDollarFieldName = memberNode.toName("this" + (isMethod ? "$$" : "$") + memberNode.getName()); + Name otherDollarFieldName = memberNode.toName("other" + (isMethod ? "$$" : "$") + memberNode.getName()); statements.append(maker.VarDef(maker.Modifiers(finalFlag), thisDollarFieldName, genJavaLangTypeRef(typeNode, "Object"), thisFieldAccessor)); statements.append(maker.VarDef(maker.Modifiers(finalFlag), otherDollarFieldName, genJavaLangTypeRef(typeNode, "Object"), otherFieldAccessor)); @@ -545,7 +506,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(flags, onParam), otherName, objectType, null)); JCBlock body = maker.Block(0, List.<JCStatement>of( - maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode, false))))); + maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode, false))))); return recursiveSetGeneratedBy(maker.MethodDef(mods, canEqualName, returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source, typeNode.getContext()); } diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java index 8c580207..28d18357 100644 --- a/src/core/lombok/javac/handlers/HandleToString.java +++ b/src/core/lombok/javac/handlers/HandleToString.java @@ -32,7 +32,7 @@ import lombok.ToString; import lombok.core.AnnotationValues; import lombok.core.AST.Kind; import lombok.core.handlers.InclusionExclusionUtils; -import lombok.core.handlers.InclusionExclusionUtils.ToStringMember; +import lombok.core.handlers.InclusionExclusionUtils.Included; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; import lombok.javac.JavacTreeMaker; @@ -66,7 +66,7 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { deleteAnnotationIfNeccessary(annotationNode, ToString.class); ToString ann = annotation.getInstance(); - java.util.List<ToStringMember<JavacNode>> members = InclusionExclusionUtils.handleToStringMarking(annotationNode.up(), annotation, annotationNode); + java.util.List<Included<JavacNode, ToString.Include>> members = InclusionExclusionUtils.handleToStringMarking(annotationNode.up(), annotation, annotationNode); if (members == null) return; Boolean callSuper = ann.callSuper(); @@ -98,11 +98,11 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { Boolean doNotUseGettersConfiguration = typeNode.getAst().readConfiguration(ConfigurationKeys.TO_STRING_DO_NOT_USE_GETTERS); FieldAccess access = doNotUseGettersConfiguration == null || !doNotUseGettersConfiguration ? FieldAccess.GETTER : FieldAccess.PREFER_FIELD; - java.util.List<ToStringMember<JavacNode>> members = InclusionExclusionUtils.handleToStringMarking(typeNode, null, null); + java.util.List<Included<JavacNode, ToString.Include>> members = InclusionExclusionUtils.handleToStringMarking(typeNode, null, null); generateToString(typeNode, errorNode, members, includeFieldNames, null, false, access); } - public void generateToString(JavacNode typeNode, JavacNode source, java.util.List<ToStringMember<JavacNode>> members, + public void generateToString(JavacNode typeNode, JavacNode source, java.util.List<Included<JavacNode, ToString.Include>> members, boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) { boolean notAClass = true; @@ -138,7 +138,7 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { } } - static JCMethodDecl createToString(JavacNode typeNode, Collection<ToStringMember<JavacNode>> members, + static JCMethodDecl createToString(JavacNode typeNode, Collection<Included<JavacNode, ToString.Include>> members, boolean includeNames, boolean callSuper, FieldAccess fieldAccess, JCTree source) { JavacTreeMaker maker = typeNode.getTreeMaker(); @@ -158,7 +158,7 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { } else if (members.isEmpty()) { prefix = typeName + "()"; } else if (includeNames) { - ToStringMember<JavacNode> firstMember = members.iterator().next(); + Included<JavacNode, ToString.Include> firstMember = members.iterator().next(); String name = firstMember.getInc() == null ? "" : firstMember.getInc().name(); if (name.isEmpty()) name = firstMember.getNode().getName(); prefix = typeName + "(" + name + "="; @@ -176,7 +176,7 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { first = false; } - for (ToStringMember<JavacNode> member : members) { + for (Included<JavacNode, ToString.Include> member : members) { JCExpression expr; JCExpression memberAccessor; diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 917e2e9c..b5bc6e6b 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -948,18 +948,19 @@ public class JavacHandlerUtil { } static JCExpression createMethodAccessor(JavacTreeMaker maker, JavacNode method) { - JCExpression receiver; + return createMethodAccessor(maker, method, null); + } + + static JCExpression createMethodAccessor(JavacTreeMaker maker, JavacNode method, JCExpression receiver) { JCMethodDecl methodDecl = (JCMethodDecl) method.get(); - if ((methodDecl.mods.flags & Flags.STATIC) == 0) { + if (receiver == null && (methodDecl.mods.flags & Flags.STATIC) == 0) { receiver = maker.Ident(method.toName("this")); - } else { + } else if (receiver == null) { JavacNode containerNode = method.up(); if (containerNode != null && containerNode.get() instanceof JCClassDecl) { JCClassDecl container = (JCClassDecl) method.up().get(); receiver = maker.Ident(container.name); - } else { - receiver = null; } } |