lombok.eclipse.handlers.ast.EclipseASTMaker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lombok-pg Show documentation
Show all versions of lombok-pg Show documentation
lombok-pg is a collection of extensions to Project Lombok
The newest version!
/*
* Copyright © 2011-2012 Philipp Eichhorn
*
* 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.ast;
import static org.eclipse.jdt.internal.compiler.ast.ASTNode.IsSuperType;
import static org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.*;
import static org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers.AccSemicolonBody;
import static org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers.AccImplementing;
import static lombok.ast.AST.*;
import static lombok.eclipse.Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
import static lombok.eclipse.Eclipse.fromQualifiedName;
import static lombok.eclipse.Eclipse.poss;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
import static lombok.eclipse.handlers.Eclipse.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
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.ArrayAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ArrayReference;
import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Assignment;
import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
import org.eclipse.jdt.internal.compiler.ast.Block;
import org.eclipse.jdt.internal.compiler.ast.BreakStatement;
import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
import org.eclipse.jdt.internal.compiler.ast.CastExpression;
import org.eclipse.jdt.internal.compiler.ast.CharLiteral;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ContinueStatement;
import org.eclipse.jdt.internal.compiler.ast.DoStatement;
import org.eclipse.jdt.internal.compiler.ast.DoubleLiteral;
import org.eclipse.jdt.internal.compiler.ast.EmptyStatement;
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
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.FloatLiteral;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.eclipse.jdt.internal.compiler.ast.IfStatement;
import org.eclipse.jdt.internal.compiler.ast.Initializer;
import org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression;
import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
import org.eclipse.jdt.internal.compiler.ast.Javadoc;
import org.eclipse.jdt.internal.compiler.ast.JavadocReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.JavadocSingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.JavadocSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.LongLiteral;
import org.eclipse.jdt.internal.compiler.ast.MagicLiteral;
import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation;
import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
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.NormalAnnotation;
import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.NumberLiteral;
import org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.PostfixExpression;
import org.eclipse.jdt.internal.compiler.ast.PrefixExpression;
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
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.StringLiteral;
import org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement;
import org.eclipse.jdt.internal.compiler.ast.ThisReference;
import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
import org.eclipse.jdt.internal.compiler.ast.TrueLiteral;
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
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.ast.UnaryExpression;
import org.eclipse.jdt.internal.compiler.ast.WhileStatement;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
import lombok.*;
import lombok.core.util.As;
import lombok.core.util.Cast;
import lombok.core.util.Each;
import lombok.core.util.Is;
import lombok.eclipse.EclipseNode;
@RequiredArgsConstructor
public final class EclipseASTMaker implements lombok.ast.ASTVisitor {
private static final Map UNARY_OPERATORS = new HashMap();
static {
UNARY_OPERATORS.put("+", OperatorIds.PLUS);
UNARY_OPERATORS.put("-", OperatorIds.MINUS);
UNARY_OPERATORS.put("!", OperatorIds.NOT);
UNARY_OPERATORS.put("~", OperatorIds.TWIDDLE);
UNARY_OPERATORS.put("++X", OperatorIds.PLUS);
UNARY_OPERATORS.put("--X", OperatorIds.MINUS);
UNARY_OPERATORS.put("X++", OperatorIds.PLUS);
UNARY_OPERATORS.put("X--", OperatorIds.MINUS);
}
private static final Map BINARY_OPERATORS = new HashMap();
static {
BINARY_OPERATORS.put("||", OperatorIds.OR_OR);
BINARY_OPERATORS.put("&&", OperatorIds.AND_AND);
BINARY_OPERATORS.put("==", OperatorIds.EQUAL_EQUAL);
BINARY_OPERATORS.put("!=", OperatorIds.NOT_EQUAL);
BINARY_OPERATORS.put("<", OperatorIds.LESS);
BINARY_OPERATORS.put(">", OperatorIds.GREATER);
BINARY_OPERATORS.put("<=", OperatorIds.LESS_EQUAL);
BINARY_OPERATORS.put(">=", OperatorIds.GREATER_EQUAL);
BINARY_OPERATORS.put("|", OperatorIds.OR);
BINARY_OPERATORS.put("^", OperatorIds.XOR);
BINARY_OPERATORS.put("&", OperatorIds.AND);
BINARY_OPERATORS.put("<<", OperatorIds.LEFT_SHIFT);
BINARY_OPERATORS.put(">>", OperatorIds.RIGHT_SHIFT);
BINARY_OPERATORS.put(">>>", OperatorIds.UNSIGNED_RIGHT_SHIFT);
BINARY_OPERATORS.put("+", OperatorIds.PLUS);
BINARY_OPERATORS.put("-", OperatorIds.MINUS);
BINARY_OPERATORS.put("*", OperatorIds.MULTIPLY);
BINARY_OPERATORS.put("/", OperatorIds.DIVIDE);
BINARY_OPERATORS.put("%", OperatorIds.REMAINDER);
}
private final EclipseNode sourceNode;
private final ASTNode source;
public T build(final lombok.ast.Node> node) {
return this. build(node, null);
}
public T build(final lombok.ast.Node> node, final Class extectedType) {
if (node == null) return null;
return Cast. uncheckedCast(node.accept(this, null));
}
public List build(final List extends lombok.ast.Node>> nodes) {
return this. build(nodes, null);
}
public List build(final List extends lombok.ast.Node>> nodes, final Class extectedType) {
if (nodes == null) return null;
final List list = new ArrayList();
for (lombok.ast.Node> node : nodes) {
list.add(build(node, extectedType));
}
return list;
}
private ASTNode posHintOf(final lombok.ast.Node> node) {
ASTNode posHint = node.posHint();
return posHint == null ? source : posHint;
}
private int modifiersFor(final Set modifiers) {
int mods = 0;
mods |= modifiers.contains(lombok.ast.Modifier.FINAL) ? AccFinal : 0;
mods |= modifiers.contains(lombok.ast.Modifier.PRIVATE) ? AccPrivate : 0;
mods |= modifiers.contains(lombok.ast.Modifier.PROTECTED) ? AccProtected : 0;
mods |= modifiers.contains(lombok.ast.Modifier.PUBLIC) ? AccPublic : 0;
mods |= modifiers.contains(lombok.ast.Modifier.STATIC) ? AccStatic : 0;
mods |= modifiers.contains(lombok.ast.Modifier.TRANSIENT) ? AccTransient : 0;
mods |= modifiers.contains(lombok.ast.Modifier.VOLATILE) ? AccVolatile : 0;
return mods;
}
private Statement getEmptyStatement(final lombok.ast.Node> node) {
final EmptyStatement emptyStatement = new EmptyStatement(0, 0);
setGeneratedByAndCopyPos(emptyStatement, source, posHintOf(node));
return emptyStatement;
}
private static ELEMENT_TYPE[] toArray(final List> list, final ELEMENT_TYPE[] array) {
if ((list != null) && !list.isEmpty()) {
return list.toArray(array);
}
return null;
}
@Override
public ASTNode visitAnnotation(final lombok.ast.Annotation node, final Void p) {
final Annotation ann;
if (node.getValues().isEmpty()) {
ann = new MarkerAnnotation(build(node.getType(), TypeReference.class), 0);
} else if (node.getValues().containsKey("value") && node.getValues().size() == 1) {
ann = new SingleMemberAnnotation(build(node.getType(), TypeReference.class), 0);
((SingleMemberAnnotation) ann).memberValue = build(node.getValues().get("value"));
} else {
ann = new NormalAnnotation(build(node.getType(), TypeReference.class), 0);
List valuePairs = new ArrayList();
for (Entry> entry : node.getValues().entrySet()) {
MemberValuePair valuePair = new MemberValuePair(entry.getKey().toCharArray(), 0, 0, build(entry.getValue(), Expression.class));
setGeneratedByAndCopyPos(valuePair, source, posHintOf(node));
valuePairs.add(valuePair);
}
((NormalAnnotation) ann).memberValuePairs = valuePairs.toArray(new MemberValuePair[0]);
}
setGeneratedByAndCopyPos(ann, source, posHintOf(node));
return ann;
}
@Override
public ASTNode visitArgument(final lombok.ast.Argument node, final Void p) {
final Argument argument = new Argument(node.getName().toCharArray(), 0, null, 0);
setGeneratedByAndCopyPos(argument, source, posHintOf(node));
argument.modifiers = modifiersFor(node.getModifiers());
argument.annotations = toArray(build(node.getAnnotations()), new Annotation[0]);
argument.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
argument.type = build(node.getType());
return argument;
}
@Override
public ASTNode visitArrayRef(final lombok.ast.ArrayRef node, final Void p) {
final ArrayReference arrayReference = new ArrayReference(build(node.getIndexed(), Expression.class), build(node.getIndex(), Expression.class));
setGeneratedByAndCopyPos(arrayReference, source, posHintOf(node));
return arrayReference;
}
@Override
public ASTNode visitAssignment(final lombok.ast.Assignment node, final Void p) {
final Assignment assignment = new Assignment(build(node.getLeft(), Expression.class), build(node.getRight(), Expression.class), 0);
setGeneratedByAndCopyPos(assignment, source, posHintOf(node));
return assignment;
}
@Override
public ASTNode visitBinary(final lombok.ast.Binary node, final Void p) {
final String operator = node.getOperator();
final int opCode;
if (BINARY_OPERATORS.containsKey(operator)) {
opCode = BINARY_OPERATORS.get(operator);
} else {
throw new IllegalStateException(String.format("Unknown binary operator '%s'", operator));
}
final BinaryExpression binaryExpression;
if ("||".equals(operator)) {
binaryExpression = new OR_OR_Expression(build(node.getLeft(), Expression.class), build(node.getRight(), Expression.class), opCode);
} else if ("&&".equals(operator)) {
binaryExpression = new AND_AND_Expression(build(node.getLeft(), Expression.class), build(node.getRight(), Expression.class), opCode);
} else if (Is.oneOf(operator, "==", "!=")) {
binaryExpression = new EqualExpression(build(node.getLeft(), Expression.class), build(node.getRight(), Expression.class), opCode);
} else {
binaryExpression = new BinaryExpression(build(node.getLeft(), Expression.class), build(node.getRight(), Expression.class), opCode);
}
setGeneratedByAndCopyPos(binaryExpression, source, posHintOf(node));
return binaryExpression;
}
@Override
public ASTNode visitBlock(final lombok.ast.Block node, final Void p) {
final Block block = new Block(0);
setGeneratedByAndCopyPos(block, source, posHintOf(node));
block.statements = toArray(build(node.getStatements()), new Statement[0]);
return block;
}
@Override
public ASTNode visitBooleanLiteral(final lombok.ast.BooleanLiteral node, final Void p) {
final MagicLiteral literal;
if (node.isTrue()) {
literal = new TrueLiteral(0, 0);
} else {
literal = new FalseLiteral(0, 0);
}
setGeneratedByAndCopyPos(literal, source, posHintOf(node));
return literal;
}
@Override
public ASTNode visitBreak(final lombok.ast.Break node, final Void p) {
final BreakStatement breakStatement = new BreakStatement(node.getLabel() == null ? null : node.getLabel().toCharArray(), 0, 0);
setGeneratedByAndCopyPos(breakStatement, source, posHintOf(node));
return breakStatement;
}
@Override
public ASTNode visitCall(final lombok.ast.Call node, final Void p) {
final MessageSend messageSend = new MessageSend();
setGeneratedByAndCopyPos(messageSend, source, posHintOf(node));
if (node.getReceiver() == null) {
messageSend.receiver = build(This().implicit());
} else {
messageSend.receiver = build(node.getReceiver());
}
messageSend.selector = node.getName().toCharArray();
messageSend.typeArguments = toArray(build(node.getTypeArgs()), new TypeReference[0]);
messageSend.arguments = toArray(build(node.getArgs()), new Expression[0]);
return messageSend;
}
@Override
public ASTNode visitCast(final lombok.ast.Cast node, final Void p) {
final CastExpression castExpression = createCastExpression(build(node.getExpression(), Expression.class), build(node.getType(), TypeReference.class));
setGeneratedByAndCopyPos(castExpression, source, posHintOf(node));
return castExpression;
}
private CastExpression createCastExpression(final Expression expression, final Expression typeRef) {
try {
return Reflection.castExpressionConstructor.newInstance(expression, typeRef);
} catch (final Exception e) {
throw new IllegalStateException(e);
}
}
@Override
public ASTNode visitCase(final lombok.ast.Case node, final Void p) {
throw new IllegalStateException("");
}
@Override
public ASTNode visitCharLiteral(final lombok.ast.CharLiteral node, final Void p) {
final CharLiteral literal = new CharLiteral(node.getCharacter().toCharArray(), 0, 0);
setGeneratedByAndCopyPos(literal, source, posHintOf(node));
return literal;
}
@Override
public ASTNode visitClassDecl(final lombok.ast.ClassDecl node, final Void p) {
final TypeDeclaration typeDeclaration = new TypeDeclaration(((CompilationUnitDeclaration) sourceNode.top().get()).compilationResult);
setGeneratedByAndCopyPos(typeDeclaration, source, posHintOf(node));
typeDeclaration.modifiers = modifiersFor(node.getModifiers());
if (node.isInterface()) typeDeclaration.modifiers |= AccInterface;
typeDeclaration.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
if (node.isLocal()) typeDeclaration.bits |= ASTNode.IsLocalType;
if (node.isAnonymous()) {
typeDeclaration.bits |= ASTNode.IsAnonymousType;
}
if (Is.empty(node.getName())) {
typeDeclaration.name = CharOperation.NO_CHAR;
} else {
typeDeclaration.name = node.getName().toCharArray();
}
typeDeclaration.annotations = toArray(build(node.getAnnotations()), new Annotation[0]);
typeDeclaration.typeParameters = toArray(build(node.getTypeParameters()), new TypeParameter[0]);
typeDeclaration.fields = toArray(build(node.getFields()), new FieldDeclaration[0]);
typeDeclaration.methods = toArray(build(node.getMethods()), new AbstractMethodDeclaration[0]);
typeDeclaration.memberTypes = toArray(build(node.getMemberTypes()), new TypeDeclaration[0]);
typeDeclaration.superInterfaces = toArray(build(node.getSuperInterfaces()), new TypeReference[0]);
typeDeclaration.superclass = build(node.getSuperclass());
for (final FieldDeclaration field : Each.elementIn(typeDeclaration.fields)) {
if (isEnumConstant(field) || (field.modifiers & Modifier.STATIC) != 0) {
typeDeclaration.addClinit();
break;
}
}
return typeDeclaration;
}
private static boolean isEnumConstant(final FieldDeclaration field) {
return ((field.initialization instanceof AllocationExpression) && (((AllocationExpression) field.initialization).enumConstant == field));
}
@Override
public ASTNode visitConstructorDecl(final lombok.ast.ConstructorDecl node, final Void p) {
final ConstructorDeclaration constructorDeclaration = new ConstructorDeclaration(((CompilationUnitDeclaration) sourceNode.top().get()).compilationResult);
setGeneratedByAndCopyPos(constructorDeclaration, source, posHintOf(node));
constructorDeclaration.modifiers = modifiersFor(node.getModifiers());
constructorDeclaration.annotations = toArray(build(node.getAnnotations()), new Annotation[0]);
if (node.implicitSuper()) {
constructorDeclaration.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper);
}
constructorDeclaration.selector = node.getName().toCharArray();
constructorDeclaration.thrownExceptions = toArray(build(node.getThrownExceptions()), new TypeReference[0]);
constructorDeclaration.typeParameters = toArray(build(node.getTypeParameters()), new TypeParameter[0]);
constructorDeclaration.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
constructorDeclaration.arguments = toArray(build(node.getArguments()), new Argument[0]);
if (!node.getStatements().isEmpty()) {
constructorDeclaration.statements = toArray(build(node.getStatements()), new Statement[0]);
}
constructorDeclaration.javadoc = build(node.getJavaDoc());
return constructorDeclaration;
}
@Override
public ASTNode visitContinue(final lombok.ast.Continue node, final Void p) {
final ContinueStatement continueStatement = new ContinueStatement(node.getLabel() == null ? null : node.getLabel().toCharArray(), 0, 0);
setGeneratedByAndCopyPos(continueStatement, source, posHintOf(node));
return continueStatement;
}
@Override
public ASTNode visitDoWhile(final lombok.ast.DoWhile node, final Void p) {
final DoStatement doStatement = new DoStatement(build(node.getCondition(), Expression.class), build(node.getAction(), Statement.class), 0, 0);
setGeneratedByAndCopyPos(doStatement, source, posHintOf(node));
return doStatement;
}
@Override
public ASTNode visitDefaultValue(lombok.ast.DefaultValue node, Void p) {
lombok.ast.Expression> returnValue = Null();
final TypeReference type = build(node.getType());
if (type instanceof SingleTypeReference) {
final String name = As.string(type.getLastToken());
if ("int".equals(name)) {
returnValue = Number(Integer.valueOf(0));
} else if ("byte".equals(name)) {
returnValue = Number(Integer.valueOf(0));
} else if ("short".equals(name)) {
returnValue = Number(Integer.valueOf(0));
} else if ("char".equals(name)) {
returnValue = Char("");
} else if ("long".equals(name)) {
returnValue = Number(Long.valueOf(0));
} else if ("float".equals(name)) {
returnValue = Number(Float.valueOf(0));
} else if ("double".equals(name)) {
returnValue = Number(Double.valueOf(0));
} else if ("boolean".equals(name)) {
returnValue = False();
} else if ("void".equals(name)) {
returnValue = null;
}
}
return build(returnValue);
}
@Override
public ASTNode visitEnumConstant(final lombok.ast.EnumConstant node, final Void p) {
final AllocationExpression allocationExpression = new AllocationExpression();
setGeneratedByAndCopyPos(allocationExpression, source, posHintOf(node));
allocationExpression.arguments = toArray(build(node.getArgs()), new Expression[0]);
allocationExpression.enumConstant = new FieldDeclaration(node.getName().toCharArray(), 0, 0);
setGeneratedByAndCopyPos(allocationExpression.enumConstant, source, posHintOf(node));
allocationExpression.enumConstant.initialization = allocationExpression;
allocationExpression.enumConstant.javadoc = build(node.getJavaDoc());
return allocationExpression.enumConstant;
}
@Override
public ASTNode visitFieldDecl(final lombok.ast.FieldDecl node, final Void p) {
final FieldDeclaration fieldDeclaration = new FieldDeclaration(node.getName().toCharArray(), 0, 0);
setGeneratedBy(fieldDeclaration, source);
fieldDeclaration.modifiers = modifiersFor(node.getModifiers());
fieldDeclaration.annotations = toArray(build(node.getAnnotations()), new Annotation[0]);
fieldDeclaration.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
fieldDeclaration.type = build(node.getType());
if (node.getInitialization() != null) {
fieldDeclaration.initialization = build(node.getInitialization());
}
fieldDeclaration.javadoc = build(node.getJavaDoc());
return fieldDeclaration;
}
@Override
public ASTNode visitFieldRef(final lombok.ast.FieldRef node, final Void p) {
FieldReference fieldRef = new FieldReference(node.getName().toCharArray(), 0);
fieldRef.receiver = build(node.getReceiver());
setGeneratedByAndCopyPos(fieldRef, source, posHintOf(node));
return fieldRef;
}
@Override
public ASTNode visitForeach(final lombok.ast.Foreach node, final Void p) {
final ForeachStatement forEach = new ForeachStatement(build(node.getElementVariable(), LocalDeclaration.class), 0);
setGeneratedByAndCopyPos(forEach, source, posHintOf(node));
forEach.collection = build(node.getCollection());
forEach.action = build(node.getAction());
return forEach;
}
@Override
public ASTNode visitIf(final lombok.ast.If node, final Void p) {
final Statement thenStatement = node.getThenStatement() == null ? getEmptyStatement(node) : build(node.getThenStatement(), Statement.class);
final IfStatement ifStatement = new IfStatement(build(node.getCondition(), Expression.class), thenStatement, 0, 0);
if (node.getElseStatement() != null) {
ifStatement.elseStatement = build(node.getElseStatement());
}
setGeneratedByAndCopyPos(ifStatement, source, posHintOf(node));
return ifStatement;
}
@Override
public ASTNode visitInitializer(lombok.ast.Initializer node, Void p) {
final Block block = new Block(0);
setGeneratedByAndCopyPos(block, source, posHintOf(node));
block.statements = toArray(build(node.getStatements()), new Statement[0]);
final Initializer initializer = new Initializer(block, modifiersFor(node.getModifiers()));
initializer.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
setGeneratedByAndCopyPos(initializer, source, posHintOf(node));
return initializer;
}
@Override
public ASTNode visitInstanceOf(final lombok.ast.InstanceOf node, final Void p) {
final InstanceOfExpression instanceOfExpression = new InstanceOfExpression(build(node.getExpression(), Expression.class), build(node.getType(), TypeReference.class));
setGeneratedByAndCopyPos(instanceOfExpression, source, posHintOf(node));
return instanceOfExpression;
}
@Override
public ASTNode visitJavaDoc(final lombok.ast.JavaDoc node, final Void p) {
final Javadoc javadoc = new Javadoc(0, 0);
setGeneratedByAndCopyPos(javadoc, source, posHintOf(node));
// TODO node.getMessage()
final List argumentReferences = new ArrayList();
for (Map.Entry argumentReference : node.getArgumentReferences().entrySet()) {
final JavadocSingleNameReference ref = new JavadocSingleNameReference((argumentReference.getKey()).toCharArray(), 0, 0, 0); // TODO argumentReference.getValue()
setGeneratedByAndCopyPos(ref, source, posHintOf(node));
argumentReferences.add(ref);
}
javadoc.paramReferences = toArray(argumentReferences, new JavadocSingleNameReference[0]);
final List paramTypeReferences = new ArrayList();
for (Map.Entry paramTypeReference : node.getParamTypeReferences().entrySet()) {
final JavadocSingleTypeReference ref = new JavadocSingleTypeReference((paramTypeReference.getKey()).toCharArray(), 0, 0, 0); // TODO paramTypeReference.getValue()
setGeneratedByAndCopyPos(ref, source, posHintOf(node));
paramTypeReferences.add(ref);
}
javadoc.paramTypeParameters = toArray(paramTypeReferences, new JavadocSingleTypeReference[0]);
final List exceptionReferences = new ArrayList();
for (Map.Entry exceptionReference : node.getExceptionReferences().entrySet()) {
final TypeReference ref = build(exceptionReference.getKey()); // TODO exceptionReference.getValue()
setGeneratedByAndCopyPos(ref, source, posHintOf(node));
exceptionReferences.add(ref);
}
javadoc.exceptionReferences = toArray(exceptionReferences, new TypeReference[0]);
if (node.getReturnMessage() != null) javadoc.returnStatement = new JavadocReturnStatement(0, 0); // TODO node.getReturnStatement()
return javadoc;
}
@Override
public ASTNode visitLocalDecl(final lombok.ast.LocalDecl node, final Void p) {
final LocalDeclaration localDeclaration = new LocalDeclaration(node.getName().toCharArray(), 0, 0);
setGeneratedByAndCopyPos(localDeclaration, source, posHintOf(node));
localDeclaration.modifiers = modifiersFor(node.getModifiers());
localDeclaration.annotations = toArray(build(node.getAnnotations()), new Annotation[0]);
localDeclaration.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
localDeclaration.type = build(node.getType());
if (node.getInitialization() != null) {
localDeclaration.initialization = build(node.getInitialization());
}
return localDeclaration;
}
@Override
public ASTNode visitMethodDecl(final lombok.ast.MethodDecl node, final Void p) {
MethodDeclaration methodDeclaration = new MethodDeclaration(((CompilationUnitDeclaration) sourceNode.top().get()).compilationResult);
setGeneratedByAndCopyPos(methodDeclaration, source, posHintOf(node));
methodDeclaration.modifiers = modifiersFor(node.getModifiers());
methodDeclaration.returnType = build(node.getReturnType(), TypeReference.class);
methodDeclaration.annotations = toArray(build(node.getAnnotations()), new Annotation[0]);
methodDeclaration.selector = node.getName().toCharArray();
methodDeclaration.thrownExceptions = toArray(build(node.getThrownExceptions()), new TypeReference[0]);
methodDeclaration.typeParameters = toArray(build(node.getTypeParameters()), new TypeParameter[0]);
methodDeclaration.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
methodDeclaration.arguments = toArray(build(node.getArguments()), new Argument[0]);
if (node.isImplementing()) methodDeclaration.modifiers |= AccImplementing;
if (node.noBody() || ((methodDeclaration.modifiers & AccAbstract) != 0)) {
methodDeclaration.modifiers |= AccSemicolonBody;
} else {
methodDeclaration.statements = toArray(build(node.getStatements()), new Statement[0]);
}
methodDeclaration.javadoc = build(node.getJavaDoc());
return methodDeclaration;
}
@Override
public ASTNode visitNameRef(final lombok.ast.NameRef node, final Void p) {
final NameReference nameReference;
if (node.getName().contains(".")) {
char[][] nameTokens = fromQualifiedName(node.getName());
nameReference = new QualifiedNameReference(nameTokens, poss(posHintOf(node), nameTokens.length), 0, 0);
} else {
nameReference = new SingleNameReference(node.getName().toCharArray(), 0);
}
setGeneratedByAndCopyPos(nameReference, source, posHintOf(node));
return nameReference;
}
@Override
public ASTNode visitNew(final lombok.ast.New node, final Void p) {
final AllocationExpression allocationExpression;
if (node.getAnonymousType() != null) {
allocationExpression = new QualifiedAllocationExpression(build(node.getAnonymousType(), TypeDeclaration.class));
} else {
allocationExpression = new AllocationExpression();
}
setGeneratedByAndCopyPos(allocationExpression, source, posHintOf(node));
allocationExpression.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
allocationExpression.type = build(node.getType());
allocationExpression.typeArguments = toArray(build(node.getTypeArgs()), new TypeReference[0]);
allocationExpression.arguments = toArray(build(node.getArgs()), new Expression[0]);
return allocationExpression;
}
@Override
public ASTNode visitNewArray(final lombok.ast.NewArray node, final Void p) {
ArrayAllocationExpression allocationExpression = new ArrayAllocationExpression();
setGeneratedByAndCopyPos(allocationExpression, source, posHintOf(node));
allocationExpression.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
allocationExpression.type = build(node.getType());
final List dims = new ArrayList();
dims.addAll(build(node.getDimensionExpressions(), Expression.class));
allocationExpression.dimensions = toArray(dims, new Expression[0]);
final List initializerExpressions = build(node.getInitializerExpressions(), Expression.class);
if (!initializerExpressions.isEmpty()) {
ArrayInitializer initializer = new ArrayInitializer();
setGeneratedByAndCopyPos(initializer, source, posHintOf(node));
initializer.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
initializer.expressions = initializerExpressions.isEmpty() ? null : toArray(initializerExpressions, new Expression[0]);
allocationExpression.initializer = initializer;
}
return allocationExpression;
}
@Override
public ASTNode visitNullLiteral(final lombok.ast.NullLiteral node, final Void p) {
final MagicLiteral literal = new NullLiteral(0, 0);
setGeneratedByAndCopyPos(literal, source, posHintOf(node));
return literal;
}
@Override
public ASTNode visitNumberLiteral(final lombok.ast.NumberLiteral node, final Void p) {
final NumberLiteral literal;
final Number number = node.getNumber();
if (number instanceof Integer) {
literal = createIntLiteral(Integer.toString(number.intValue()).toCharArray());
} else if (number instanceof Long) {
literal = createLongLiteral((Long.toString(number.longValue()) + "L").toCharArray());
} else if (number instanceof Float) {
literal = new FloatLiteral((Float.toString(number.floatValue()) + "f").toCharArray(), 0, 0);
} else {
literal = new DoubleLiteral((Double.toString(number.doubleValue()) + "d").toCharArray(), 0, 0);
}
setGeneratedByAndCopyPos(literal, source, posHintOf(node));
return literal;
}
private IntLiteral createIntLiteral(final char[] token) {
IntLiteral result;
try {
if (Reflection.intLiteralConstructor != null) {
result = Reflection.intLiteralConstructor.newInstance(token, 0, 0);
} else {
result = (IntLiteral) Reflection.intLiteralFactoryMethod.invoke(null, token, 0, 0);
}
} catch (final Exception e) {
throw new IllegalStateException(e);
}
return result;
}
private LongLiteral createLongLiteral(final char[] token) {
LongLiteral result;
try {
if (Reflection.longLiteralConstructor != null) {
result = Reflection.longLiteralConstructor.newInstance(token, 0, 0);
} else {
result = (LongLiteral) Reflection.longLiteralFactoryMethod.invoke(null, token, 0, 0);
}
} catch (final Exception e) {
throw new IllegalStateException(e);
}
return result;
}
@Override
public ASTNode visitReturn(final lombok.ast.Return node, final Void p) {
final ReturnStatement returnStatement = new ReturnStatement(node.getExpression() == null ? null : build(node.getExpression(), Expression.class), 0, 0);
setGeneratedByAndCopyPos(returnStatement, source, posHintOf(node));
return returnStatement;
}
@Override
public ASTNode visitReturnDefault(final lombok.ast.ReturnDefault node, final Void p) {
lombok.ast.TypeRef returnType = node.upTo(lombok.ast.MethodDecl.class).getReturnType();
if (returnType == null) {
returnType = Type(methodNodeOf(sourceNode).getName());
}
return build(Return(DefaultValue(returnType)));
}
@Override
public ASTNode visitStringLiteral(final lombok.ast.StringLiteral node, final Void p) {
final StringLiteral stringLiteral = new StringLiteral(node.getString().toCharArray(), 0, 0, 1);
setGeneratedByAndCopyPos(stringLiteral, source, posHintOf(node));
return stringLiteral;
}
@Override
public ASTNode visitSwitch(final lombok.ast.Switch node, final Void p) {
final SwitchStatement switchStatement = new SwitchStatement();
switchStatement.expression = build(node.getExpression());
List caseStatements = new ArrayList();
for (lombok.ast.Case caze : node.getCases()) {
final CaseStatement caseStatement = new CaseStatement(caze.getPattern() == null ? null : build(caze.getPattern(), Expression.class), 0, 0);
setGeneratedByAndCopyPos(caseStatement, source, posHintOf(node));
caseStatements.add(caseStatement);
caseStatements.addAll(build(caze.getStatements(), Statement.class));
}
switchStatement.statements = caseStatements.toArray(new Statement[caseStatements.size()]);
return switchStatement;
}
@Override
public ASTNode visitSynchronized(final lombok.ast.Synchronized node, final Void p) {
final Block block = new Block(0);
setGeneratedByAndCopyPos(block, source, posHintOf(node));
block.statements = toArray(build(node.getStatements()), new Statement[0]);
final SynchronizedStatement synchronizedStatemenet = new SynchronizedStatement(build(node.getLock(), Expression.class), block, 0, 0);
setGeneratedByAndCopyPos(synchronizedStatemenet, source, posHintOf(node));
return synchronizedStatemenet;
}
@Override
public ASTNode visitThis(final lombok.ast.This node, final Void p) {
final ThisReference thisReference;
if (node.getType() != null) {
thisReference = new QualifiedThisReference(build(node.getType(), TypeReference.class), 0, 0);
} else {
thisReference = new ThisReference(0, 0);
if (node.isImplicit()) {
thisReference.bits |= ASTNode.IsImplicitThis;
}
}
setGeneratedByAndCopyPos(thisReference, source, posHintOf(node));
return thisReference;
}
@Override
public ASTNode visitThrow(final lombok.ast.Throw node, final Void p) {
final ThrowStatement throwStatement = new ThrowStatement(build(node.getExpression(), Expression.class), 0, 0);
setGeneratedByAndCopyPos(throwStatement, source, posHintOf(node));
return throwStatement;
}
@Override
public ASTNode visitTry(final lombok.ast.Try node, final Void p) {
final TryStatement tryStatement = new TryStatement();
setGeneratedByAndCopyPos(tryStatement, source, posHintOf(node));
tryStatement.tryBlock = build(node.getTryBlock());
tryStatement.catchArguments = toArray(build(node.getCatchArguments()), new Argument[0]);
tryStatement.catchBlocks = toArray(build(node.getCatchBlocks()), new Block[0]);
if (node.getFinallyBlock() != null) {
tryStatement.finallyBlock = build(node.getFinallyBlock());
}
return tryStatement;
}
@Override
public ASTNode visitTypeParam(final lombok.ast.TypeParam node, final Void p) {
final TypeParameter typeParameter = new TypeParameter();
typeParameter.name = node.getName().toCharArray();
final List bounds = new ArrayList(node.getBounds());
if (!bounds.isEmpty()) {
typeParameter.type = build(bounds.get(0));
bounds.remove(0);
typeParameter.bounds = toArray(build(bounds), new TypeReference[0]);
}
setGeneratedByAndCopyPos(typeParameter, source, posHintOf(node));
return typeParameter;
}
@Override
public ASTNode visitTypeRef(final lombok.ast.TypeRef node, final Void p) {
final TypeReference[] paramTypes = build(node.getTypeArgs()).toArray(new TypeReference[0]);
final TypeReference typeReference;
if (node.getTypeName().equals("void")) {
typeReference = new SingleTypeReference(TypeBinding.VOID.simpleName, 0);
} else if (node.getTypeName().contains(".")) {
final char[][] typeNameTokens = fromQualifiedName(node.getTypeName());
long[] poss = new long[typeNameTokens.length];
Arrays.fill(poss, 0);
if (Is.notEmpty(paramTypes)) {
final TypeReference[][] typeArguments = new TypeReference[typeNameTokens.length][];
typeArguments[typeNameTokens.length - 1] = paramTypes;
typeReference = new ParameterizedQualifiedTypeReference(typeNameTokens, typeArguments, 0, poss);
} else {
if (node.getDims() > 0) {
typeReference = new ArrayQualifiedTypeReference(typeNameTokens, node.getDims(), poss);
} else {
typeReference = new QualifiedTypeReference(typeNameTokens, poss);
}
}
} else {
final char[] typeNameToken = node.getTypeName().toCharArray();
if (Is.notEmpty(paramTypes)) {
typeReference = new ParameterizedSingleTypeReference(typeNameToken, paramTypes, 0, 0);
} else {
if (node.getDims() > 0) {
typeReference = new ArrayTypeReference(typeNameToken, node.getDims(), 0);
} else {
typeReference = new SingleTypeReference(typeNameToken, 0);
}
}
}
setGeneratedByAndCopyPos(typeReference, source, posHintOf(node));
if (node.isSuperType()) typeReference.bits |= IsSuperType;
return typeReference;
}
@Override
public ASTNode visitUnary(final lombok.ast.Unary node, final Void p) {
final String operator = node.getOperator();
final int opCode;
if (UNARY_OPERATORS.containsKey(operator)) {
opCode = UNARY_OPERATORS.get(operator);
} else {
throw new IllegalStateException(String.format("Unknown unary operator '%s'", operator));
}
final Expression unaryExpression;
if (Is.oneOf(operator, "++X", "--X")) {
unaryExpression = new PrefixExpression(build(node.getExpression(), Expression.class), IntLiteral.One, opCode, 0);
} else if (Is.oneOf(operator, "X++", "X--")) {
unaryExpression = new PostfixExpression(build(node.getExpression(), Expression.class), IntLiteral.One, opCode, 0);
} else {
unaryExpression = new UnaryExpression(build(node.getExpression(), Expression.class), opCode);
}
setGeneratedByAndCopyPos(unaryExpression, source, posHintOf(node));
return unaryExpression;
}
@Override
public ASTNode visitWhile(final lombok.ast.While node, final Void p) {
final WhileStatement whileStatement = new WhileStatement(build(node.getCondition(), Expression.class), build(node.getAction(), Statement.class), 0, 0);
setGeneratedByAndCopyPos(whileStatement, source, posHintOf(node));
return whileStatement;
}
@Override
public ASTNode visitWildcard(final lombok.ast.Wildcard node, final Void p) {
int kind = Wildcard.UNBOUND;
if (node.getBound() != null) {
switch (node.getBound()) {
case SUPER:
kind = Wildcard.SUPER;
break;
default:
case EXTENDS:
kind = Wildcard.EXTENDS;
}
}
final Wildcard wildcard = new Wildcard(kind);
setGeneratedByAndCopyPos(wildcard, source, posHintOf(node));
wildcard.bound = build(node.getType());
return wildcard;
}
@Override
public ASTNode visitWrappedExpression(final lombok.ast.WrappedExpression node, final Void p) {
Expression expression = (Expression) node.getWrappedObject();
setGeneratedBy(expression, source);
return expression;
}
@Override
public ASTNode visitWrappedMethodDecl(final lombok.ast.WrappedMethodDecl node, final Void p) {
MethodDeclaration methodDeclaration = new MethodDeclaration(((CompilationUnitDeclaration) sourceNode.top().get()).compilationResult);
setGeneratedByAndCopyPos(methodDeclaration, source, posHintOf(node));
MethodBinding abstractMethod = (MethodBinding) node.getWrappedObject();
if (node.getReturnType() == null) {
node.withReturnType(Type(abstractMethod.returnType));
}
if (node.getThrownExceptions().isEmpty()) for (ReferenceBinding thrownException : Each.elementIn(abstractMethod.thrownExceptions)) {
node.withThrownException(Type(thrownException));
}
if (node.getArguments().isEmpty() && Is.notEmpty(abstractMethod.parameters)) for (int i = 0; i < abstractMethod.parameters.length; i++) {
node.withArgument(Arg(Type(abstractMethod.parameters[i]), "arg" + i));
}
if (node.getTypeParameters().isEmpty()) for (TypeVariableBinding binding : Each.elementIn(abstractMethod.typeVariables)) {
ReferenceBinding super1 = binding.superclass;
ReferenceBinding[] super2 = binding.superInterfaces;
lombok.ast.TypeParam typeParameter = TypeParam(As.string(binding.sourceName));
if (super2 == null) super2 = new ReferenceBinding[0];
if (super1 != null || super2.length > 0) {
if (super1 != null) typeParameter.withBound(Type(super1));
for (ReferenceBinding bound : super2) {
typeParameter.withBound(Type(bound).makeSuperType());
}
}
node.withTypeParameter(typeParameter);
}
methodDeclaration.modifiers = (abstractMethod.getAccessFlags() & (~AccAbstract));
methodDeclaration.returnType = build(node.getReturnType(), TypeReference.class);
methodDeclaration.annotations = toArray(build(node.getAnnotations()), new Annotation[0]);
methodDeclaration.selector = abstractMethod.selector;
methodDeclaration.thrownExceptions = toArray(build(node.getThrownExceptions()), new TypeReference[0]);
methodDeclaration.typeParameters = toArray(build(node.getTypeParameters()), new TypeParameter[0]);
methodDeclaration.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
methodDeclaration.arguments = toArray(build(node.getArguments()), new Argument[0]);
if (node.isImplementing()) methodDeclaration.modifiers |= AccImplementing;
if (node.noBody()) {
methodDeclaration.modifiers |= AccSemicolonBody;
} else {
methodDeclaration.statements = toArray(build(node.getStatements()), new Statement[0]);
}
return methodDeclaration;
}
@Override
public ASTNode visitWrappedStatement(final lombok.ast.WrappedStatement node, final Void p) {
Statement statement = (Statement) node.getWrappedObject();
setGeneratedByAndCopyPos(statement, source, posHintOf(node));
return statement;
}
@Override
public ASTNode visitWrappedTypeRef(final lombok.ast.WrappedTypeRef node, final Void p) {
TypeReference typeReference = null;
if (node.getWrappedObject() instanceof TypeBinding) {
typeReference = makeType((TypeBinding) node.getWrappedObject(), source, false);
} else if (node.getWrappedObject() instanceof TypeReference) {
typeReference = copyType((TypeReference) node.getWrappedObject(), source);
}
if (node.getDims() > 0) {
typeReference = typeReference.copyDims(node.getDims());
}
if (node.isSuperType()) typeReference.bits |= IsSuperType;
setGeneratedBy(typeReference, source);
return typeReference;
}
// to support both eclipse 3.6 and eclipse 3.7+
private static final class Reflection {
public static final Constructor castExpressionConstructor;
public static final Constructor intLiteralConstructor;
public static final Constructor longLiteralConstructor;
public static final Method intLiteralFactoryMethod;
public static final Method longLiteralFactoryMethod;
static {
Class>[] parameterTypes = { char[].class, int.class, int.class };
Constructor intLiteralConstructor_ = null;
Constructor longLiteralConstructor_ = null;
Method intLiteralFactoryMethod_ = null;
Method longLiteralFactoryMethod_ = null;
try {
intLiteralConstructor_ = IntLiteral.class.getConstructor(parameterTypes);
longLiteralConstructor_ = LongLiteral.class.getConstructor(parameterTypes);
} catch (final Exception ignore) {
// probably eclipse 3.7+
}
try {
intLiteralFactoryMethod_ = IntLiteral.class.getMethod("buildIntLiteral", parameterTypes);
longLiteralFactoryMethod_ = LongLiteral.class.getMethod("buildLongLiteral", parameterTypes);
} catch (final Exception ignore) {
// probably eclipse versions before 3.7
}
castExpressionConstructor = Cast.uncheckedCast(CastExpression.class.getConstructors()[0]);
intLiteralConstructor = intLiteralConstructor_;
longLiteralConstructor = longLiteralConstructor_;
intLiteralFactoryMethod = intLiteralFactoryMethod_;
longLiteralFactoryMethod = longLiteralFactoryMethod_;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy