diff options
author | Reinier Zwitserloot <reinier@tipit.to> | 2009-11-25 07:32:49 +0100 |
---|---|---|
committer | Reinier Zwitserloot <reinier@tipit.to> | 2009-11-25 07:32:49 +0100 |
commit | 1a0e611a9c5e1ee518670647ce1a44beae559b44 (patch) | |
tree | e5ef8f671bc6688f486e874d4e2e1a7813e4f0b2 /src/lombok/eclipse/handlers | |
parent | 7fd947ea40c25dad9ee543ebc4b92de9a2e05efc (diff) | |
download | lombok-1a0e611a9c5e1ee518670647ce1a44beae559b44.tar.gz lombok-1a0e611a9c5e1ee518670647ce1a44beae559b44.tar.bz2 lombok-1a0e611a9c5e1ee518670647ce1a44beae559b44.zip |
Refactored the source folders.
Diffstat (limited to 'src/lombok/eclipse/handlers')
-rw-r--r-- | src/lombok/eclipse/handlers/EclipseHandlerUtil.java | 385 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/HandleCleanup.java | 200 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/HandleData.java | 243 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java | 718 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/HandleGetter.java | 154 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/HandlePrintAST.java | 57 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/HandleSetter.java | 172 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/HandleSneakyThrows.java | 224 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/HandleSynchronized.java | 132 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/HandleToString.java | 304 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/package-info.java | 26 |
11 files changed, 0 insertions, 2615 deletions
diff --git a/src/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/lombok/eclipse/handlers/EclipseHandlerUtil.java deleted file mode 100644 index 2f676d09..00000000 --- a/src/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * 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 static lombok.eclipse.Eclipse.fromQualifiedName; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; - -import lombok.AccessLevel; -import lombok.core.TransformationsUtil; -import lombok.core.AST.Kind; -import lombok.eclipse.Eclipse; -import lombok.eclipse.EclipseNode; - -import org.eclipse.jdt.internal.compiler.ast.ASTNode; -import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; -import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; -import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; -import org.eclipse.jdt.internal.compiler.ast.Annotation; -import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; -import org.eclipse.jdt.internal.compiler.ast.EqualExpression; -import org.eclipse.jdt.internal.compiler.ast.Expression; -import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; -import org.eclipse.jdt.internal.compiler.ast.IfStatement; -import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation; -import org.eclipse.jdt.internal.compiler.ast.NullLiteral; -import org.eclipse.jdt.internal.compiler.ast.OperatorIds; -import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; -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.ThrowStatement; -import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; -import org.eclipse.jdt.internal.compiler.ast.TypeReference; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; - -/** - * Container for static utility methods useful to handlers written for eclipse. - */ -public class EclipseHandlerUtil { - private EclipseHandlerUtil() { - //Prevent instantiation - } - - /** - * Checks if the given type reference represents a primitive type. - */ - public static boolean isPrimitive(TypeReference ref) { - if (ref.dimensions() > 0) return false; - return TransformationsUtil.PRIMITIVE_TYPE_NAME_PATTERN.matcher(Eclipse.toQualifiedName(ref.getTypeName())).matches(); - } - - /** - * Turns an {@code AccessLevel} instance into the flag bit used by eclipse. - */ - public static int toEclipseModifier(AccessLevel value) { - switch (value) { - case MODULE: - case PACKAGE: - return 0; - default: - case PUBLIC: - return ClassFileConstants.AccPublic; - case PROTECTED: - return ClassFileConstants.AccProtected; - case PRIVATE: - return ClassFileConstants.AccPrivate; - } - } - - /** - * Checks if an eclipse-style array-of-array-of-characters to represent a fully qualified name ('foo.bar.baz'), matches a plain - * string containing the same fully qualified name with dots in the string. - */ - public static boolean nameEquals(char[][] typeName, String string) { - StringBuilder sb = new StringBuilder(); - boolean first = true; - for (char[] elem : typeName) { - if (first) first = false; - else sb.append('.'); - sb.append(elem); - } - - return string.contentEquals(sb); - } - - /** Serves as return value for the methods that check for the existence of fields and methods. */ - public enum MemberExistsResult { - NOT_EXISTS, EXISTS_BY_USER, EXISTS_BY_LOMBOK; - } - - /** - * Checks if there is a field with the provided name. - * - * @param fieldName the field name to check for. - * @param node Any node that represents the Type (TypeDeclaration) to look in, or any child node thereof. - */ - public static MemberExistsResult fieldExists(String fieldName, EclipseNode node) { - while (node != null && !(node.get() instanceof TypeDeclaration)) { - node = node.up(); - } - - if (node != null && node.get() instanceof TypeDeclaration) { - TypeDeclaration typeDecl = (TypeDeclaration)node.get(); - if (typeDecl.fields != null) for (FieldDeclaration def : typeDecl.fields) { - char[] fName = def.name; - if (fName == null) continue; - if (fieldName.equals(new String(fName))) { - EclipseNode existing = node.getNodeFor(def); - if (existing == null || !existing.isHandled()) return MemberExistsResult.EXISTS_BY_USER; - return MemberExistsResult.EXISTS_BY_LOMBOK; - } - } - } - - return MemberExistsResult.NOT_EXISTS; - } - - /** - * Checks if there is a method with the provided name. In case of multiple methods (overloading), only - * the first method decides if EXISTS_BY_USER or EXISTS_BY_LOMBOK is returned. - * - * @param methodName the method name to check for. - * @param node Any node that represents the Type (TypeDeclaration) to look in, or any child node thereof. - */ - public static MemberExistsResult methodExists(String methodName, EclipseNode node) { - while (node != null && !(node.get() instanceof TypeDeclaration)) { - node = node.up(); - } - - if (node != null && node.get() instanceof TypeDeclaration) { - TypeDeclaration typeDecl = (TypeDeclaration)node.get(); - if (typeDecl.methods != null) for (AbstractMethodDeclaration def : typeDecl.methods) { - char[] mName = def.selector; - if (mName == null) continue; - if (methodName.equals(new String(mName))) { - EclipseNode existing = node.getNodeFor(def); - if (existing == null || !existing.isHandled()) return MemberExistsResult.EXISTS_BY_USER; - return MemberExistsResult.EXISTS_BY_LOMBOK; - } - } - } - - return MemberExistsResult.NOT_EXISTS; - } - - /** - * Checks if there is a (non-default) constructor. In case of multiple constructors (overloading), only - * the first constructor decides if EXISTS_BY_USER or EXISTS_BY_LOMBOK is returned. - * - * @param node Any node that represents the Type (TypeDeclaration) to look in, or any child node thereof. - */ - public static MemberExistsResult constructorExists(EclipseNode node) { - while (node != null && !(node.get() instanceof TypeDeclaration)) { - node = node.up(); - } - - 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 ((def.bits & ASTNode.IsDefaultConstructor) != 0) continue; - EclipseNode existing = node.getNodeFor(def); - if (existing == null || !existing.isHandled()) return MemberExistsResult.EXISTS_BY_USER; - return MemberExistsResult.EXISTS_BY_LOMBOK; - } - } - } - - return MemberExistsResult.NOT_EXISTS; - } - - /** - * Returns the constructor that's already been generated by lombok. - * Provide any node that represents the type (TypeDeclaration) to look in, or any child node thereof. - */ - public static EclipseNode getExistingLombokConstructor(EclipseNode node) { - while (node != null && !(node.get() instanceof TypeDeclaration)) { - node = node.up(); - } - - if (node == null) return null; - - if (node.get() instanceof TypeDeclaration) { - for (AbstractMethodDeclaration def : ((TypeDeclaration)node.get()).methods) { - if (def instanceof ConstructorDeclaration) { - if ((def.bits & ASTNode.IsDefaultConstructor) != 0) continue; - EclipseNode existing = node.getNodeFor(def); - if (existing.isHandled()) return existing; - } - } - } - - return null; - } - - /** - * Returns the method that's already been generated by lombok with the given name. - * Provide any node that represents the type (TypeDeclaration) to look in, or any child node thereof. - */ - public static EclipseNode getExistingLombokMethod(String methodName, EclipseNode node) { - while (node != null && !(node.get() instanceof TypeDeclaration)) { - node = node.up(); - } - - if (node == null) return null; - - if (node.get() instanceof TypeDeclaration) { - for (AbstractMethodDeclaration def : ((TypeDeclaration)node.get()).methods) { - char[] mName = def.selector; - if (mName == null) continue; - if (methodName.equals(new String(mName))) { - EclipseNode existing = node.getNodeFor(def); - if (existing.isHandled()) return existing; - } - } - } - - return null; - } - - /** - * Inserts a field into an existing type. The type must represent a {@code TypeDeclaration}. - */ - public static void injectField(EclipseNode type, FieldDeclaration field) { - TypeDeclaration parent = (TypeDeclaration) type.get(); - - if (parent.fields == null) { - parent.fields = new FieldDeclaration[1]; - parent.fields[0] = field; - } else { - FieldDeclaration[] newArray = new FieldDeclaration[parent.fields.length + 1]; - System.arraycopy(parent.fields, 0, newArray, 0, parent.fields.length); - newArray[parent.fields.length] = field; - parent.fields = newArray; - } - - type.add(field, Kind.FIELD).recursiveSetHandled(); - } - - /** - * Inserts a method into an existing type. The type must represent a {@code TypeDeclaration}. - */ - public static void injectMethod(EclipseNode type, AbstractMethodDeclaration method) { - TypeDeclaration parent = (TypeDeclaration) type.get(); - - if (parent.methods == null) { - parent.methods = new AbstractMethodDeclaration[1]; - parent.methods[0] = method; - } else { - boolean injectionComplete = false; - if (method instanceof ConstructorDeclaration) { - for (int i = 0 ; i < parent.methods.length ; i++) { - if (parent.methods[i] instanceof ConstructorDeclaration && - (parent.methods[i].bits & ASTNode.IsDefaultConstructor) != 0) { - EclipseNode tossMe = type.getNodeFor(parent.methods[i]); - parent.methods[i] = method; - if (tossMe != null) tossMe.up().removeChild(tossMe); - injectionComplete = true; - break; - } - } - } - if (!injectionComplete) { - AbstractMethodDeclaration[] newArray = new AbstractMethodDeclaration[parent.methods.length + 1]; - System.arraycopy(parent.methods, 0, newArray, 0, parent.methods.length); - newArray[parent.methods.length] = method; - parent.methods = newArray; - } - } - - type.add(method, Kind.METHOD).recursiveSetHandled(); - } - - /** - * Searches the given field node for annotations and returns each one that matches the provided regular expression pattern. - * - * Only the simple name is checked - the package and any containing class are ignored. - */ - public static Annotation[] findAnnotations(FieldDeclaration field, Pattern namePattern) { - List<Annotation> result = new ArrayList<Annotation>(); - if (field.annotations == null) return new Annotation[0]; - for (Annotation annotation : field.annotations) { - TypeReference typeRef = annotation.type; - if (typeRef != null && typeRef.getTypeName()!= null) { - char[][] typeName = typeRef.getTypeName(); - String suspect = new String(typeName[typeName.length - 1]); - if (namePattern.matcher(suspect).matches()) { - result.add(annotation); - } - } - } - return result.toArray(new Annotation[0]); - } - - /** - * Generates a new statement that checks if the given variable is null, and if so, throws a {@code NullPointerException} with the - * variable name as message. - */ - public static Statement generateNullCheck(AbstractVariableDeclaration variable, ASTNode source) { - int pS = source.sourceStart, pE = source.sourceEnd; - long p = (long)pS << 32 | pE; - - if (isPrimitive(variable.type)) return null; - AllocationExpression exception = new AllocationExpression(); - Eclipse.setGeneratedBy(exception, source); - exception.type = new QualifiedTypeReference(fromQualifiedName("java.lang.NullPointerException"), new long[]{p, p, p}); - Eclipse.setGeneratedBy(exception.type, source); - exception.arguments = new Expression[] { new StringLiteral(variable.name, pS, pE, 0)}; - Eclipse.setGeneratedBy(exception.arguments[0], source); - ThrowStatement throwStatement = new ThrowStatement(exception, pS, pE); - Eclipse.setGeneratedBy(throwStatement, source); - - SingleNameReference varName = new SingleNameReference(variable.name, p); - Eclipse.setGeneratedBy(varName, source); - NullLiteral nullLiteral = new NullLiteral(pS, pE); - Eclipse.setGeneratedBy(nullLiteral, source); - EqualExpression equalExpression = new EqualExpression(varName, nullLiteral, OperatorIds.EQUAL_EQUAL); - equalExpression.sourceStart = pS; equalExpression.sourceEnd = pE; - Eclipse.setGeneratedBy(equalExpression, source); - IfStatement ifStatement = new IfStatement(equalExpression, throwStatement, 0, 0); - Eclipse.setGeneratedBy(ifStatement, source); - return ifStatement; - } - - /** - * Create an annotation of the given name, and is marked as being generated by the given source. - */ - public static MarkerAnnotation makeMarkerAnnotation(char[][] name, ASTNode source) { - long pos = (long)source.sourceStart << 32 | source.sourceEnd; - TypeReference typeRef = new QualifiedTypeReference(name, new long[] {pos, pos, pos}); - Eclipse.setGeneratedBy(typeRef, source); - MarkerAnnotation ann = new MarkerAnnotation(typeRef, (int)(pos >> 32)); - ann.declarationSourceEnd = ann.sourceEnd = ann.statementEnd = (int)pos; - Eclipse.setGeneratedBy(ann, source); - return ann; - } - - /** - * Given a list of field names and a node referring to a type, finds each name in the list that does not match a field within the type. - */ - public static List<Integer> createListOfNonExistentFields(List<String> list, EclipseNode type, boolean excludeStandard, boolean excludeTransient) { - boolean[] matched = new boolean[list.size()]; - - for (EclipseNode child : type.down()) { - if (list.isEmpty()) break; - if (child.getKind() != Kind.FIELD) continue; - if (excludeStandard) { - if ((((FieldDeclaration)child.get()).modifiers & ClassFileConstants.AccStatic) != 0) continue; - if (child.getName().startsWith("$")) continue; - } - if (excludeTransient && (((FieldDeclaration)child.get()).modifiers & ClassFileConstants.AccTransient) != 0) continue; - int idx = list.indexOf(child.getName()); - if (idx > -1) matched[idx] = true; - } - - List<Integer> problematic = new ArrayList<Integer>(); - for (int i = 0 ; i < list.size() ; i++) { - if (!matched[i]) problematic.add(i); - } - - return problematic; - } -} diff --git a/src/lombok/eclipse/handlers/HandleCleanup.java b/src/lombok/eclipse/handlers/HandleCleanup.java deleted file mode 100644 index d296e96b..00000000 --- a/src/lombok/eclipse/handlers/HandleCleanup.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * 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 java.util.Arrays; - -import lombok.Cleanup; -import lombok.core.AnnotationValues; -import lombok.core.AST.Kind; -import lombok.eclipse.Eclipse; -import lombok.eclipse.EclipseAnnotationHandler; -import lombok.eclipse.EclipseNode; - -import org.eclipse.jdt.internal.compiler.ast.ASTNode; -import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; -import org.eclipse.jdt.internal.compiler.ast.Annotation; -import org.eclipse.jdt.internal.compiler.ast.Assignment; -import org.eclipse.jdt.internal.compiler.ast.Block; -import org.eclipse.jdt.internal.compiler.ast.CaseStatement; -import org.eclipse.jdt.internal.compiler.ast.CastExpression; -import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; -import org.eclipse.jdt.internal.compiler.ast.MemberValuePair; -import org.eclipse.jdt.internal.compiler.ast.MessageSend; -import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; -import org.eclipse.jdt.internal.compiler.ast.Statement; -import org.eclipse.jdt.internal.compiler.ast.SwitchStatement; -import org.eclipse.jdt.internal.compiler.ast.TryStatement; -import org.mangosdk.spi.ProviderFor; - -/** - * Handles the {@code lombok.Cleanup} annotation for eclipse. - */ -@ProviderFor(EclipseAnnotationHandler.class) -public class HandleCleanup implements EclipseAnnotationHandler<Cleanup> { - public boolean handle(AnnotationValues<Cleanup> annotation, Annotation ast, EclipseNode annotationNode) { - String cleanupName = annotation.getInstance().value(); - if (cleanupName.length() == 0) { - annotationNode.addError("cleanupName cannot be the empty string."); - return true; - } - - if (annotationNode.up().getKind() != Kind.LOCAL) { - annotationNode.addError("@Cleanup is legal only on local variable declarations."); - return true; - } - - LocalDeclaration decl = (LocalDeclaration)annotationNode.up().get(); - - if (decl.initialization == null) { - annotationNode.addError("@Cleanup variable declarations need to be initialized."); - return true; - } - - EclipseNode ancestor = annotationNode.up().directUp(); - ASTNode blockNode = ancestor.get(); - - final boolean isSwitch; - final Statement[] statements; - if (blockNode instanceof AbstractMethodDeclaration) { - isSwitch = false; - statements = ((AbstractMethodDeclaration)blockNode).statements; - } else if (blockNode instanceof Block) { - isSwitch = false; - statements = ((Block)blockNode).statements; - } else if (blockNode instanceof SwitchStatement) { - isSwitch = true; - statements = ((SwitchStatement)blockNode).statements; - } else { - annotationNode.addError("@Cleanup is legal only on a local variable declaration inside a block."); - return true; - } - - if (statements == null) { - annotationNode.addError("LOMBOK BUG: Parent block does not contain any statements."); - return true; - } - - int start = 0; - for (; start < statements.length ; start++) { - if (statements[start] == decl) break; - } - - if (start == statements.length) { - annotationNode.addError("LOMBOK BUG: Can't find this local variable declaration inside its parent."); - return true; - } - - start++; //We start with try{} *AFTER* the var declaration. - - int end; - if (isSwitch) { - end = start + 1; - for (; end < statements.length ; end++) { - if (statements[end] instanceof CaseStatement) { - break; - } - } - } else end = statements.length; - - //At this point: - // start-1 = Local Declaration marked with @Cleanup - // start = first instruction that needs to be wrapped into a try block - // end = last intruction of the scope -OR- last instruction before the next case label in switch statements. - // hence: - // [start, end) = statements for the try block. - - Statement[] tryBlock = new Statement[end - start]; - System.arraycopy(statements, start, tryBlock, 0, end-start); - //Remove the stuff we just dumped into the tryBlock, and then leave room for the try node. - int newStatementsLength = statements.length - (end-start); //Remove room for every statement moved into try block... - newStatementsLength += 1; //But add room for the TryStatement node itself. - Statement[] newStatements = new Statement[newStatementsLength]; - System.arraycopy(statements, 0, newStatements, 0, start); //copy all statements before the try block verbatim. - System.arraycopy(statements, end, newStatements, start+1, statements.length - end); //For switch statements. - - doAssignmentCheck(annotationNode, tryBlock, decl.name); - - TryStatement tryStatement = new TryStatement(); - Eclipse.setGeneratedBy(tryStatement, ast); - tryStatement.tryBlock = new Block(0); - tryStatement.tryBlock.statements = tryBlock; - newStatements[start] = tryStatement; - - Statement[] finallyBlock = new Statement[1]; - MessageSend unsafeClose = new MessageSend(); - Eclipse.setGeneratedBy(unsafeClose, ast); - unsafeClose.sourceStart = ast.sourceStart; - unsafeClose.sourceEnd = ast.sourceEnd; - SingleNameReference receiver = new SingleNameReference(decl.name, 0); - Eclipse.setGeneratedBy(receiver, ast); - unsafeClose.receiver = receiver; - long nameSourcePosition = (long)ast.sourceStart << 32 | ast.sourceEnd; - if (ast.memberValuePairs() != null) for (MemberValuePair pair : ast.memberValuePairs()) { - if (pair.name != null && new String(pair.name).equals("value")) { - nameSourcePosition = (long)pair.value.sourceStart << 32 | pair.value.sourceEnd; - break; - } - } - unsafeClose.nameSourcePosition = nameSourcePosition; - unsafeClose.selector = cleanupName.toCharArray(); - finallyBlock[0] = unsafeClose; - tryStatement.finallyBlock = new Block(0); - Eclipse.setGeneratedBy(tryStatement.finallyBlock, ast); - tryStatement.finallyBlock.statements = finallyBlock; - - tryStatement.catchArguments = null; - tryStatement.catchBlocks = null; - - if (blockNode instanceof AbstractMethodDeclaration) { - ((AbstractMethodDeclaration)blockNode).statements = newStatements; - } else if (blockNode instanceof Block) { - ((Block)blockNode).statements = newStatements; - } else if (blockNode instanceof SwitchStatement) { - ((SwitchStatement)blockNode).statements = newStatements; - } - - ancestor.rebuild(); - - return true; - } - - private void doAssignmentCheck(EclipseNode node, Statement[] tryBlock, char[] varName) { - for (Statement statement : tryBlock) doAssignmentCheck0(node, statement, varName); - } - - private void doAssignmentCheck0(EclipseNode node, Statement statement, char[] varName) { - if (statement instanceof Assignment) - doAssignmentCheck0(node, ((Assignment)statement).expression, varName); - else if (statement instanceof LocalDeclaration) - doAssignmentCheck0(node, ((LocalDeclaration)statement).initialization, varName); - else if (statement instanceof CastExpression) - doAssignmentCheck0(node, ((CastExpression)statement).expression, varName); - else if (statement instanceof SingleNameReference) { - if (Arrays.equals(((SingleNameReference)statement).token, varName)) { - EclipseNode problemNode = node.getNodeFor(statement); - if (problemNode != null) problemNode.addWarning( - "You're assigning an auto-cleanup variable to something else. This is a bad idea."); - } - } - } -} diff --git a/src/lombok/eclipse/handlers/HandleData.java b/src/lombok/eclipse/handlers/HandleData.java deleted file mode 100644 index 8c4e07ce..00000000 --- a/src/lombok/eclipse/handlers/HandleData.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * 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 static lombok.eclipse.Eclipse.*; -import static lombok.eclipse.handlers.EclipseHandlerUtil.*; - -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import lombok.AccessLevel; -import lombok.Data; -import lombok.core.AnnotationValues; -import lombok.core.TransformationsUtil; -import lombok.core.AST.Kind; -import lombok.eclipse.Eclipse; -import lombok.eclipse.EclipseAnnotationHandler; -import lombok.eclipse.EclipseNode; -import lombok.eclipse.handlers.EclipseHandlerUtil.MemberExistsResult; - -import org.eclipse.jdt.internal.compiler.ast.ASTNode; -import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; -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.CompilationUnitDeclaration; -import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; -import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall; -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.MethodDeclaration; -import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference; -import org.eclipse.jdt.internal.compiler.ast.ReturnStatement; -import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; -import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; -import org.eclipse.jdt.internal.compiler.ast.Statement; -import org.eclipse.jdt.internal.compiler.ast.ThisReference; -import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; -import org.eclipse.jdt.internal.compiler.ast.TypeParameter; -import org.eclipse.jdt.internal.compiler.ast.TypeReference; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.mangosdk.spi.ProviderFor; - -/** - * Handles the {@code lombok.Data} annotation for eclipse. - */ -@ProviderFor(EclipseAnnotationHandler.class) -public class HandleData implements EclipseAnnotationHandler<Data> { - public boolean handle(AnnotationValues<Data> annotation, Annotation ast, EclipseNode annotationNode) { - Data ann = annotation.getInstance(); - EclipseNode typeNode = annotationNode.up(); - - 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) { - annotationNode.addError("@Data is only supported on a class."); - return false; - } - - List<EclipseNode> nodesForConstructor = new ArrayList<EclipseNode>(); - for (EclipseNode child : typeNode.down()) { - if (child.getKind() != Kind.FIELD) continue; - FieldDeclaration fieldDecl = (FieldDeclaration) child.get(); - //Skip fields that start with $ - if (fieldDecl.name.length > 0 && fieldDecl.name[0] == '$') continue; - //Skip static fields. - if ((fieldDecl.modifiers & ClassFileConstants.AccStatic) != 0) continue; - boolean isFinal = (fieldDecl.modifiers & ClassFileConstants.AccFinal) != 0; - boolean isNonNull = findAnnotations(fieldDecl, TransformationsUtil.NON_NULL_PATTERN).length != 0; - if ((isFinal || isNonNull) && fieldDecl.initialization == null) nodesForConstructor.add(child); - new HandleGetter().generateGetterForField(child, annotationNode.get()); - if (!isFinal) new HandleSetter().generateSetterForField(child, annotationNode.get()); - } - - new HandleToString().generateToStringForType(typeNode, annotationNode); - new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode); - - //Careful: Generate the public static constructor (if there is one) LAST, so that any attempt to - //'find callers' on the annotation node will find callers of the constructor, which is by far the - //most useful of the many methods built by @Data. This trick won't work for the non-static constructor, - //for whatever reason, though you can find callers of that one by focusing on the class name itself - //and hitting 'find callers'. - - if (constructorExists(typeNode) == MemberExistsResult.NOT_EXISTS) { - ConstructorDeclaration constructor = createConstructor( - ann.staticConstructor().length() == 0, typeNode, nodesForConstructor, ast); - injectMethod(typeNode, constructor); - } - - if (ann.staticConstructor().length() > 0) { - if (methodExists("of", typeNode) == MemberExistsResult.NOT_EXISTS) { - MethodDeclaration staticConstructor = createStaticConstructor( - ann.staticConstructor(), typeNode, nodesForConstructor, ast); - injectMethod(typeNode, staticConstructor); - } - } - - return false; - } - - private ConstructorDeclaration createConstructor(boolean isPublic, - EclipseNode type, Collection<EclipseNode> fields, ASTNode source) { - long p = (long)source.sourceStart << 32 | source.sourceEnd; - - ConstructorDeclaration constructor = new ConstructorDeclaration( - ((CompilationUnitDeclaration) type.top().get()).compilationResult); - Eclipse.setGeneratedBy(constructor, source); - - constructor.modifiers = EclipseHandlerUtil.toEclipseModifier(isPublic ? AccessLevel.PUBLIC : AccessLevel.PRIVATE); - constructor.annotations = null; - constructor.selector = ((TypeDeclaration)type.get()).name; - constructor.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper); - Eclipse.setGeneratedBy(constructor.constructorCall, source); - constructor.thrownExceptions = null; - constructor.typeParameters = null; - constructor.bits |= Eclipse.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> args = new ArrayList<Argument>(); - List<Statement> assigns = new ArrayList<Statement>(); - List<Statement> nullChecks = new ArrayList<Statement>(); - - for (EclipseNode fieldNode : fields) { - FieldDeclaration field = (FieldDeclaration) fieldNode.get(); - FieldReference thisX = new FieldReference(("this." + new String(field.name)).toCharArray(), p); - Eclipse.setGeneratedBy(thisX, source); - thisX.receiver = new ThisReference((int)(p >> 32), (int)p); - Eclipse.setGeneratedBy(thisX.receiver, source); - thisX.token = field.name; - - SingleNameReference assignmentNameRef = new SingleNameReference(field.name, p); - Eclipse.setGeneratedBy(assignmentNameRef, source); - Assignment assignment = new Assignment(thisX, assignmentNameRef, (int)p); - Eclipse.setGeneratedBy(assignment, source); - assigns.add(assignment); - long fieldPos = (((long)field.sourceStart) << 32) | field.sourceEnd; - Argument argument = new Argument(field.name, fieldPos, copyType(field.type, source), Modifier.FINAL); - Eclipse.setGeneratedBy(argument, source); - Annotation[] nonNulls = findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN); - Annotation[] nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN); - if (nonNulls.length != 0) { - Statement nullCheck = generateNullCheck(field, source); - if (nullCheck != null) nullChecks.add(nullCheck); - } - Annotation[] copiedAnnotations = copyAnnotations(nonNulls, nullables, source); - if (copiedAnnotations.length != 0) argument.annotations = copiedAnnotations; - args.add(argument); - } - - nullChecks.addAll(assigns); - constructor.statements = nullChecks.isEmpty() ? null : nullChecks.toArray(new Statement[nullChecks.size()]); - constructor.arguments = args.isEmpty() ? null : args.toArray(new Argument[args.size()]); - return constructor; - } - - private MethodDeclaration createStaticConstructor(String name, EclipseNode type, Collection<EclipseNode> fields, ASTNode source) { - int pS = source.sourceStart, pE = source.sourceEnd; - long p = (long)pS << 32 | pE; - - MethodDeclaration constructor = new MethodDeclaration( - ((CompilationUnitDeclaration) type.top().get()).compilationResult); - Eclipse.setGeneratedBy(constructor, source); - - constructor.modifiers = EclipseHandlerUtil.toEclipseModifier(AccessLevel.PUBLIC) | Modifier.STATIC; - TypeDeclaration typeDecl = (TypeDeclaration) type.get(); - if (typeDecl.typeParameters != null && typeDecl.typeParameters.length > 0) { - TypeReference[] refs = new TypeReference[typeDecl.typeParameters.length]; - int idx = 0; - for (TypeParameter param : typeDecl.typeParameters) { - TypeReference typeRef = new SingleTypeReference(param.name, (long)param.sourceStart << 32 | param.sourceEnd); - Eclipse.setGeneratedBy(typeRef, source); - refs[idx++] = typeRef; - } - constructor.returnType = new ParameterizedSingleTypeReference(typeDecl.name, refs, 0, p); - } else constructor.returnType = new SingleTypeReference(((TypeDeclaration)type.get()).name, p); - Eclipse.setGeneratedBy(constructor.returnType, source); - constructor.annotations = null; - constructor.selector = name.toCharArray(); - constructor.thrownExceptions = null; - constructor.typeParameters = copyTypeParams(((TypeDeclaration)type.get()).typeParameters, source); - constructor.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; - constructor.bodyStart = constructor.declarationSourceStart = constructor.sourceStart = source.sourceStart; - constructor.bodyEnd = constructor.declarationSourceEnd = constructor.sourceEnd = source.sourceEnd; - - List<Argument> args = new ArrayList<Argument>(); - List<Expression> assigns = new ArrayList<Expression>(); - AllocationExpression statement = new AllocationExpression(); - statement.sourceStart = pS; statement.sourceEnd = pE; - Eclipse.setGeneratedBy(statement, source); - statement.type = copyType(constructor.returnType, source); - - for (EclipseNode fieldNode : fields) { - FieldDeclaration field = (FieldDeclaration) fieldNode.get(); - long fieldPos = (((long)field.sourceStart) << 32) | field.sourceEnd; - SingleNameReference nameRef = new SingleNameReference(field.name, fieldPos); - Eclipse.setGeneratedBy(nameRef, source); - assigns.add(nameRef); - - Argument argument = new Argument(field.name, fieldPos, copyType(field.type, source), 0); - Eclipse.setGeneratedBy(argument, source); - - Annotation[] copiedAnnotations = copyAnnotations( - findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN), - findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN), source); - if (copiedAnnotations.length != 0) argument.annotations = copiedAnnotations; - args.add(new Argument(field.name, fieldPos, copyType(field.type, source), Modifier.FINAL)); - } - - statement.arguments = assigns.isEmpty() ? null : assigns.toArray(new Expression[assigns.size()]); - constructor.arguments = args.isEmpty() ? null : args.toArray(new Argument[args.size()]); - constructor.statements = new Statement[] { new ReturnStatement(statement, (int)(p >> 32), (int)p) }; - Eclipse.setGeneratedBy(constructor.statements[0], source); - return constructor; - } -} diff --git a/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java deleted file mode 100644 index 7c0980c8..00000000 --- a/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java +++ /dev/null @@ -1,718 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * 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 static lombok.eclipse.handlers.EclipseHandlerUtil.*; - -import static lombok.eclipse.Eclipse.copyTypes; - -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -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.BinaryExpression; -import org.eclipse.jdt.internal.compiler.ast.CastExpression; -import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; -import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression; -import org.eclipse.jdt.internal.compiler.ast.EqualExpression; -import org.eclipse.jdt.internal.compiler.ast.Expression; -import org.eclipse.jdt.internal.compiler.ast.FalseLiteral; -import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; -import org.eclipse.jdt.internal.compiler.ast.FieldReference; -import org.eclipse.jdt.internal.compiler.ast.IfStatement; -import org.eclipse.jdt.internal.compiler.ast.IntLiteral; -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.NullLiteral; -import org.eclipse.jdt.internal.compiler.ast.OperatorIds; -import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference; -import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; -import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; -import org.eclipse.jdt.internal.compiler.ast.Reference; -import org.eclipse.jdt.internal.compiler.ast.ReturnStatement; -import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; -import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; -import org.eclipse.jdt.internal.compiler.ast.Statement; -import org.eclipse.jdt.internal.compiler.ast.SuperReference; -import org.eclipse.jdt.internal.compiler.ast.ThisReference; -import org.eclipse.jdt.internal.compiler.ast.TrueLiteral; -import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; -import org.eclipse.jdt.internal.compiler.ast.TypeReference; -import org.eclipse.jdt.internal.compiler.ast.UnaryExpression; -import org.eclipse.jdt.internal.compiler.ast.Wildcard; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; -import org.eclipse.jdt.internal.compiler.lookup.TypeIds; -import org.mangosdk.spi.ProviderFor; - -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.core.AnnotationValues; -import lombok.core.AST.Kind; -import lombok.eclipse.Eclipse; -import lombok.eclipse.EclipseAnnotationHandler; -import lombok.eclipse.EclipseNode; - -/** - * Handles the {@code EqualsAndHashCode} annotation for eclipse. - */ -@ProviderFor(EclipseAnnotationHandler.class) -public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsAndHashCode> { - private static final Set<String> BUILT_IN_TYPES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList( - "byte", "short", "int", "long", "char", "boolean", "double", "float"))); - - private void checkForBogusFieldNames(EclipseNode type, AnnotationValues<EqualsAndHashCode> annotation) { - if (annotation.isExplicit("exclude")) { - for (int i : createListOfNonExistentFields(Arrays.asList(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(Arrays.asList(annotation.getInstance().of()), type, false, false)) { - annotation.setWarning("of", "This field does not exist.", i); - } - } - } - - public void generateEqualsAndHashCodeForType(EclipseNode typeNode, EclipseNode errorNode) { - for (EclipseNode child : typeNode.down()) { - if (child.getKind() == Kind.ANNOTATION) { - if (Eclipse.annotationTypeMatches(EqualsAndHashCode.class, child)) { - //The annotation will make it happen, so we can skip it. - return; - } - } - } - - generateMethods(typeNode, errorNode, null, null, null, false); - } - - @Override public boolean handle(AnnotationValues<EqualsAndHashCode> annotation, - Annotation ast, EclipseNode annotationNode) { - EqualsAndHashCode ann = annotation.getInstance(); - List<String> excludes = Arrays.asList(ann.exclude()); - List<String> includes = Arrays.asList(ann.of()); - EclipseNode typeNode = annotationNode.up(); - - 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."); - } - - return generateMethods(typeNode, annotationNode, excludes, includes, callSuper, true); - } - - public boolean generateMethods(EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes, - Boolean callSuper, boolean whineIfExists) { - 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(); - //Skip static fields. - if ((fieldDecl.modifiers & ClassFileConstants.AccStatic) != 0) continue; - //Skip transient fields. - if ((fieldDecl.modifiers & ClassFileConstants.AccTransient) != 0) continue; - //Skip excluded fields. - if (excludes != null && excludes.contains(new String(fieldDecl.name))) continue; - //Skip fields that start with $. - if (fieldDecl.name.length > 0 && fieldDecl.name[0] == '$') continue; - nodesForEquality.add(child); - } - } - - switch (methodExists("hashCode", typeNode)) { - case NOT_EXISTS: - MethodDeclaration hashCode = createHashCode(typeNode, nodesForEquality, callSuper, errorNode.get()); - 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; - } - - switch (methodExists("equals", typeNode)) { - case NOT_EXISTS: - MethodDeclaration equals = createEquals(typeNode, nodesForEquality, callSuper, errorNode.get()); - 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; - } - - return true; - } - - private MethodDeclaration createHashCode(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source) { - int pS = source.sourceStart, pE = source.sourceEnd; - long p = (long)pS << 32 | pE; - - MethodDeclaration method = new MethodDeclaration( - ((CompilationUnitDeclaration) type.top().get()).compilationResult); - Eclipse.setGeneratedBy(method, source); - - method.modifiers = EclipseHandlerUtil.toEclipseModifier(AccessLevel.PUBLIC); - method.returnType = TypeReference.baseTypeReference(TypeIds.T_int, 0); - Eclipse.setGeneratedBy(method.returnType, source); - method.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source)}; - method.selector = "hashCode".toCharArray(); - method.thrownExceptions = null; - method.typeParameters = null; - method.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; - method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart; - method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd; - method.arguments = null; - - List<Statement> statements = new ArrayList<Statement>(); - List<Expression> intoResult = new ArrayList<Expression>(); - - final char[] PRIME = "PRIME".toCharArray(); - final char[] RESULT = "result".toCharArray(); - final boolean isEmpty = fields.isEmpty(); - - /* final int PRIME = 31; */ { - /* Without fields, PRIME isn't used, and that would trigger a 'local variable not used' warning. */ - if (!isEmpty || callSuper) { - LocalDeclaration primeDecl = new LocalDeclaration(PRIME, pS, pE); - Eclipse.setGeneratedBy(primeDecl, source); - primeDecl.modifiers |= Modifier.FINAL; - primeDecl.type = TypeReference.baseTypeReference(TypeIds.T_int, 0); - primeDecl.type.sourceStart = pS; primeDecl.type.sourceEnd = pE; - Eclipse.setGeneratedBy(primeDecl.type, source); - primeDecl.initialization = new IntLiteral("31".toCharArray(), pS, pE); - Eclipse.setGeneratedBy(primeDecl.initialization, source); - statements.add(primeDecl); - } - } - - /* int result = 1; */ { - LocalDeclaration resultDecl = new LocalDeclaration(RESULT, pS, pE); - Eclipse.setGeneratedBy(resultDecl, source); - resultDecl.initialization = new IntLiteral("1".toCharArray(), pS, pE); - Eclipse.setGeneratedBy(resultDecl.initialization, source); - resultDecl.type = TypeReference.baseTypeReference(TypeIds.T_int, 0); - resultDecl.type.sourceStart = pS; resultDecl.type.sourceEnd = pE; - Eclipse.setGeneratedBy(resultDecl.type, source); - statements.add(resultDecl); - } - - if (callSuper) { - MessageSend callToSuper = new MessageSend(); - Eclipse.setGeneratedBy(callToSuper, source); - callToSuper.sourceStart = pS; callToSuper.sourceEnd = pE; - callToSuper.receiver = new SuperReference(pS, pE); - Eclipse.setGeneratedBy(callToSuper.receiver, source); - callToSuper.selector = "hashCode".toCharArray(); - intoResult.add(callToSuper); - } - - int tempCounter = 0; - for (EclipseNode field : fields) { - FieldDeclaration f = (FieldDeclaration) field.get(); - char[] token = f.type.getLastToken(); - if (f.type.dimensions() == 0 && token != null) { - if (Arrays.equals(TypeConstants.FLOAT, token)) { - /* Float.floatToIntBits(fieldName) */ - MessageSend floatToIntBits = new MessageSend(); - floatToIntBits.sourceStart = pS; floatToIntBits.sourceEnd = pE; - Eclipse.setGeneratedBy(floatToIntBits, source); - floatToIntBits.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_FLOAT); - floatToIntBits.selector = "floatToIntBits".toCharArray(); - floatToIntBits.arguments = new Expression[] { generateFieldReference(f.name, source) }; - intoResult.add(floatToIntBits); - } else if (Arrays.equals(TypeConstants.DOUBLE, token)) { - /* longToIntForHashCode(Double.doubleToLongBits(fieldName)) */ - MessageSend doubleToLongBits = new MessageSend(); - doubleToLongBits.sourceStart = pS; doubleToLongBits.sourceEnd = pE; - Eclipse.setGeneratedBy(doubleToLongBits, source); - doubleToLongBits.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_DOUBLE); - doubleToLongBits.selector = "doubleToLongBits".toCharArray(); - doubleToLongBits.arguments = new Expression[] { generateFieldReference(f.name, source) }; - final char[] tempName = ("temp" + ++tempCounter).toCharArray(); - LocalDeclaration tempVar = new LocalDeclaration(tempName, pS, pE); - Eclipse.setGeneratedBy(tempVar, source); - tempVar.initialization = doubleToLongBits; - tempVar.type = TypeReference.baseTypeReference(TypeIds.T_long, 0); - tempVar.type.sourceStart = pS; tempVar.type.sourceEnd = pE; - Eclipse.setGeneratedBy(tempVar.type, source); - tempVar.modifiers = Modifier.FINAL; - statements.add(tempVar); - SingleNameReference copy1 = new SingleNameReference(tempName, p); - Eclipse.setGeneratedBy(copy1, source); - SingleNameReference copy2 = new SingleNameReference(tempName, p); - Eclipse.setGeneratedBy(copy2, source); - intoResult.add(longToIntForHashCode(copy1, copy2, source)); - } else if (Arrays.equals(TypeConstants.BOOLEAN, token)) { - /* booleanField ? 1231 : 1237 */ - IntLiteral int1231 = new IntLiteral("1231".toCharArray(), pS, pE); - Eclipse.setGeneratedBy(int1231, source); - IntLiteral int1237 = new IntLiteral("1237".toCharArray(), pS, pE); - Eclipse.setGeneratedBy(int1237, source); - ConditionalExpression int1231or1237 = new ConditionalExpression( - generateFieldReference(f.name, source), int1231, int1237); - Eclipse.setGeneratedBy(int1231or1237, source); - intoResult.add(int1231or1237); - } else if (Arrays.equals(TypeConstants.LONG, token)) { - intoResult.add(longToIntForHashCode(generateFieldReference(f.name, source), generateFieldReference(f.name, source), source)); - } else if (BUILT_IN_TYPES.contains(new String(token))) { - intoResult.add(generateFieldReference(f.name, source)); - } else /* objects */ { - /* this.fieldName == null ? 0 : this.fieldName.hashCode() */ - MessageSend hashCodeCall = new MessageSend(); - hashCodeCall.sourceStart = pS; hashCodeCall.sourceEnd = pE; - Eclipse.setGeneratedBy(hashCodeCall, source); - hashCodeCall.receiver = generateFieldReference(f.name, source); - hashCodeCall.selector = "hashCode".toCharArray(); - NullLiteral nullLiteral = new NullLiteral(pS, pE); - Eclipse.setGeneratedBy(nullLiteral, source); - EqualExpression objIsNull = new EqualExpression( - generateFieldReference(f.name, source), nullLiteral, OperatorIds.EQUAL_EQUAL); - Eclipse.setGeneratedBy(objIsNull, source); - IntLiteral int0 = new IntLiteral("0".toCharArray(), pS, pE); - Eclipse.setGeneratedBy(int0, source); - ConditionalExpression nullOrHashCode = new ConditionalExpression(objIsNull, int0, hashCodeCall); - nullOrHashCode.sourceStart = pS; nullOrHashCode.sourceEnd = pE; - Eclipse.setGeneratedBy(nullOrHashCode, source); - intoResult.add(nullOrHashCode); - } - } else if (f.type.dimensions() > 0 && token != null) { - /* Arrays.deepHashCode(array) //just hashCode for simple arrays */ - MessageSend arraysHashCodeCall = new MessageSend(); - arraysHashCodeCall.sourceStart = pS; arraysHashCodeCall.sourceEnd = pE; - Eclipse.setGeneratedBy(arraysHashCodeCall, source); - arraysHashCodeCall.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.UTIL, "Arrays".toCharArray()); - if (f.type.dimensions() > 1 || !BUILT_IN_TYPES.contains(new String(token))) { - arraysHashCodeCall.selector = "deepHashCode".toCharArray(); - } else { - arraysHashCodeCall.selector = "hashCode".toCharArray(); - } - arraysHashCodeCall.arguments = new Expression[] { generateFieldReference(f.name, source) }; - intoResult.add(arraysHashCodeCall); - } - } - - /* fold each intoResult entry into: - result = result * PRIME + (item); */ { - for (Expression ex : intoResult) { - SingleNameReference resultRef = new SingleNameReference(RESULT, p); - Eclipse.setGeneratedBy(resultRef, source); - SingleNameReference primeRef = new SingleNameReference(PRIME, p); - Eclipse.setGeneratedBy(primeRef, source); - BinaryExpression multiplyByPrime = new BinaryExpression(resultRef, primeRef, OperatorIds.MULTIPLY); - multiplyByPrime.sourceStart = pS; multiplyByPrime.sourceEnd = pE; - Eclipse.setGeneratedBy(multiplyByPrime, source); - BinaryExpression addItem = new BinaryExpression(multiplyByPrime, ex, OperatorIds.PLUS); - addItem.sourceStart = pS; addItem.sourceEnd = pE; - Eclipse.setGeneratedBy(addItem, source); - resultRef = new SingleNameReference(RESULT, p); - Eclipse.setGeneratedBy(resultRef, source); - Assignment assignment = new Assignment(resultRef, addItem, pE); - assignment.sourceStart = pS; assignment.sourceEnd = pE; - Eclipse.setGeneratedBy(assignment, source); - statements.add(assignment); - } - } - - /* return result; */ { - SingleNameReference resultRef = new SingleNameReference(RESULT, p); - Eclipse.setGeneratedBy(resultRef, source); - ReturnStatement returnStatement = new ReturnStatement(resultRef, pS, pE); - Eclipse.setGeneratedBy(returnStatement, source); - statements.add(returnStatement); - } - method.statements = statements.toArray(new Statement[statements.size()]); - return method; - } - - private MethodDeclaration createEquals(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source) { - int pS = source.sourceStart; int pE = source.sourceEnd; - long p = (long)pS << 32 | pE; - - MethodDeclaration method = new MethodDeclaration( - ((CompilationUnitDeclaration) type.top().get()).compilationResult); - Eclipse.setGeneratedBy(method, source); - method.modifiers = EclipseHandlerUtil.toEclipseModifier(AccessLevel.PUBLIC); - method.returnType = TypeReference.baseTypeReference(TypeIds.T_boolean, 0); - method.returnType.sourceStart = pS; method.returnType.sourceEnd = pE; - Eclipse.setGeneratedBy(method.returnType, source); - method.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source)}; - method.selector = "equals".toCharArray(); - method.thrownExceptions = null; - method.typeParameters = null; - method.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; - method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart; - method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd; - TypeReference objectRef = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, new long[] { p, p, p }); - Eclipse.setGeneratedBy(objectRef, source); - method.arguments = new Argument[] {new Argument(new char[] { 'o' }, 0, objectRef, Modifier.FINAL)}; - method.arguments[0].sourceStart = pS; method.arguments[0].sourceEnd = pE; - Eclipse.setGeneratedBy(method.arguments[0], source); - - List<Statement> statements = new ArrayList<Statement>(); - - /* if (o == this) return true; */ { - SingleNameReference oRef = new SingleNameReference(new char[] { 'o' }, p); - Eclipse.setGeneratedBy(oRef, source); - ThisReference thisRef = new ThisReference(pS, pE); - Eclipse.setGeneratedBy(thisRef, source); - EqualExpression otherEqualsThis = new EqualExpression(oRef, thisRef, OperatorIds.EQUAL_EQUAL); - Eclipse.setGeneratedBy(otherEqualsThis, source); - - TrueLiteral trueLiteral = new TrueLiteral(pS, pE); - Eclipse.setGeneratedBy(trueLiteral, source); - ReturnStatement returnTrue = new ReturnStatement(trueLiteral, pS, pE); - Eclipse.setGeneratedBy(returnTrue, source); - IfStatement ifOtherEqualsThis = new IfStatement(otherEqualsThis, returnTrue, pS, pE); - Eclipse.setGeneratedBy(ifOtherEqualsThis, source); - statements.add(ifOtherEqualsThis); - } - - /* if (o == null) return false; */ { - SingleNameReference oRef = new SingleNameReference(new char[] { 'o' }, p); - Eclipse.setGeneratedBy(oRef, source); - NullLiteral nullLiteral = new NullLiteral(pS, pE); - Eclipse.setGeneratedBy(nullLiteral, source); - EqualExpression otherEqualsNull = new EqualExpression(oRef, nullLiteral, OperatorIds.EQUAL_EQUAL); - Eclipse.setGeneratedBy(otherEqualsNull, source); - - FalseLiteral falseLiteral = new FalseLiteral(pS, pE); - Eclipse.setGeneratedBy(falseLiteral, source); - ReturnStatement returnFalse = new ReturnStatement(falseLiteral, pS, pE); - Eclipse.setGeneratedBy(returnFalse, source); - IfStatement ifOtherEqualsNull = new IfStatement(otherEqualsNull, returnFalse, pS, pE); - Eclipse.setGeneratedBy(ifOtherEqualsNull, source); - statements.add(ifOtherEqualsNull); - } - - /* if (o.getClass() != getClass()) return false; */ { - MessageSend otherGetClass = new MessageSend(); - otherGetClass.sourceStart = pS; otherGetClass.sourceEnd = pE; - Eclipse.setGeneratedBy(otherGetClass, source); - otherGetClass.receiver = new SingleNameReference(new char[] { 'o' }, p); - Eclipse.setGeneratedBy(otherGetClass.receiver, source); - otherGetClass.selector = "getClass".toCharArray(); - MessageSend thisGetClass = new MessageSend(); - thisGetClass.sourceStart = pS; thisGetClass.sourceEnd = pE; - Eclipse.setGeneratedBy(thisGetClass, source); - thisGetClass.receiver = new ThisReference(pS, pE); - Eclipse.setGeneratedBy(thisGetClass.receiver, source); - thisGetClass.selector = "getClass".toCharArray(); - EqualExpression classesNotEqual = new EqualExpression(otherGetClass, thisGetClass, OperatorIds.NOT_EQUAL); - Eclipse.setGeneratedBy(classesNotEqual, source); - FalseLiteral falseLiteral = new FalseLiteral(pS, pE); - Eclipse.setGeneratedBy(falseLiteral, source); - ReturnStatement returnFalse = new ReturnStatement(falseLiteral, pS, pE); - Eclipse.setGeneratedBy(returnFalse, source); - IfStatement ifClassesNotEqual = new IfStatement(classesNotEqual, returnFalse, pS, pE); - Eclipse.setGeneratedBy(ifClassesNotEqual, source); - statements.add(ifClassesNotEqual); - } - - char[] otherN = "other".toCharArray(); - - /* if (!super.equals(o)) return false; */ - if (callSuper) { - MessageSend callToSuper = new MessageSend(); - callToSuper.sourceStart = pS; callToSuper.sourceEnd = pE; - Eclipse.setGeneratedBy(callToSuper, source); - callToSuper.receiver = new SuperReference(pS, pE); - Eclipse.setGeneratedBy(callToSuper.receiver, source); - callToSuper.selector = "equals".toCharArray(); - SingleNameReference oRef = new SingleNameReference(new char[] { 'o' }, p); - Eclipse.setGeneratedBy(oRef, source); - callToSuper.arguments = new Expression[] {oRef}; - Expression superNotEqual = new UnaryExpression(callToSuper, OperatorIds.NOT); - Eclipse.setGeneratedBy(superNotEqual, source); - FalseLiteral falseLiteral = new FalseLiteral(pS, pE); - Eclipse.setGeneratedBy(falseLiteral, source); - ReturnStatement returnFalse = new ReturnStatement(falseLiteral, pS, pE); - Eclipse.setGeneratedBy(returnFalse, source); - IfStatement ifSuperEquals = new IfStatement(superNotEqual, returnFalse, pS, pE); - Eclipse.setGeneratedBy(ifSuperEquals, source); - statements.add(ifSuperEquals); - } - - TypeDeclaration typeDecl = (TypeDeclaration)type.get(); - /* MyType<?> other = (MyType<?>) o; */ { - if (!fields.isEmpty()) { - LocalDeclaration other = new LocalDeclaration(otherN, pS, pE); - Eclipse.setGeneratedBy(other, source); - char[] typeName = typeDecl.name; - Expression targetType; - if (typeDecl.typeParameters == null || typeDecl.typeParameters.length == 0) { - targetType = new SingleNameReference(((TypeDeclaration)type.get()).name, p); - Eclipse.setGeneratedBy(targetType, source); - other.type = new SingleTypeReference(typeName, p); - Eclipse.setGeneratedBy(other.type, source); - } else { - TypeReference[] typeArgs = new TypeReference[typeDecl.typeParameters.length]; - for (int i = 0; i < typeArgs.length; i++) { - typeArgs[i] = new Wildcard(Wildcard.UNBOUND); - typeArgs[i].sourceStart = pS; typeArgs[i].sourceEnd = pE; - Eclipse.setGeneratedBy(typeArgs[i], source); - } - targetType = new ParameterizedSingleTypeReference(typeName, typeArgs, 0, p); - Eclipse.setGeneratedBy(targetType, source); - other.type = new ParameterizedSingleTypeReference(typeName, copyTypes(typeArgs, source), 0, p); - Eclipse.setGeneratedBy(other.type, source); - } - NameReference oRef = new SingleNameReference(new char[] { 'o' }, p); - Eclipse.setGeneratedBy(oRef, source); - other.initialization = new CastExpression(oRef, targetType); - Eclipse.setGeneratedBy(other.initialization, source); - statements.add(other); - } - } - - for (EclipseNode field : fields) { - FieldDeclaration f = (FieldDeclaration) field.get(); - char[] token = f.type.getLastToken(); - if (f.type.dimensions() == 0 && token != null) { - if (Arrays.equals(TypeConstants.FLOAT, token)) { - statements.add(generateCompareFloatOrDouble(otherN, "Float".toCharArray(), f.name, source)); - } else if (Arrays.equals(TypeConstants.DOUBLE, token)) { - statements.add(generateCompareFloatOrDouble(otherN, "Double".toCharArray(), f.name, source)); - } else if (BUILT_IN_TYPES.contains(new String(token))) { - NameReference fieldRef = new SingleNameReference(f.name, p); - Eclipse.setGeneratedBy(fieldRef, source); - EqualExpression fieldsNotEqual = new EqualExpression(fieldRef, - generateQualifiedNameRef(source, otherN, f.name), OperatorIds.NOT_EQUAL); - Eclipse.setGeneratedBy(fieldsNotEqual, source); - FalseLiteral falseLiteral = new FalseLiteral(pS, pE); - Eclipse.setGeneratedBy(falseLiteral, source); - ReturnStatement returnStatement = new ReturnStatement(falseLiteral, pS, pE); - Eclipse.setGeneratedBy(returnStatement, source); - IfStatement ifStatement = new IfStatement(fieldsNotEqual, returnStatement, pS, pE); - Eclipse.setGeneratedBy(ifStatement, source); - statements.add(ifStatement); - } else /* objects */ { - NameReference fieldNameRef = new SingleNameReference(f.name, p); - Eclipse.setGeneratedBy(fieldNameRef, source); - NullLiteral nullLiteral = new NullLiteral(pS, pE); - Eclipse.setGeneratedBy(nullLiteral, source); - EqualExpression fieldIsNull = new EqualExpression(fieldNameRef, nullLiteral, OperatorIds.EQUAL_EQUAL); - nullLiteral = new NullLiteral(pS, pE); - Eclipse.setGeneratedBy(nullLiteral, source); - EqualExpression otherFieldIsntNull = new EqualExpression( - generateQualifiedNameRef(source, otherN, f.name), - nullLiteral, OperatorIds.NOT_EQUAL); - MessageSend equalsCall = new MessageSend(); - equalsCall.sourceStart = pS; equalsCall.sourceEnd = pE; - Eclipse.setGeneratedBy(equalsCall, source); - equalsCall.receiver = new SingleNameReference(f.name, p); - Eclipse.setGeneratedBy(equalsCall.receiver, source); - equalsCall.selector = "equals".toCharArray(); - equalsCall.arguments = new Expression[] { generateQualifiedNameRef(source, otherN, f.name) }; - UnaryExpression fieldsNotEqual = new UnaryExpression(equalsCall, OperatorIds.NOT); - fieldsNotEqual.sourceStart = pS; fieldsNotEqual.sourceEnd = pE; - Eclipse.setGeneratedBy(fieldsNotEqual, source); - ConditionalExpression fullEquals = new ConditionalExpression(fieldIsNull, otherFieldIsntNull, fieldsNotEqual); - fullEquals.sourceStart = pS; fullEquals.sourceEnd = pE; - Eclipse.setGeneratedBy(fullEquals, source); - FalseLiteral falseLiteral = new FalseLiteral(pS, pE); - Eclipse.setGeneratedBy(falseLiteral, source); - ReturnStatement returnStatement = new ReturnStatement(falseLiteral, pS, pE); - Eclipse.setGeneratedBy(returnStatement, source); - IfStatement ifStatement = new IfStatement(fullEquals, returnStatement, pS, pE); - Eclipse.setGeneratedBy(ifStatement, source); - statements.add(ifStatement); - } - } else if (f.type.dimensions() > 0 && token != null) { - MessageSend arraysEqualCall = new MessageSend(); - arraysEqualCall.sourceStart = pS; arraysEqualCall.sourceEnd = pE; - Eclipse.setGeneratedBy(arraysEqualCall, source); - arraysEqualCall.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.UTIL, "Arrays".toCharArray()); - if (f.type.dimensions() > 1 || !BUILT_IN_TYPES.contains(new String(token))) { - arraysEqualCall.selector = "deepEquals".toCharArray(); - } else { - arraysEqualCall.selector = "equals".toCharArray(); - } - NameReference fieldNameRef = new SingleNameReference(f.name, p); - Eclipse.setGeneratedBy(fieldNameRef, source); - arraysEqualCall.arguments = new Expression[] { fieldNameRef, generateQualifiedNameRef(source, otherN, f.name) }; - UnaryExpression arraysNotEqual = new UnaryExpression(arraysEqualCall, OperatorIds.NOT); - arraysNotEqual.sourceStart = pS; arraysNotEqual.sourceEnd = pE; - Eclipse.setGeneratedBy(arraysNotEqual, source); - FalseLiteral falseLiteral = new FalseLiteral(pS, pE); - Eclipse.setGeneratedBy(falseLiteral, source); - ReturnStatement returnStatement = new ReturnStatement(falseLiteral, pS, pE); - Eclipse.setGeneratedBy(returnStatement, source); - IfStatement ifStatement = new IfStatement(arraysNotEqual, returnStatement, pS, pE); - Eclipse.setGeneratedBy(ifStatement, source); - statements.add(ifStatement); - } - } - - /* return true; */ { - TrueLiteral trueLiteral = new TrueLiteral(pS, pE); - Eclipse.setGeneratedBy(trueLiteral, source); - ReturnStatement returnStatement = new ReturnStatement(trueLiteral, pS, pE); - Eclipse.setGeneratedBy(returnStatement, source); - statements.add(returnStatement); - } - method.statements = statements.toArray(new Statement[statements.size()]); - return method; - } - - private IfStatement generateCompareFloatOrDouble(char[] otherN, char[] floatOrDouble, char[] fieldName, ASTNode source) { - int pS = source.sourceStart, pE = source.sourceEnd; - long p = (long)pS << 32 | pE; - /* if (Float.compare(fieldName, other.fieldName) != 0) return false */ - MessageSend floatCompare = new MessageSend(); - floatCompare.sourceStart = pS; floatCompare.sourceEnd = pE; - Eclipse.setGeneratedBy(floatCompare, source); - floatCompare.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.LANG, floatOrDouble); - floatCompare.selector = "compare".toCharArray(); - NameReference fieldNameRef = new SingleNameReference(fieldName, p); - Eclipse.setGeneratedBy(fieldNameRef, source); - floatCompare.arguments = new Expression[] {fieldNameRef, generateQualifiedNameRef(source, otherN, fieldName)}; - IntLiteral int0 = new IntLiteral(new char[] {'0'}, pS, pE); - Eclipse.setGeneratedBy(int0, source); - EqualExpression ifFloatCompareIsNot0 = new EqualExpression(floatCompare, int0, OperatorIds.NOT_EQUAL); - ifFloatCompareIsNot0.sourceStart = pS; ifFloatCompareIsNot0.sourceEnd = pE; - Eclipse.setGeneratedBy(ifFloatCompareIsNot0, source); - FalseLiteral falseLiteral = new FalseLiteral(pS, pE); - Eclipse.setGeneratedBy(falseLiteral, source); - ReturnStatement returnFalse = new ReturnStatement(falseLiteral, pS, pE); - Eclipse.setGeneratedBy(returnFalse, source); - IfStatement ifStatement = new IfStatement(ifFloatCompareIsNot0, returnFalse, pS, pE); - Eclipse.setGeneratedBy(ifStatement, source); - return ifStatement; - } - - /** Give 2 clones! */ - private Expression longToIntForHashCode(Reference ref1, Reference ref2, ASTNode source) { - int pS = source.sourceStart, pE = source.sourceEnd; - /* (int)(ref >>> 32 ^ ref) */ - IntLiteral int32 = new IntLiteral("32".toCharArray(), pS, pE); - Eclipse.setGeneratedBy(int32, source); - BinaryExpression higherBits = new BinaryExpression(ref1, int32, OperatorIds.UNSIGNED_RIGHT_SHIFT); - Eclipse.setGeneratedBy(higherBits, source); - BinaryExpression xorParts = new BinaryExpression(ref2, higherBits, OperatorIds.XOR); - Eclipse.setGeneratedBy(xorParts, source); - TypeReference intRef = TypeReference.baseTypeReference(TypeIds.T_int, 0); - intRef.sourceStart = pS; intRef.sourceEnd = pE; - Eclipse.setGeneratedBy(intRef, source); - CastExpression expr = new CastExpression(xorParts, intRef); - expr.sourceStart = pS; expr.sourceEnd = pE; - Eclipse.setGeneratedBy(expr, source); - return expr; - } - - private Reference generateFieldReference(char[] fieldName, ASTNode source) { - int pS = source.sourceStart, pE = source.sourceEnd; - long p = (long)pS << 32 | pE; - FieldReference thisX = new FieldReference(("this." + new String(fieldName)).toCharArray(), p); - Eclipse.setGeneratedBy(thisX, source); - thisX.receiver = new ThisReference(pS, pE); - Eclipse.setGeneratedBy(thisX.receiver, source); - thisX.token = fieldName; - return thisX; - } - - private NameReference generateQualifiedNameRef(ASTNode source, char[]... varNames) { - int pS = source.sourceStart, pE = source.sourceEnd; - long p = (long)pS << 32 | pE; - - NameReference ref; - - if (varNames.length > 1) ref = new QualifiedNameReference(varNames, new long[varNames.length], pS, pE); - else ref = new SingleNameReference(varNames[0], p); - Eclipse.setGeneratedBy(ref, source); - return ref; - } -} diff --git a/src/lombok/eclipse/handlers/HandleGetter.java b/src/lombok/eclipse/handlers/HandleGetter.java deleted file mode 100644 index 4a9930e3..00000000 --- a/src/lombok/eclipse/handlers/HandleGetter.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * 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 static lombok.eclipse.Eclipse.*; -import static lombok.eclipse.handlers.EclipseHandlerUtil.*; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.core.AnnotationValues; -import lombok.core.TransformationsUtil; -import lombok.core.AST.Kind; -import lombok.eclipse.Eclipse; -import lombok.eclipse.EclipseAnnotationHandler; -import lombok.eclipse.EclipseNode; - -import org.eclipse.jdt.internal.compiler.ast.ASTNode; -import org.eclipse.jdt.internal.compiler.ast.Annotation; -import org.eclipse.jdt.internal.compiler.ast.Expression; -import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; -import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; -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.TypeDeclaration; -import org.eclipse.jdt.internal.compiler.ast.TypeReference; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.mangosdk.spi.ProviderFor; - -/** - * Handles the {@code lombok.Getter} annotation for eclipse. - */ -@ProviderFor(EclipseAnnotationHandler.class) -public class HandleGetter implements EclipseAnnotationHandler<Getter> { - /** - * Generates a getter on the stated field. - * - * Used by {@link HandleData}. - * - * The difference between this call and the handle method is as follows: - * - * If there is a {@code lombok.Getter} annotation on the field, it is used and the - * same rules apply (e.g. warning if the method already exists, stated access level applies). - * If not, the getter is still generated if it isn't already there, though there will not - * be a warning if its already there. The default access level is used. - */ - public void generateGetterForField(EclipseNode fieldNode, ASTNode pos) { - for (EclipseNode child : fieldNode.down()) { - if (child.getKind() == Kind.ANNOTATION) { - if (annotationTypeMatches(Getter.class, child)) { - //The annotation will make it happen, so we can skip it. - return; - } - } - } - - createGetterForField(AccessLevel.PUBLIC, fieldNode, fieldNode, pos, false); - } - - public boolean handle(AnnotationValues<Getter> annotation, Annotation ast, EclipseNode annotationNode) { - EclipseNode fieldNode = annotationNode.up(); - AccessLevel level = annotation.getInstance().value(); - if (level == AccessLevel.NONE) return true; - - return createGetterForField(level, fieldNode, annotationNode, annotationNode.get(), true); - } - - private boolean createGetterForField(AccessLevel level, - EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists) { - if (fieldNode.getKind() != Kind.FIELD) { - errorNode.addError("@Getter is only supported on a field."); - return true; - } - - FieldDeclaration field = (FieldDeclaration) fieldNode.get(); - TypeReference fieldType = copyType(field.type, source); - String fieldName = new String(field.name); - boolean isBoolean = nameEquals(fieldType.getTypeName(), "boolean") && fieldType.dimensions() == 0; - String getterName = TransformationsUtil.toGetterName(fieldName, isBoolean); - - int modifier = toEclipseModifier(level) | (field.modifiers & ClassFileConstants.AccStatic); - - for (String altName : TransformationsUtil.toAllGetterNames(fieldName, isBoolean)) { - switch (methodExists(altName, fieldNode)) { - case EXISTS_BY_LOMBOK: - return true; - case EXISTS_BY_USER: - if (whineIfExists) { - String altNameExpl = ""; - if (!altName.equals(getterName)) altNameExpl = String.format(" (%s)", altName); - errorNode.addWarning( - String.format("Not generating %s(): A method with that name already exists%s", getterName, altNameExpl)); - } - return true; - default: - case NOT_EXISTS: - //continue scanning the other alt names. - } - } - - MethodDeclaration method = generateGetter((TypeDeclaration) fieldNode.up().get(), field, getterName, modifier, source); - Annotation[] copiedAnnotations = copyAnnotations( - findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN), - findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN), source); - if (copiedAnnotations.length != 0) { - method.annotations = copiedAnnotations; - } - - injectMethod(fieldNode.up(), method); - - return true; - } - - private MethodDeclaration generateGetter(TypeDeclaration parent, FieldDeclaration field, String name, - int modifier, ASTNode source) { - MethodDeclaration method = new MethodDeclaration(parent.compilationResult); - Eclipse.setGeneratedBy(method, source); - method.modifiers = modifier; - method.returnType = copyType(field.type, source); - method.annotations = null; - method.arguments = null; - method.selector = name.toCharArray(); - method.binding = null; - method.thrownExceptions = null; - method.typeParameters = null; - method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; - Expression fieldExpression = new SingleNameReference(field.name, ((long)field.declarationSourceStart << 32) | field.declarationSourceEnd); - Eclipse.setGeneratedBy(fieldExpression, source); - Statement returnStatement = new ReturnStatement(fieldExpression, field.sourceStart, field.sourceEnd); - Eclipse.setGeneratedBy(returnStatement, source); - method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart; - method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd; - method.statements = new Statement[] { returnStatement }; - return method; - } -} diff --git a/src/lombok/eclipse/handlers/HandlePrintAST.java b/src/lombok/eclipse/handlers/HandlePrintAST.java deleted file mode 100644 index 580a54a2..00000000 --- a/src/lombok/eclipse/handlers/HandlePrintAST.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * 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 java.io.File; -import java.io.FileNotFoundException; -import java.io.PrintStream; - -import org.eclipse.jdt.internal.compiler.ast.Annotation; -import org.mangosdk.spi.ProviderFor; - -import lombok.Lombok; -import lombok.core.AnnotationValues; -import lombok.core.PrintAST; -import lombok.eclipse.EclipseASTVisitor; -import lombok.eclipse.EclipseAnnotationHandler; -import lombok.eclipse.EclipseNode; - -/** - * Handles the {@code lombok.core.PrintAST} annotation for eclipse. - */ -@ProviderFor(EclipseAnnotationHandler.class) -public class HandlePrintAST implements EclipseAnnotationHandler<PrintAST> { - public boolean handle(AnnotationValues<PrintAST> annotation, Annotation ast, EclipseNode annotationNode) { - if (!annotationNode.isCompleteParse()) return false; - - PrintStream stream = System.out; - String fileName = annotation.getInstance().outfile(); - if (fileName.length() > 0) try { - stream = new PrintStream(new File(fileName)); - } catch (FileNotFoundException e) { - Lombok.sneakyThrow(e); - } - - annotationNode.up().traverse(new EclipseASTVisitor.Printer(annotation.getInstance().printContent(), stream)); - return true; - } -} diff --git a/src/lombok/eclipse/handlers/HandleSetter.java b/src/lombok/eclipse/handlers/HandleSetter.java deleted file mode 100644 index 9bd10af3..00000000 --- a/src/lombok/eclipse/handlers/HandleSetter.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * 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 static lombok.eclipse.Eclipse.*; -import static lombok.eclipse.handlers.EclipseHandlerUtil.*; - -import java.lang.reflect.Modifier; - -import lombok.AccessLevel; -import lombok.Setter; -import lombok.core.AnnotationValues; -import lombok.core.TransformationsUtil; -import lombok.core.AST.Kind; -import lombok.eclipse.Eclipse; -import lombok.eclipse.EclipseAnnotationHandler; -import lombok.eclipse.EclipseNode; - -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.FieldDeclaration; -import org.eclipse.jdt.internal.compiler.ast.FieldReference; -import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; -import org.eclipse.jdt.internal.compiler.ast.NameReference; -import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; -import org.eclipse.jdt.internal.compiler.ast.Statement; -import org.eclipse.jdt.internal.compiler.ast.ThisReference; -import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; -import org.eclipse.jdt.internal.compiler.ast.TypeReference; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.eclipse.jdt.internal.compiler.lookup.TypeIds; -import org.mangosdk.spi.ProviderFor; - -/** - * Handles the {@code lombok.Setter} annotation for eclipse. - */ -@ProviderFor(EclipseAnnotationHandler.class) -public class HandleSetter implements EclipseAnnotationHandler<Setter> { - /** - * Generates a setter on the stated field. - * - * Used by {@link HandleData}. - * - * The difference between this call and the handle method is as follows: - * - * If there is a {@code lombok.Setter} annotation on the field, it is used and the - * same rules apply (e.g. warning if the method already exists, stated access level applies). - * If not, the setter is still generated if it isn't already there, though there will not - * be a warning if its already there. The default access level is used. - */ - public void generateSetterForField(EclipseNode fieldNode, ASTNode pos) { - for (EclipseNode child : fieldNode.down()) { - if (child.getKind() == Kind.ANNOTATION) { - if (annotationTypeMatches(Setter.class, child)) { - //The annotation will make it happen, so we can skip it. - return; - } - } - } - - createSetterForField(AccessLevel.PUBLIC, fieldNode, fieldNode, pos, false); - } - - public boolean handle(AnnotationValues<Setter> annotation, Annotation ast, EclipseNode annotationNode) { - EclipseNode fieldNode = annotationNode.up(); - if (fieldNode.getKind() != Kind.FIELD) return false; - AccessLevel level = annotation.getInstance().value(); - if (level == AccessLevel.NONE) return true; - - return createSetterForField(level, fieldNode, annotationNode, annotationNode.get(), true); - } - - private boolean createSetterForField(AccessLevel level, - EclipseNode fieldNode, EclipseNode errorNode, ASTNode pos, boolean whineIfExists) { - if (fieldNode.getKind() != Kind.FIELD) { - errorNode.addError("@Setter is only supported on a field."); - return true; - } - - FieldDeclaration field = (FieldDeclaration) fieldNode.get(); - String setterName = TransformationsUtil.toSetterName(new String(field.name)); - - int modifier = toEclipseModifier(level) | (field.modifiers & ClassFileConstants.AccStatic); - - switch (methodExists(setterName, fieldNode)) { - case EXISTS_BY_LOMBOK: - return true; - case EXISTS_BY_USER: - if (whineIfExists) errorNode.addWarning( - String.format("Not generating %s(%s %s): A method with that name already exists", - setterName, field.type, new String(field.name))); - return true; - default: - case NOT_EXISTS: - //continue with creating the setter - } - - MethodDeclaration method = generateSetter((TypeDeclaration) fieldNode.up().get(), field, setterName, modifier, pos); - - injectMethod(fieldNode.up(), method); - - return true; - } - - private MethodDeclaration generateSetter(TypeDeclaration parent, FieldDeclaration field, String name, - int modifier, ASTNode source) { - - int pS = source.sourceStart, pE = source.sourceEnd; - long p = (long)pS << 32 | pE; - MethodDeclaration method = new MethodDeclaration(parent.compilationResult); - Eclipse.setGeneratedBy(method, source); - method.modifiers = modifier; - method.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0); - method.returnType.sourceStart = pS; method.returnType.sourceEnd = pE; - Eclipse.setGeneratedBy(method.returnType, source); - method.annotations = null; - Argument param = new Argument(field.name, p, copyType(field.type, source), Modifier.FINAL); - param.sourceStart = pS; param.sourceEnd = pE; - Eclipse.setGeneratedBy(param, source); - method.arguments = new Argument[] { param }; - method.selector = name.toCharArray(); - method.binding = null; - method.thrownExceptions = null; - method.typeParameters = null; - method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; - FieldReference thisX = new FieldReference(field.name, p); - Eclipse.setGeneratedBy(thisX, source); - thisX.receiver = new ThisReference(source.sourceStart, source.sourceEnd); - Eclipse.setGeneratedBy(thisX.receiver, source); - NameReference fieldNameRef = new SingleNameReference(field.name, p); - Eclipse.setGeneratedBy(fieldNameRef, source); - Assignment assignment = new Assignment(thisX, fieldNameRef, (int)p); - assignment.sourceStart = pS; assignment.sourceEnd = pE; - Eclipse.setGeneratedBy(assignment, source); - method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart; - method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd; - - Annotation[] nonNulls = findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN); - Annotation[] nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN); - if (nonNulls.length == 0) { - method.statements = new Statement[] { assignment }; - } else { - Statement nullCheck = generateNullCheck(field, source); - if (nullCheck != null) method.statements = new Statement[] { nullCheck, assignment }; - else method.statements = new Statement[] { assignment }; - } - Annotation[] copiedAnnotations = copyAnnotations(nonNulls, nullables, source); - if (copiedAnnotations.length != 0) param.annotations = copiedAnnotations; - return method; - } -} diff --git a/src/lombok/eclipse/handlers/HandleSneakyThrows.java b/src/lombok/eclipse/handlers/HandleSneakyThrows.java deleted file mode 100644 index 38f22b2a..00000000 --- a/src/lombok/eclipse/handlers/HandleSneakyThrows.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * 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 java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.List; - -import lombok.SneakyThrows; -import lombok.core.AnnotationValues; -import lombok.eclipse.Eclipse; -import lombok.eclipse.EclipseAnnotationHandler; -import lombok.eclipse.EclipseNode; - -import org.eclipse.jdt.internal.compiler.ast.ASTNode; -import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; -import org.eclipse.jdt.internal.compiler.ast.Annotation; -import org.eclipse.jdt.internal.compiler.ast.Argument; -import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer; -import org.eclipse.jdt.internal.compiler.ast.Block; -import org.eclipse.jdt.internal.compiler.ast.Expression; -import org.eclipse.jdt.internal.compiler.ast.MemberValuePair; -import org.eclipse.jdt.internal.compiler.ast.MessageSend; -import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; -import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; -import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; -import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; -import org.eclipse.jdt.internal.compiler.ast.Statement; -import org.eclipse.jdt.internal.compiler.ast.ThrowStatement; -import org.eclipse.jdt.internal.compiler.ast.TryStatement; -import org.eclipse.jdt.internal.compiler.ast.TypeReference; -import org.mangosdk.spi.ProviderFor; - -/** - * Handles the {@code lombok.HandleSneakyThrows} annotation for eclipse. - */ -@ProviderFor(EclipseAnnotationHandler.class) -public class HandleSneakyThrows implements EclipseAnnotationHandler<SneakyThrows> { - private static class DeclaredException { - final String exceptionName; - final ASTNode node; - - DeclaredException(String exceptionName, ASTNode node) { - this.exceptionName = exceptionName; - this.node = node; - } - - public long getPos() { - return (long)node.sourceStart << 32 | node.sourceEnd; - } - } - - @Override public boolean handle(AnnotationValues<SneakyThrows> annotation, Annotation source, EclipseNode annotationNode) { - List<String> exceptionNames = annotation.getRawExpressions("value"); - List<DeclaredException> exceptions = new ArrayList<DeclaredException>(); - - MemberValuePair[] memberValuePairs = source.memberValuePairs(); - if (memberValuePairs == null || memberValuePairs.length == 0) { - exceptions.add(new DeclaredException("java.lang.Throwable", source)); - } else { - Expression arrayOrSingle = memberValuePairs[0].value; - final Expression[] exceptionNameNodes; - if (arrayOrSingle instanceof ArrayInitializer) { - exceptionNameNodes = ((ArrayInitializer)arrayOrSingle).expressions; - } else exceptionNameNodes = new Expression[] { arrayOrSingle }; - - if (exceptionNames.size() != exceptionNameNodes.length) { - annotationNode.addError( - "LOMBOK BUG: The number of exception classes in the annotation isn't the same pre- and post- guessing."); - } - - int idx = 0; - for (String exceptionName : exceptionNames) { - if (exceptionName.endsWith(".class")) exceptionName = exceptionName.substring(0, exceptionName.length() - 6); - exceptions.add(new DeclaredException(exceptionName, exceptionNameNodes[idx++])); - } - } - - - EclipseNode owner = annotationNode.up(); - switch (owner.getKind()) { -// case FIELD: -// return handleField(annotationNode, (FieldDeclaration)owner.get(), exceptions); - case METHOD: - return handleMethod(annotationNode, (AbstractMethodDeclaration)owner.get(), exceptions); - default: - annotationNode.addError("@SneakyThrows is legal only on methods and constructors."); - return true; - } - } - -// private boolean handleField(Node annotation, FieldDeclaration field, List<DeclaredException> exceptions) { -// if (field.initialization == null) { -// annotation.addError("@SneakyThrows can only be used on fields with an initialization statement."); -// return true; -// } -// -// Expression expression = field.initialization; -// Statement[] content = new Statement[] {new Assignment( -// new SingleNameReference(field.name, 0), expression, 0)}; -// field.initialization = null; -// -// for (DeclaredException exception : exceptions) { -// content = new Statement[] { buildTryCatchBlock(content, exception) }; -// } -// -// Block block = new Block(0); -// block.statements = content; -// -// Node typeNode = annotation.up().up(); -// -// Initializer initializer = new Initializer(block, field.modifiers & Modifier.STATIC); -// initializer.sourceStart = expression.sourceStart; -// initializer.sourceEnd = expression.sourceEnd; -// initializer.declarationSourceStart = expression.sourceStart; -// initializer.declarationSourceEnd = expression.sourceEnd; -// injectField(typeNode, initializer); -// -// typeNode.rebuild(); -// -// return true; -// } - - private boolean handleMethod(EclipseNode annotation, AbstractMethodDeclaration method, List<DeclaredException> exceptions) { - if (method.isAbstract()) { - annotation.addError("@SneakyThrows can only be used on concrete methods."); - return true; - } - - if (method.statements == null) return false; - - Statement[] contents = method.statements; - - for (DeclaredException exception : exceptions) { - contents = new Statement[] { buildTryCatchBlock(contents, exception, exception.node) }; - } - - method.statements = contents; - annotation.up().rebuild(); - - return true; - } - - private Statement buildTryCatchBlock(Statement[] contents, DeclaredException exception, ASTNode source) { - long p = exception.getPos(); - int pS = (int)(p >> 32), pE = (int)p; - - TryStatement tryStatement = new TryStatement(); - Eclipse.setGeneratedBy(tryStatement, source); - tryStatement.tryBlock = new Block(0); - tryStatement.tryBlock.sourceStart = pS; tryStatement.tryBlock.sourceEnd = pE; - Eclipse.setGeneratedBy(tryStatement.tryBlock, source); - tryStatement.tryBlock.statements = contents; - TypeReference typeReference; - if (exception.exceptionName.indexOf('.') == -1) { - typeReference = new SingleTypeReference(exception.exceptionName.toCharArray(), p); - typeReference.statementEnd = pE; - } else { - String[] x = exception.exceptionName.split("\\."); - char[][] elems = new char[x.length][]; - long[] poss = new long[x.length]; - int start = pS; - for (int i = 0; i < x.length; i++) { - elems[i] = x[i].trim().toCharArray(); - int end = start + x[i].length(); - poss[i] = (long)start << 32 | end; - start = end + 1; - } - typeReference = new QualifiedTypeReference(elems, poss); - } - Eclipse.setGeneratedBy(typeReference, source); - - Argument catchArg = new Argument("$ex".toCharArray(), p, typeReference, Modifier.FINAL); - Eclipse.setGeneratedBy(catchArg, source); - catchArg.declarationSourceEnd = catchArg.declarationEnd = catchArg.sourceEnd = pE; - catchArg.declarationSourceStart = catchArg.modifiersSourceStart = catchArg.sourceStart = pS; - - tryStatement.catchArguments = new Argument[] { catchArg }; - - MessageSend sneakyThrowStatement = new MessageSend(); - Eclipse.setGeneratedBy(sneakyThrowStatement, source); - sneakyThrowStatement.receiver = new QualifiedNameReference(new char[][] { "lombok".toCharArray(), "Lombok".toCharArray() }, new long[] { p, p }, pS, pE); - Eclipse.setGeneratedBy(sneakyThrowStatement.receiver, source); - sneakyThrowStatement.receiver.statementEnd = pE; - sneakyThrowStatement.selector = "sneakyThrow".toCharArray(); - SingleNameReference exRef = new SingleNameReference("$ex".toCharArray(), p); - Eclipse.setGeneratedBy(exRef, source); - exRef.statementEnd = pE; - sneakyThrowStatement.arguments = new Expression[] { exRef }; - sneakyThrowStatement.nameSourcePosition = p; - sneakyThrowStatement.sourceStart = pS; - sneakyThrowStatement.sourceEnd = sneakyThrowStatement.statementEnd = pE; - Statement rethrowStatement = new ThrowStatement(sneakyThrowStatement, pS, pE); - Eclipse.setGeneratedBy(rethrowStatement, source); - Block block = new Block(0); - block.sourceStart = pS; - block.sourceEnd = pE; - Eclipse.setGeneratedBy(block, source); - block.statements = new Statement[] { rethrowStatement }; - tryStatement.catchBlocks = new Block[] { block }; - tryStatement.sourceStart = pS; - tryStatement.sourceEnd = pE; - return tryStatement; - } -} diff --git a/src/lombok/eclipse/handlers/HandleSynchronized.java b/src/lombok/eclipse/handlers/HandleSynchronized.java deleted file mode 100644 index fde36192..00000000 --- a/src/lombok/eclipse/handlers/HandleSynchronized.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * 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 static lombok.eclipse.handlers.EclipseHandlerUtil.*; - -import java.lang.reflect.Modifier; - -import lombok.Synchronized; -import lombok.core.AnnotationValues; -import lombok.core.AST.Kind; -import lombok.eclipse.Eclipse; -import lombok.eclipse.EclipseAnnotationHandler; -import lombok.eclipse.EclipseNode; -import lombok.eclipse.handlers.EclipseHandlerUtil.MemberExistsResult; - -import org.eclipse.jdt.internal.compiler.ast.Annotation; -import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression; -import org.eclipse.jdt.internal.compiler.ast.Block; -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.IntLiteral; -import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; -import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; -import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; -import org.eclipse.jdt.internal.compiler.ast.Statement; -import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement; -import org.eclipse.jdt.internal.compiler.ast.ThisReference; -import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; -import org.mangosdk.spi.ProviderFor; - -/** - * Handles the {@code lombok.Synchronized} annotation for eclipse. - */ -@ProviderFor(EclipseAnnotationHandler.class) -public class HandleSynchronized implements EclipseAnnotationHandler<Synchronized> { - private static final char[] INSTANCE_LOCK_NAME = "$lock".toCharArray(); - private static final char[] STATIC_LOCK_NAME = "$LOCK".toCharArray(); - - @Override public boolean handle(AnnotationValues<Synchronized> annotation, Annotation source, EclipseNode annotationNode) { - int p1 = source.sourceStart -1; - int p2 = source.sourceStart -2; - long pos = (((long)p1) << 32) | p2; - EclipseNode methodNode = annotationNode.up(); - if (methodNode == null || methodNode.getKind() != Kind.METHOD || !(methodNode.get() instanceof MethodDeclaration)) { - annotationNode.addError("@Synchronized is legal only on methods."); - return true; - } - - MethodDeclaration method = (MethodDeclaration)methodNode.get(); - if (method.isAbstract()) { - annotationNode.addError("@Synchronized is legal only on concrete methods."); - return true; - } - - char[] lockName = annotation.getInstance().value().toCharArray(); - boolean autoMake = false; - if (lockName.length == 0) { - autoMake = true; - lockName = method.isStatic() ? STATIC_LOCK_NAME : INSTANCE_LOCK_NAME; - } - - if (fieldExists(new String(lockName), methodNode) == MemberExistsResult.NOT_EXISTS) { - if (!autoMake) { - annotationNode.addError("The field " + new String(lockName) + " does not exist."); - return true; - } - FieldDeclaration fieldDecl = new FieldDeclaration(lockName, 0, -1); - Eclipse.setGeneratedBy(fieldDecl, source); - fieldDecl.declarationSourceEnd = -1; - - fieldDecl.modifiers = (method.isStatic() ? Modifier.STATIC : 0) | Modifier.FINAL | Modifier.PRIVATE; - - //We use 'new Object[0];' because quite unlike 'new Object();', empty arrays *ARE* serializable! - ArrayAllocationExpression arrayAlloc = new ArrayAllocationExpression(); - Eclipse.setGeneratedBy(arrayAlloc, source); - arrayAlloc.dimensions = new Expression[] { new IntLiteral(new char[] { '0' }, 0, 0) }; - Eclipse.setGeneratedBy(arrayAlloc.dimensions[0], source); - arrayAlloc.type = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, new long[] { 0, 0, 0 }); - Eclipse.setGeneratedBy(arrayAlloc.type, source); - fieldDecl.type = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, new long[] { 0, 0, 0 }); - Eclipse.setGeneratedBy(fieldDecl.type, source); - fieldDecl.initialization = arrayAlloc; - injectField(annotationNode.up().up(), fieldDecl); - } - - if (method.statements == null) return false; - - Block block = new Block(0); - Eclipse.setGeneratedBy(block, source); - block.statements = method.statements; - Expression lockVariable; - if (method.isStatic()) lockVariable = new QualifiedNameReference(new char[][] { - methodNode.up().getName().toCharArray(), lockName }, new long[] { pos, pos }, p1, p2); - else { - lockVariable = new FieldReference(lockName, pos); - ThisReference thisReference = new ThisReference(p1, p2); - Eclipse.setGeneratedBy(thisReference, source); - ((FieldReference)lockVariable).receiver = thisReference; - } - Eclipse.setGeneratedBy(lockVariable, source); - - method.statements = new Statement[] { - new SynchronizedStatement(lockVariable, block, 0, 0) - }; - Eclipse.setGeneratedBy(method.statements[0], source); - - methodNode.rebuild(); - - return true; - } -} diff --git a/src/lombok/eclipse/handlers/HandleToString.java b/src/lombok/eclipse/handlers/HandleToString.java deleted file mode 100644 index d5a4c398..00000000 --- a/src/lombok/eclipse/handlers/HandleToString.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * 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 static lombok.eclipse.handlers.EclipseHandlerUtil.*; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import lombok.AccessLevel; -import lombok.ToString; -import lombok.core.AnnotationValues; -import lombok.core.AST.Kind; -import lombok.eclipse.Eclipse; -import lombok.eclipse.EclipseAnnotationHandler; -import lombok.eclipse.EclipseNode; - -import org.eclipse.jdt.internal.compiler.ast.ASTNode; -import org.eclipse.jdt.internal.compiler.ast.Annotation; -import org.eclipse.jdt.internal.compiler.ast.BinaryExpression; -import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; -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.MessageSend; -import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; -import org.eclipse.jdt.internal.compiler.ast.NameReference; -import org.eclipse.jdt.internal.compiler.ast.OperatorIds; -import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; -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.SuperReference; -import org.eclipse.jdt.internal.compiler.ast.ThisReference; -import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; -import org.mangosdk.spi.ProviderFor; - -/** - * Handles the {@code ToString} annotation for eclipse. - */ -@ProviderFor(EclipseAnnotationHandler.class) -public class HandleToString implements EclipseAnnotationHandler<ToString> { - private void checkForBogusFieldNames(EclipseNode type, AnnotationValues<ToString> annotation) { - if (annotation.isExplicit("exclude")) { - for (int i : createListOfNonExistentFields(Arrays.asList(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(Arrays.asList(annotation.getInstance().of()), type, false, false)) { - annotation.setWarning("of", "This field does not exist.", i); - } - } - } - - public void generateToStringForType(EclipseNode typeNode, EclipseNode errorNode) { - for (EclipseNode child : typeNode.down()) { - if (child.getKind() == Kind.ANNOTATION) { - if (Eclipse.annotationTypeMatches(ToString.class, child)) { - //The annotation will make it happen, so we can skip it. - return; - } - } - } - - boolean includeFieldNames = true; - try { - includeFieldNames = ((Boolean)ToString.class.getMethod("includeFieldNames").getDefaultValue()).booleanValue(); - } catch (Exception ignore) {} - generateToString(typeNode, errorNode, null, null, includeFieldNames, null, false); - } - - public boolean handle(AnnotationValues<ToString> annotation, Annotation ast, EclipseNode annotationNode) { - ToString ann = annotation.getInstance(); - List<String> excludes = Arrays.asList(ann.exclude()); - List<String> includes = Arrays.asList(ann.of()); - EclipseNode typeNode = annotationNode.up(); - 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."); - } - - checkForBogusFieldNames(typeNode, annotation); - - return generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true); - } - - public boolean generateToString(EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes, - boolean includeFieldNames, Boolean callSuper, boolean whineIfExists) { - 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("@ToString is only supported on a class."); - 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(); - //Skip static fields. - if ((fieldDecl.modifiers & ClassFileConstants.AccStatic) != 0) continue; - //Skip excluded fields. - if (excludes != null && excludes.contains(new String(fieldDecl.name))) continue; - //Skip fields that start with $ - if (fieldDecl.name.length > 0 && fieldDecl.name[0] == '$') continue; - nodesForToString.add(child); - } - } - - switch (methodExists("toString", typeNode)) { - case NOT_EXISTS: - MethodDeclaration toString = createToString(typeNode, nodesForToString, includeFieldNames, callSuper, errorNode.get()); - 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; - } - } - - private MethodDeclaration createToString(EclipseNode type, Collection<EclipseNode> fields, - boolean includeFieldNames, boolean callSuper, ASTNode source) { - TypeDeclaration typeDeclaration = (TypeDeclaration)type.get(); - char[] rawTypeName = typeDeclaration.name; - String typeName = rawTypeName == null ? "" : new String(rawTypeName); - char[] suffix = ")".toCharArray(); - String infixS = ", "; - char[] infix = infixS.toCharArray(); - int pS = source.sourceStart, pE = source.sourceEnd; - long p = (long)pS << 32 | pE; - final int PLUS = OperatorIds.PLUS; - - char[] prefix; - - if (callSuper) { - prefix = (typeName + "(super=").toCharArray(); - } else if (fields.isEmpty()) { - prefix = (typeName + "()").toCharArray(); - } else if (includeFieldNames) { - prefix = (typeName + "(" + new String(((FieldDeclaration)fields.iterator().next().get()).name) + "=").toCharArray(); - } else { - prefix = (typeName + "(").toCharArray(); - } - - boolean first = true; - Expression current = new StringLiteral(prefix, pS, pE, 0); - Eclipse.setGeneratedBy(current, source); - - if (callSuper) { - MessageSend callToSuper = new MessageSend(); - callToSuper.sourceStart = pS; callToSuper.sourceEnd = pE; - Eclipse.setGeneratedBy(callToSuper, source); - callToSuper.receiver = new SuperReference(pS, pE); - Eclipse.setGeneratedBy(callToSuper, source); - callToSuper.selector = "toString".toCharArray(); - current = new BinaryExpression(current, callToSuper, PLUS); - Eclipse.setGeneratedBy(current, source); - first = false; - } - - for (EclipseNode field : fields) { - FieldDeclaration f = (FieldDeclaration)field.get(); - if (f.name == null || f.type == null) continue; - - Expression ex; - if (f.type.dimensions() > 0) { - MessageSend arrayToString = new MessageSend(); - arrayToString.sourceStart = pS; arrayToString.sourceEnd = pE; - arrayToString.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.UTIL, "Arrays".toCharArray()); - arrayToString.arguments = new Expression[] { new SingleNameReference(f.name, p) }; - Eclipse.setGeneratedBy(arrayToString.arguments[0], source); - if (f.type.dimensions() > 1 || !BUILT_IN_TYPES.contains(new String(f.type.getLastToken()))) { - arrayToString.selector = "deepToString".toCharArray(); - } else { - arrayToString.selector = "toString".toCharArray(); - } - ex = arrayToString; - } else { - FieldReference thisX = new FieldReference(f.name, p); - thisX.receiver = new ThisReference(source.sourceStart, source.sourceEnd); - Eclipse.setGeneratedBy(thisX.receiver, source); - ex = thisX; - } - Eclipse.setGeneratedBy(ex, source); - - if (first) { - current = new BinaryExpression(current, ex, PLUS); - current.sourceStart = pS; current.sourceEnd = pE; - Eclipse.setGeneratedBy(current, source); - first = false; - continue; - } - - StringLiteral fieldNameLiteral; - if (includeFieldNames) { - char[] namePlusEqualsSign = (infixS + new String(f.name) + "=").toCharArray(); - fieldNameLiteral = new StringLiteral(namePlusEqualsSign, pS, pE, 0); - } else { - fieldNameLiteral = new StringLiteral(infix, pS, pE, 0); - } - Eclipse.setGeneratedBy(fieldNameLiteral, source); - current = new BinaryExpression(current, fieldNameLiteral, PLUS); - Eclipse.setGeneratedBy(current, source); - current = new BinaryExpression(current, ex, PLUS); - Eclipse.setGeneratedBy(current, source); - } - if (!first) { - StringLiteral suffixLiteral = new StringLiteral(suffix, pS, pE, 0); - Eclipse.setGeneratedBy(suffixLiteral, source); - current = new BinaryExpression(current, suffixLiteral, PLUS); - Eclipse.setGeneratedBy(current, source); - } - - ReturnStatement returnStatement = new ReturnStatement(current, pS, pE); - Eclipse.setGeneratedBy(returnStatement, source); - - MethodDeclaration method = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult); - Eclipse.setGeneratedBy(method, source); - method.modifiers = toEclipseModifier(AccessLevel.PUBLIC); - method.returnType = new QualifiedTypeReference(TypeConstants.JAVA_LANG_STRING, new long[] {p, p, p}); - Eclipse.setGeneratedBy(method.returnType, source); - method.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source)}; - method.arguments = null; - method.selector = "toString".toCharArray(); - method.thrownExceptions = null; - method.typeParameters = null; - method.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; - method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart; - method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd; - method.statements = new Statement[] { returnStatement }; - return method; - } - - private static final Set<String> BUILT_IN_TYPES = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList( - "byte", "short", "int", "long", "char", "boolean", "double", "float"))); - - private NameReference generateQualifiedNameRef(ASTNode source, char[]... varNames) { - int pS = source.sourceStart, pE = source.sourceEnd; - long p = (long)pS << 32 | pE; - NameReference ref; - if (varNames.length > 1) ref = new QualifiedNameReference(varNames, new long[varNames.length], pS, pE); - else ref = new SingleNameReference(varNames[0], p); - Eclipse.setGeneratedBy(ref, source); - return ref; - } -} diff --git a/src/lombok/eclipse/handlers/package-info.java b/src/lombok/eclipse/handlers/package-info.java deleted file mode 100644 index 062b73b3..00000000 --- a/src/lombok/eclipse/handlers/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * 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. - */ - -/** - * Contains the classes that implement the transformations for all of lombok's various features on the eclipse platform. - */ -package lombok.eclipse.handlers; |