diff options
Diffstat (limited to 'src/core/lombok/javac/handlers')
7 files changed, 81 insertions, 88 deletions
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index 86ac00e6..7cf78392 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -58,6 +58,7 @@ 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.experimental.NonFinal; import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; @@ -398,10 +399,13 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { } if (methodExists("toString", builderType, 0) == MemberExistsResult.NOT_EXISTS) { - java.util.List<JavacNode> fieldNodes = new ArrayList<JavacNode>(); + java.util.List<ToStringMember<JavacNode>> fieldNodes = new ArrayList<ToStringMember<JavacNode>>(); for (BuilderFieldData bfd : builderFields) { - fieldNodes.addAll(bfd.createdFields); + for (JavacNode f : bfd.createdFields) { + fieldNodes.add(new ToStringMember<JavacNode>(f, null, true)); + } } + JCMethodDecl md = HandleToString.createToString(builderType, fieldNodes, true, false, FieldAccess.ALWAYS_FIELD, ast); if (md != null) injectMethod(builderType, md); } diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index d8bfd154..b3650ca6 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -39,7 +39,6 @@ import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; import lombok.javac.JavacTreeMaker; -import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult; import org.mangosdk.spi.ProviderFor; diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index 7e6598a7..4fc6155c 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -41,7 +41,6 @@ import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; import lombok.javac.JavacTreeMaker; import lombok.javac.JavacTreeMaker.TypeTag; -import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; import org.mangosdk.spi.ProviderFor; diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index 331b2fac..4e3c9576 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -36,7 +36,6 @@ 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; diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java index 897d5f2c..8c580207 100644 --- a/src/core/lombok/javac/handlers/HandleToString.java +++ b/src/core/lombok/javac/handlers/HandleToString.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 @@ -31,6 +31,8 @@ import lombok.ConfigurationKeys; 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.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; import lombok.javac.JavacTreeMaker; @@ -52,57 +54,33 @@ import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.List; -import com.sun.tools.javac.util.ListBuffer; /** * Handles the {@code ToString} annotation for javac. */ @ProviderFor(JavacAnnotationHandler.class) public class HandleToString extends JavacAnnotationHandler<ToString> { - public void checkForBogusFieldNames(JavacNode type, AnnotationValues<ToString> annotation) { - if (annotation.isExplicit("exclude")) { - for (int i : createListOfNonExistentFields(List.from(annotation.getInstance().exclude()), type, true, false)) { - 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<ToString> annotation, JCAnnotation ast, JavacNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.TO_STRING_FLAG_USAGE, "@ToString"); deleteAnnotationIfNeccessary(annotationNode, ToString.class); ToString ann = annotation.getInstance(); - List<String> excludes = List.from(ann.exclude()); - List<String> includes = List.from(ann.of()); - JavacNode typeNode = annotationNode.up(); - - checkForBogusFieldNames(typeNode, annotation); + java.util.List<ToStringMember<JavacNode>> members = InclusionExclusionUtils.handleToStringMarking(annotationNode.up(), annotation, annotationNode); + if (members == null) return; 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.TO_STRING_DO_NOT_USE_GETTERS); boolean doNotUseGetters = annotation.isExplicit("doNotUseGetters") || doNotUseGettersConfiguration == null ? ann.doNotUseGetters() : doNotUseGettersConfiguration; FieldAccess fieldAccess = doNotUseGetters ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER; Boolean fieldNamesConfiguration = annotationNode.getAst().readConfiguration(ConfigurationKeys.TO_STRING_INCLUDE_FIELD_NAMES); - boolean includeFieldNames = annotation.isExplicit("includeFieldNames") || fieldNamesConfiguration == null ? ann.includeFieldNames() : fieldNamesConfiguration; + boolean includeNames = annotation.isExplicit("includeFieldNames") || fieldNamesConfiguration == null ? ann.includeFieldNames() : fieldNamesConfiguration; - generateToString(typeNode, annotationNode, excludes, includes, includeFieldNames, callSuper, true, fieldAccess); + generateToString(annotationNode.up(), annotationNode, members, includeNames, callSuper, true, fieldAccess); } public void generateToStringForType(JavacNode typeNode, JavacNode errorNode) { @@ -111,7 +89,6 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { return; } - boolean includeFieldNames = true; try { Boolean configuration = typeNode.getAst().readConfiguration(ConfigurationKeys.TO_STRING_INCLUDE_FIELD_NAMES); @@ -121,20 +98,22 @@ 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; - generateToString(typeNode, errorNode, null, null, includeFieldNames, null, false, access); + java.util.List<ToStringMember<JavacNode>> members = InclusionExclusionUtils.handleToStringMarking(typeNode, null, null); + generateToString(typeNode, errorNode, members, includeFieldNames, null, false, access); } - public void generateToString(JavacNode typeNode, JavacNode source, List<String> excludes, List<String> includes, - boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) { + public void generateToString(JavacNode typeNode, JavacNode source, java.util.List<ToStringMember<JavacNode>> members, + boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) { + boolean notAClass = true; if (typeNode.get() instanceof JCClassDecl) { - long flags = ((JCClassDecl)typeNode.get()).mods.flags; + long flags = ((JCClassDecl) typeNode.get()).mods.flags; notAClass = (flags & (Flags.INTERFACE | Flags.ANNOTATION)) != 0; } if (callSuper == null) { try { - callSuper = ((Boolean)ToString.class.getMethod("callSuper").getDefaultValue()).booleanValue(); + callSuper = ((Boolean) ToString.class.getMethod("callSuper").getDefaultValue()).booleanValue(); } catch (Exception ignore) {} } @@ -143,30 +122,9 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { return; } - ListBuffer<JavacNode> nodesForToString = 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())) nodesForToString.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 excluded fields. - if (excludes != null && excludes.contains(fieldDecl.name.toString())) continue; - //Skip fields that start with $. - if (fieldDecl.name.toString().startsWith("$")) continue; - nodesForToString.append(child); - } - } - switch (methodExists("toString", typeNode, 0)) { case NOT_EXISTS: - JCMethodDecl method = createToString(typeNode, nodesForToString.toList(), includeFieldNames, callSuper, fieldAccess, source.get()); + JCMethodDecl method = createToString(typeNode, members, includeFieldNames, callSuper, fieldAccess, source.get()); injectMethod(typeNode, method); break; case EXISTS_BY_LOMBOK: @@ -180,7 +138,9 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { } } - static JCMethodDecl createToString(JavacNode typeNode, Collection<JavacNode> fields, boolean includeFieldNames, boolean callSuper, FieldAccess fieldAccess, JCTree source) { + static JCMethodDecl createToString(JavacNode typeNode, Collection<ToStringMember<JavacNode>> members, + boolean includeNames, boolean callSuper, FieldAccess fieldAccess, JCTree source) { + JavacTreeMaker maker = typeNode.getTreeMaker(); JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil()); @@ -195,10 +155,13 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { String prefix; if (callSuper) { prefix = typeName + "(super="; - } else if (fields.isEmpty()) { + } else if (members.isEmpty()) { prefix = typeName + "()"; - } else if (includeFieldNames) { - prefix = typeName + "(" + ((JCVariableDecl)fields.iterator().next().get()).name.toString() + "="; + } else if (includeNames) { + ToStringMember<JavacNode> firstMember = members.iterator().next(); + String name = firstMember.getInc() == null ? "" : firstMember.getInc().name(); + if (name.isEmpty()) name = firstMember.getNode().getName(); + prefix = typeName + "(" + name + "="; } else { prefix = typeName + "("; } @@ -207,30 +170,35 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { if (callSuper) { JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(), - maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("toString")), - List.<JCExpression>nil()); + maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("toString")), + List.<JCExpression>nil()); current = maker.Binary(CTC_PLUS, current, callToSuper); first = false; } - for (JavacNode fieldNode : fields) { + for (ToStringMember<JavacNode> member : members) { JCExpression expr; - JCExpression fieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess); + JCExpression memberAccessor; + JavacNode memberNode = member.getNode(); + if (memberNode.getKind() == Kind.METHOD) { + memberAccessor = createMethodAccessor(maker, memberNode); + } else { + memberAccessor = createFieldAccessor(maker, memberNode, fieldAccess); + } - JCExpression fieldType = getFieldType(fieldNode, fieldAccess); + JCExpression memberType = getFieldType(memberNode, fieldAccess); // The distinction between primitive and object will be useful if we ever add a 'hideNulls' option. - boolean fieldIsPrimitive = fieldType instanceof JCPrimitiveTypeTree; - boolean fieldIsPrimitiveArray = fieldType instanceof JCArrayTypeTree && ((JCArrayTypeTree) fieldType).elemtype instanceof JCPrimitiveTypeTree; - boolean fieldIsObjectArray = !fieldIsPrimitiveArray && fieldType instanceof JCArrayTypeTree; @SuppressWarnings("unused") - boolean fieldIsObject = !fieldIsPrimitive && !fieldIsPrimitiveArray && !fieldIsObjectArray; + boolean fieldIsPrimitive = memberType instanceof JCPrimitiveTypeTree; + boolean fieldIsPrimitiveArray = memberType instanceof JCArrayTypeTree && ((JCArrayTypeTree) memberType).elemtype instanceof JCPrimitiveTypeTree; + boolean fieldIsObjectArray = !fieldIsPrimitiveArray && memberType instanceof JCArrayTypeTree; if (fieldIsPrimitiveArray || fieldIsObjectArray) { JCExpression tsMethod = chainDots(typeNode, "java", "util", "Arrays", fieldIsObjectArray ? "deepToString" : "toString"); - expr = maker.Apply(List.<JCExpression>nil(), tsMethod, List.<JCExpression>of(fieldAccessor)); - } else expr = fieldAccessor; + expr = maker.Apply(List.<JCExpression>nil(), tsMethod, List.<JCExpression>of(memberAccessor)); + } else expr = memberAccessor; if (first) { current = maker.Binary(CTC_PLUS, current, expr); @@ -238,8 +206,10 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { continue; } - if (includeFieldNames) { - current = maker.Binary(CTC_PLUS, current, maker.Literal(infix + fieldNode.getName() + "=")); + if (includeNames) { + String n = member.getInc() == null ? "" : member.getInc().name(); + if (n.isEmpty()) n = memberNode.getName(); + current = maker.Binary(CTC_PLUS, current, maker.Literal(infix + n + "=")); } else { current = maker.Binary(CTC_PLUS, current, maker.Literal(infix)); } @@ -254,7 +224,7 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { JCBlock body = maker.Block(0, List.of(returnStatement)); return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("toString"), returnType, - List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null), source, typeNode.getContext()); + List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null), source, typeNode.getContext()); } public static String getTypeName(JavacNode typeNode) { diff --git a/src/core/lombok/javac/handlers/HandleWither.java b/src/core/lombok/javac/handlers/HandleWither.java index 987a3d34..87f3c16a 100644 --- a/src/core/lombok/javac/handlers/HandleWither.java +++ b/src/core/lombok/javac/handlers/HandleWither.java @@ -36,7 +36,6 @@ 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 org.mangosdk.spi.ProviderFor; diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 4b5c48dd..917e2e9c 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -216,7 +216,11 @@ public class JavacHandlerUtil { } } - static JavacNode findAnnotation(Class<? extends Annotation> type, JavacNode node, boolean delete) { + public static JavacNode findAnnotation(Class<? extends Annotation> type, JavacNode node) { + return findAnnotation(type, node, false); + } + + public static JavacNode findAnnotation(Class<? extends Annotation> type, JavacNode node, boolean delete) { if (node == null) return null; if (type == null) return null; switch (node.getKind()) { @@ -874,10 +878,6 @@ public class JavacHandlerUtil { return null; } - public enum FieldAccess { - GETTER, PREFER_FIELD, ALWAYS_FIELD; - } - static boolean lookForGetter(JavacNode field, FieldAccess fieldAccess) { if (fieldAccess == FieldAccess.GETTER) return true; if (fieldAccess == FieldAccess.ALWAYS_FIELD) return false; @@ -899,12 +899,14 @@ public class JavacHandlerUtil { * @see #createFieldAccessor(TreeMaker, JavacNode, FieldAccess) */ static JCExpression getFieldType(JavacNode field, FieldAccess fieldAccess) { + if (field.getKind() == Kind.METHOD) return ((JCMethodDecl) field.get()).restype; + boolean lookForGetter = lookForGetter(field, fieldAccess); GetterMethod getter = lookForGetter ? findGetter(field) : null; if (getter == null) { - return ((JCVariableDecl)field.get()).vartype; + return ((JCVariableDecl) field.get()).vartype; } return getter.type; @@ -941,7 +943,28 @@ public class JavacHandlerUtil { if (receiver == null) receiver = maker.Ident(field.toName("this")); JCMethodInvocation call = maker.Apply(List.<JCExpression>nil(), - maker.Select(receiver, getter.name), List.<JCExpression>nil()); + maker.Select(receiver, getter.name), List.<JCExpression>nil()); + return call; + } + + static JCExpression createMethodAccessor(JavacTreeMaker maker, JavacNode method) { + JCExpression receiver; + JCMethodDecl methodDecl = (JCMethodDecl) method.get(); + + if ((methodDecl.mods.flags & Flags.STATIC) == 0) { + receiver = maker.Ident(method.toName("this")); + } else { + 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; + } + } + + JCMethodInvocation call = maker.Apply(List.<JCExpression>nil(), + receiver == null ? maker.Ident(methodDecl.name) : maker.Select(receiver, methodDecl.name), List.<JCExpression>nil()); return call; } |