aboutsummaryrefslogtreecommitdiff
path: root/src/lombok/eclipse/handlers/HandleToString.java
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@tipit.to>2009-11-25 07:32:49 +0100
committerReinier Zwitserloot <reinier@tipit.to>2009-11-25 07:32:49 +0100
commit1a0e611a9c5e1ee518670647ce1a44beae559b44 (patch)
treee5ef8f671bc6688f486e874d4e2e1a7813e4f0b2 /src/lombok/eclipse/handlers/HandleToString.java
parent7fd947ea40c25dad9ee543ebc4b92de9a2e05efc (diff)
downloadlombok-1a0e611a9c5e1ee518670647ce1a44beae559b44.tar.gz
lombok-1a0e611a9c5e1ee518670647ce1a44beae559b44.tar.bz2
lombok-1a0e611a9c5e1ee518670647ce1a44beae559b44.zip
Refactored the source folders.
Diffstat (limited to 'src/lombok/eclipse/handlers/HandleToString.java')
-rw-r--r--src/lombok/eclipse/handlers/HandleToString.java304
1 files changed, 0 insertions, 304 deletions
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;
- }
-}