public boolean generateMethods( EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) { assert excludes == null || includes == null; 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 | ClassFileConstants.AccEnum)) != 0; if (typeDecl == null || notAClass) { errorNode.addError("@EqualsAndHashCode is only supported on a class."); return false; } boolean implicitCallSuper = callSuper == null; if (callSuper == null) { try { callSuper = ((Boolean) EqualsAndHashCode.class.getMethod("callSuper").getDefaultValue()) .booleanValue(); } catch (Exception ignore) { throw new InternalError( "Lombok bug - this cannot happen - can't find callSuper field in EqualsAndHashCode annotation."); } } boolean isDirectDescendantOfObject = true; if (typeDecl.superclass != null) { String p = typeDecl.superclass.toString(); isDirectDescendantOfObject = p.equals("Object") || p.equals("java.lang.Object"); } if (isDirectDescendantOfObject && callSuper) { errorNode.addError( "Generating equals/hashCode with a supercall to java.lang.Object is pointless."); return true; } if (!isDirectDescendantOfObject && !callSuper && implicitCallSuper) { errorNode.addWarning( "Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type."); } List<EclipseNode> nodesForEquality = new ArrayList<EclipseNode>(); if (includes != null) { for (EclipseNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; FieldDeclaration fieldDecl = (FieldDeclaration) child.get(); if (includes.contains(new String(fieldDecl.name))) nodesForEquality.add(child); } } else { for (EclipseNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; FieldDeclaration fieldDecl = (FieldDeclaration) child.get(); if (!EclipseHandlerUtil.filterField(fieldDecl)) continue; // Skip transient fields. if ((fieldDecl.modifiers & ClassFileConstants.AccTransient) != 0) continue; // Skip excluded fields. if (excludes != null && excludes.contains(new String(fieldDecl.name))) continue; nodesForEquality.add(child); } } boolean needsCanEqual = false; switch (methodExists("equals", typeNode)) { case NOT_EXISTS: boolean isFinal = (typeDecl.modifiers & ClassFileConstants.AccFinal) != 0; needsCanEqual = !isDirectDescendantOfObject || !isFinal; MethodDeclaration equals = createEquals( typeNode, nodesForEquality, callSuper, errorNode.get(), fieldAccess, needsCanEqual); injectMethod(typeNode, equals); break; case EXISTS_BY_LOMBOK: break; default: case EXISTS_BY_USER: if (whineIfExists) { errorNode.addWarning( "Not generating equals(Object other): A method with that name already exists"); } break; } if (needsCanEqual) { switch (methodExists("canEqual", typeNode)) { case NOT_EXISTS: MethodDeclaration equals = createCanEqual(typeNode, errorNode.get()); injectMethod(typeNode, equals); break; case EXISTS_BY_LOMBOK: case EXISTS_BY_USER: default: break; } } switch (methodExists("hashCode", typeNode)) { case NOT_EXISTS: MethodDeclaration hashCode = createHashCode(typeNode, nodesForEquality, callSuper, errorNode.get(), fieldAccess); injectMethod(typeNode, hashCode); break; case EXISTS_BY_LOMBOK: break; default: case EXISTS_BY_USER: if (whineIfExists) { errorNode.addWarning("Not generating hashCode(): A method with that name already exists"); } break; } return true; }
public boolean generateToString( EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes, boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) { 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("@ToString is only supported on a class or enum."); return false; } if (callSuper == null) { try { callSuper = ((Boolean) ToString.class.getMethod("callSuper").getDefaultValue()).booleanValue(); } catch (Exception ignore) { } } List<EclipseNode> nodesForToString = new ArrayList<EclipseNode>(); if (includes != null) { for (EclipseNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; FieldDeclaration fieldDecl = (FieldDeclaration) child.get(); if (includes.contains(new String(fieldDecl.name))) nodesForToString.add(child); } } else { for (EclipseNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; FieldDeclaration fieldDecl = (FieldDeclaration) child.get(); if (!EclipseHandlerUtil.filterField(fieldDecl)) continue; // Skip excluded fields. if (excludes != null && excludes.contains(new String(fieldDecl.name))) continue; nodesForToString.add(child); } } switch (methodExists("toString", typeNode)) { case NOT_EXISTS: MethodDeclaration toString = createToString( typeNode, nodesForToString, includeFieldNames, callSuper, errorNode.get(), fieldAccess); injectMethod(typeNode, toString); return true; case EXISTS_BY_LOMBOK: return true; default: case EXISTS_BY_USER: if (whineIfExists) { errorNode.addWarning("Not generating toString(): A method with that name already exists"); } return true; } }