/* *******************************************************************
* Copyright (c) 2010 Contributors
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andy Clement - SpringSource
* ******************************************************************/
package org.aspectj.ajdt.internal.compiler;
import org.aspectj.asm.internal.CharOperation;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ArrayReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AssertStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Assignment;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Block;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.BreakStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CaseStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CastExpression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CharLiteral;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.DoubleLiteral;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.FalseLiteral;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.FieldReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.FloatLiteral;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ForStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.IfStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.IntLiteral;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.LongLiteral;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.PostfixExpression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.PrefixExpression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Statement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.StringLiteral;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ThisReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TrueLiteral;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TryStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Wildcard;
import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ParameterizedFieldBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
public class CommonPrinter {
StringBuilder output;
private int tab = 0;
MethodScope mscope;
AbstractMethodDeclaration declaration;
protected int expressionLevel = 0;
public CommonPrinter(MethodScope mscope) {
output = new StringBuilder();
this.mscope = mscope;
}
protected StringBuilder printTypeReference(TypeReference tr) {
if (tr instanceof Wildcard) {
Wildcard w = (Wildcard) tr;
output.append('?');
if (w.bound != null) {
if (w.kind == Wildcard.EXTENDS) {
output.append(" extends ");
} else if (w.kind == Wildcard.SUPER) {
output.append(" super ");
}
printTypeReference(w.bound);
}
return output;
} else if (tr instanceof ParameterizedSingleTypeReference) {
ParameterizedSingleTypeReference pstr = (ParameterizedSingleTypeReference) tr;
ReferenceBinding tb = (ReferenceBinding) mscope.getType(pstr.token);
output.append(CharOperation.concatWith(tb.compoundName, '.'));
output.append('<');
TypeReference[] typeArguments = pstr.typeArguments;
for (int i = 0; i < typeArguments.length; i++) {
if (i > 0) {
output.append(',');
}
printTypeReference(typeArguments[i]);
}
output.append('>');
for (int i = 0; i < pstr.dimensions; i++) {
output.append("[]"); //$NON-NLS-1$
}
return output;
} else if (tr instanceof ParameterizedQualifiedTypeReference) {
ParameterizedQualifiedTypeReference pqtr = (ParameterizedQualifiedTypeReference) tr;
output.append(CharOperation.concatWith(pqtr.tokens, '.'));
output.append('<');
TypeReference[][] typeArguments = pqtr.typeArguments;
// TODO don't support parameterized interim name components
TypeReference[] ofInterest = typeArguments[typeArguments.length - 1];
for (int i = 0; i < ofInterest.length; i++) {
if (i > 0) {
output.append(',');
}
printTypeReference(ofInterest[i]);
}
output.append('>');
for (int i = 0; i < pqtr.dimensions(); i++) {
output.append("[]"); //$NON-NLS-1$
}
return output;
} else if (tr instanceof SingleTypeReference) {
SingleTypeReference str = (SingleTypeReference) tr;
TypeBinding tb = mscope.getType(str.token);
output.append(tb.debugName()); // fq name
for (int i = 0; i < str.dimensions(); i++) {
output.append("[]"); //$NON-NLS-1$
}
return output;
} else if (tr instanceof QualifiedTypeReference) {
QualifiedTypeReference qtr = (QualifiedTypeReference) tr;
output.append(CharOperation.concatWith(qtr.tokens, '.'));
for (int i = 0; i < qtr.dimensions(); i++) {
output.append("[]"); //$NON-NLS-1$
}
return output;
}
throwit(tr);
return output;
}
protected StringBuilder printMemberValuePair(MemberValuePair mvp) {
output.append(mvp.name).append(" = "); //$NON-NLS-1$
printExpression(mvp.value);
return output;
}
protected StringBuilder printAnnotations(Annotation[] annotations) {
int length = annotations.length;
for (int i = 0; i < length; i++) {
printAnnotation(annotations[i]);
output.append(" "); //$NON-NLS-1$
}
return output;
}
public StringBuilder printAnnotation(Annotation annotation) {
output.append('@');
printExpression(annotation.type);
MemberValuePair[] mvps = annotation.memberValuePairs();
if (mvps != null && mvps.length > 0) {
output.append('(');
for (int m = 0; m < mvps.length; m++) {
if (m > 0) {
output.append(',');
}
printMemberValuePair(mvps[m]);
}
output.append(')');
}
return output;
}
public String toString() {
return output.toString();
}
protected StringBuilder printBody(int indent) {
if (declaration.isAbstract()) { // || (md.modifiers & ExtraCompilerModifiers.AccSemicolonBody) != 0) {
return output.append(';');
}
output.append(" {"); //$NON-NLS-1$
if (declaration.statements != null) {
for (int i = 0; i < declaration.statements.length; i++) {
output.append('\n');
printStatement(declaration.statements[i], indent);
}
}
output.append('\n');
printIndent(indent == 0 ? 0 : indent - 1).append('}');
return output;
}
protected StringBuilder printBody(AbstractMethodDeclaration amd, int indent) {
if (amd.isAbstract()) { // || (md.modifiers & ExtraCompilerModifiers.AccSemicolonBody) != 0) {
return output.append(';');
}
output.append(" {"); //$NON-NLS-1$
if (amd.statements != null) {
for (int i = 0; i < amd.statements.length; i++) {
output.append('\n');
printStatement(amd.statements[i], indent);
}
}
output.append('\n');
printIndent(indent == 0 ? 0 : indent - 1).append('}');
return output;
}
protected StringBuilder printArgument(Argument argument) {
// printIndent(indent, output);
printModifiers(argument.modifiers);
if (argument.annotations != null) {
printAnnotations(argument.annotations);
}
printTypeReference(argument.type).append(' ');
return output.append(argument.name);
}
void throwit(Object o) {
if (true) {
System.out.println("so far:" + output.toString());
throw new IllegalStateException(o == null ? "" : o.getClass().getName() + ":" + o);
}
}
void throwit() {
if (true) {
throw new IllegalStateException();
}
}
public StringBuilder printIndent(int indent) {
for (int i = indent; i > 0; i--) {
output.append(" "); //$NON-NLS-1$
}
return output;
}
public StringBuilder printModifiers(int modifiers) {
if ((modifiers & ClassFileConstants.AccPublic) != 0) {
output.append("public "); //$NON-NLS-1$
}
if ((modifiers & ClassFileConstants.AccPrivate) != 0) {
output.append("private "); //$NON-NLS-1$
}
if ((modifiers & ClassFileConstants.AccProtected) != 0) {
output.append("protected "); //$NON-NLS-1$
}
if ((modifiers & ClassFileConstants.AccStatic) != 0) {
output.append("static "); //$NON-NLS-1$
}
if ((modifiers & ClassFileConstants.AccFinal) != 0) {
output.append("final "); //$NON-NLS-1$
}
if ((modifiers & ClassFileConstants.AccSynchronized) != 0) {
output.append("synchronized "); //$NON-NLS-1$
}
if ((modifiers & ClassFileConstants.AccVolatile) != 0) {
output.append("volatile "); //$NON-NLS-1$
}
if ((modifiers & ClassFileConstants.AccTransient) != 0) {
output.append("transient "); //$NON-NLS-1$
}
if ((modifiers & ClassFileConstants.AccNative) != 0) {
output.append("native "); //$NON-NLS-1$
}
if ((modifiers & ClassFileConstants.AccAbstract) != 0) {
output.append("abstract "); //$NON-NLS-1$
}
return output;
}
public StringBuilder printExpression(Expression e) {
// TODO other literals
try {
expressionLevel++;
if (e instanceof TypeReference) {
return printTypeReference((TypeReference) e);
} else if (e instanceof IntLiteral) {
return output.append(((IntLiteral) e).value);
} else if (e instanceof CharLiteral) {
return output.append(((CharLiteral) e).source());
} else if (e instanceof DoubleLiteral) {
return output.append(((DoubleLiteral) e).source());
} else if (e instanceof LongLiteral) {
return output.append(((LongLiteral) e).source());
} else if (e instanceof FloatLiteral) {
return output.append(((FloatLiteral) e).source());
} else if (e instanceof TrueLiteral) {
return output.append(((TrueLiteral) e).source());
} else if (e instanceof FalseLiteral) {
return output.append(((FalseLiteral) e).source());
} else if (e instanceof ClassLiteralAccess) {
printTypeReference(((ClassLiteralAccess) e).type);
return output.append(".class");
} else if (e instanceof StringLiteral) {
return printStringLiteral((StringLiteral) e);
} else if (e instanceof SingleNameReference) {
SingleNameReference snr = (SingleNameReference) e;
if (snr.binding instanceof ReferenceBinding) {
output.append(CharOperation.concatWith(((ReferenceBinding) snr.binding).compoundName, '.'));
} else if (snr.binding instanceof ParameterizedFieldBinding) {
ParameterizedFieldBinding pfb = (ParameterizedFieldBinding) snr.binding;
output.append(pfb.name);
} else if (snr.binding instanceof LocalVariableBinding) {
LocalVariableBinding lvb = (LocalVariableBinding) snr.binding;
output.append(lvb.name);
} else if (snr.binding instanceof FieldBinding) {
FieldBinding fb = (FieldBinding) snr.binding;
ReferenceBinding rb = fb.declaringClass;
if (fb.isStatic()) {
// qualify it
output.append(CharOperation.concatWith(rb.compoundName, '.'));
output.append('.');
output.append(fb.name);
} else {
output.append(snr.token);
}
int stop = 1;
} else {
throwit(snr.binding);
}
return output;
} else if (e instanceof QualifiedNameReference) {
QualifiedNameReference qnr = (QualifiedNameReference) e;
if (qnr.binding instanceof FieldBinding) {
FieldBinding fb = (FieldBinding) qnr.binding;
ReferenceBinding rb = fb.declaringClass;
if (fb.isStatic()) {
output.append(CharOperation.concatWith(rb.compoundName, '.'));
output.append('.');
output.append(fb.name);
} else {
output.append(CharOperation.concatWith(qnr.tokens, '.'));// ((ReferenceBinding) qnr.binding).compoundName,
}
} else if (qnr.binding instanceof ReferenceBinding) {
output.append(CharOperation.concatWith(qnr.tokens, '.'));// ((ReferenceBinding) qnr.binding).compoundName,
// '.'));
} else if (qnr.binding instanceof LocalVariableBinding) {
output.append(CharOperation.concatWith(qnr.tokens, '.'));// oncatWith(((LocalVariableBinding)
// qnr.binding).compoundName, '.'));
// LocalVariableBinding lvb = (LocalVariableBinding) qnr.binding;
// output.append(lvb.name);
} else {
throwit(qnr.binding);
}
// output.append(qnr.actualReceiverType.debugName());
// output.append('.');
// output.append(qnr.tokens[qnr.tokens.length - 1]);
return output;
} else if (e instanceof ArrayReference) {
ArrayReference ar = (ArrayReference) e;
printExpression(ar.receiver).append('[');
return printExpression(ar.position).append(']');
} else if (e instanceof MessageSend) {
return printMessageSendStatement((MessageSend) e);
} else if (e instanceof ThisReference) {
ThisReference tr = (ThisReference) e;
if (tr.isImplicitThis()) {
return output;
}
return output.append("this"); //$NON-NLS-1$
} else if (e instanceof CastExpression) {
return printCastExpression((CastExpression) e);
} else if (e instanceof BinaryExpression) {
if (expressionLevel != 0) {
output.append('(');
}
expressionLevel++;
BinaryExpression be = (BinaryExpression) e;
printExpression(be.left).append(' ').append(be.operatorToString()).append(' ');
printExpression(be.right);
expressionLevel--;
if (expressionLevel != 0) {
output.append(')');
}
return output;
} else if (e instanceof NullLiteral) {
return output.append("null");
} else if (e instanceof QualifiedAllocationExpression) {
return printQualifiedAllocationExpression((QualifiedAllocationExpression) e, 0);
} else if (e instanceof AllocationExpression) {
return printAllocationExpression((AllocationExpression) e);
} else if (e instanceof ArrayInitializer) {
return printArrayInitialized((ArrayInitializer) e);
} else if (e instanceof FieldReference) {
return printFieldReference((FieldReference) e);
} else if (e instanceof UnaryExpression) {
return printUnaryExpression((UnaryExpression) e);
} else if (e instanceof InstanceOfExpression) {
return printInstanceOfExpression((InstanceOfExpression) e);
} else if (e instanceof Assignment) {
return printAssignment((Assignment) e, false);
} else if (e instanceof ArrayAllocationExpression) {
return printArrayAllocationExpression((ArrayAllocationExpression) e);
} else if (e instanceof ConditionalExpression) {
return printConditionalExpression((ConditionalExpression) e);
}
throwit(e);
return output;
} finally {
expressionLevel--;
}
}
private StringBuilder printConditionalExpression(ConditionalExpression e) {
if (expressionLevel != 0) {
output.append('(');
}
expressionLevel++;
printExpression(e.condition).append(" ? ");
printExpression(e.valueIfTrue).append(" : ");
printExpression(e.valueIfFalse);
expressionLevel--;
if (expressionLevel != 0) {
output.append(')');
}
return output;
}
private StringBuilder printArrayAllocationExpression(ArrayAllocationExpression aae) {
output.append("new "); //$NON-NLS-1$
printTypeReference(aae.type);
for (int i = 0; i < aae.dimensions.length; i++) {
if (aae.dimensions[i] == null) {
output.append("[]"); //$NON-NLS-1$
} else {
output.append('[');
printExpression(aae.dimensions[i]);
output.append(']');
}
}
if (aae.initializer != null) {
printExpression(aae.initializer);
}
return output;
}
private StringBuilder printInstanceOfExpression(InstanceOfExpression e) {
if (expressionLevel != 0) {
output.append('(');
}
expressionLevel++;
printExpression(e.expression).append(" instanceof "); //$NON-NLS-1$
printTypeReference(e.type);
expressionLevel--;
if (expressionLevel != 0) {
output.append(')');
}
return output;
}
private StringBuilder printUnaryExpression(UnaryExpression e) {
if (expressionLevel != 0) {
output.append('(');
}
expressionLevel++;
output.append(e.operatorToString()).append(' ');
printExpression(e.expression);
expressionLevel--;
if (expressionLevel != 0) {
output.append(')');
}
return output;
}
private StringBuilder printFieldReference(FieldReference fr) {
printExpression(fr.receiver).append('.').append(fr.token);
return output;
}
private StringBuilder printArrayInitialized(ArrayInitializer e) {
output.append('{');
if (e.expressions != null) {
// int j = 20;
for (int i = 0; i < e.expressions.length; i++) {
if (i > 0) {
output.append(", "); //$NON-NLS-1$
}
printExpression(e.expressions[i]);
// expressions[i].printExpression(0, output);
// j--;
// if (j == 0) {
// output.append('\n');
// printIndent(indent + 1, output);
// j = 20;
// }
}
}
return output.append('}');
}
private StringBuilder printCastExpression(CastExpression e) {
output.append('(');
output.append('(');
printExpression(e.type).append(") "); //$NON-NLS-1$
printExpression(e.expression);
output.append(')');
return output;
}
private StringBuilder printStringLiteral(StringLiteral e) {
output.append('\"');
for (int i = 0; i < e.source().length; i++) {
switch (e.source()[i]) {
case '\b':
output.append("\\b"); //$NON-NLS-1$
break;
case '\t':
output.append("\\t"); //$NON-NLS-1$
break;
case '\n':
output.append("\\n"); //$NON-NLS-1$
break;
case '\f':
output.append("\\f"); //$NON-NLS-1$
break;
case '\r':
output.append("\\r"); //$NON-NLS-1$
break;
case '\"':
output.append("\\\""); //$NON-NLS-1$
break;
case '\'':
output.append("\\'"); //$NON-NLS-1$
break;
case '\\': // take care not to display the escape as a potential real char
output.append("\\\\"); //$NON-NLS-1$
break;
default:
output.append(e.source()[i]);
}
}
output.append('\"');
return output;
}
public StringBuilder printExpression(SingleTypeReference str) {
output.append(str.token);
return output;
}
protected StringBuilder printStatement(Statement statement, int indent) {
return printStatement(statement, indent, true);
}
protected StringBuilder printStatement(Statement statement, int indent, boolean applyIndent) {
if (statement instanceof ReturnStatement) {
printIndent(indent).append("return "); //$NON-NLS-1$
if (((ReturnStatement) statement).expression != null) {
printExpression(((ReturnStatement) statement).expression);
}
return output.append(';');
} else if (statement instanceof PostfixExpression) {
return printPostfixExpression((PostfixExpression) statement);
} else if (statement instanceof PrefixExpression) {
return printPrefixExpression((PrefixExpression) statement);
} else if (statement instanceof MessageSend) {
printIndent(indent);
MessageSend ms = (MessageSend) statement;
printMessageSendStatement(ms);
return output.append(';');
} else if (statement instanceof QualifiedAllocationExpression) {
printIndent(indent);
printQualifiedAllocationExpression((QualifiedAllocationExpression) statement, indent);
return output.append(';');
} else if (statement instanceof Assignment) {
printIndent(indent);
printAssignment((Assignment) statement);
return output.append(';');
} else if (statement instanceof TryStatement) {
printTryStatement((TryStatement) statement, indent);
return output;
} else if (statement instanceof IfStatement) {
printIndent(indent);
IfStatement is = (IfStatement) statement;
printIndent(indent).append("if ("); //$NON-NLS-1$
printExpression(is.condition).append(")\n"); //$NON-NLS-1$
printStatement(is.thenStatement, indent + 2);
if (is.elseStatement != null) {
output.append('\n');
printIndent(indent);
output.append("else\n"); //$NON-NLS-1$
printStatement(is.elseStatement, indent + 2);
}
return output;
} else if (statement instanceof Block) {
printBlock((Block) statement, indent, applyIndent);
return output;
} else if (statement instanceof LocalDeclaration) {
return printLocalDeclaration((LocalDeclaration) statement, indent);
} else if (statement instanceof SwitchStatement) {
return printSwitchStatement((SwitchStatement) statement, indent);
} else if (statement instanceof CaseStatement) {
return printCaseStatement((CaseStatement) statement, indent);
} else if (statement instanceof BreakStatement) {
return printBreakStatement((BreakStatement) statement, indent);
} else if (statement instanceof ThrowStatement) {
return printThrowStatement((ThrowStatement) statement, indent);
} else if (statement instanceof TypeDeclaration) {
return printTypeDeclaration((TypeDeclaration) statement, indent, false).append(';');
} else if (statement instanceof AssertStatement) {
return printAssertStatement((AssertStatement) statement, indent);
} else if (statement instanceof ForStatement) {
return printForStatement((ForStatement) statement, indent);
} else if (statement instanceof ForeachStatement) {
return printForeachStatement((ForeachStatement) statement, indent);
}
System.err.println(statement);
System.err.println(statement.getClass().getName());
throwit(statement);
return output;
}
private StringBuilder printPostfixExpression(PostfixExpression pe) {
printExpression(pe.lhs);
output.append(' ');
output.append(pe.operatorToString());
return output;
}
private StringBuilder printPrefixExpression(PrefixExpression pe) {
output.append(pe.operatorToString());
output.append(' ');
printExpression(pe.lhs);
return output;
}
public StringBuilder printAsExpression(LocalDeclaration ld, int indent) {
// printIndent(indent);
printModifiers(ld.modifiers);
if (ld.annotations != null) {
printAnnotations(ld.annotations);
}
if (ld.type != null) {
printTypeReference(ld.type).append(' ');
}
output.append(ld.name);
switch (ld.getKind()) {
case AbstractVariableDeclaration.ENUM_CONSTANT:
if (ld.initialization != null) {
printExpression(ld.initialization);
}
break;
default:
if (ld.initialization != null) {
output.append(" = "); //$NON-NLS-1$
printExpression(ld.initialization);
}
}
return output;
}
private StringBuilder printForeachStatement(ForeachStatement statement, int indent) {
printIndent(indent).append("for ("); //$NON-NLS-1$
printAsExpression(statement.elementVariable, indent);
output.append(" : ");//$NON-NLS-1$
printExpression(statement.collection).append(") "); //$NON-NLS-1$
// block
if (statement.action == null) {
output.append(';');
} else {
printStatement(statement.action, indent + 1);
}
return output;
}
private StringBuilder printForStatement(ForStatement fs, int indent) {
printIndent(indent).append("for ("); //$NON-NLS-1$
// inits
if (fs.initializations != null) {
for (int i = 0; i < fs.initializations.length; i++) {
// nice only with expressions
if (i > 0) {
output.append(", "); //$NON-NLS-1$
}
printStatement(fs.initializations[i], 0);
}
}
if (!output.toString().endsWith(";")) {
output.append("; "); //$NON-NLS-1$
}
// cond
if (fs.condition != null) {
printExpression(fs.condition);
}
output.append("; "); //$NON-NLS-1$
// updates
if (fs.increments != null) {
for (int i = 0; i < fs.increments.length; i++) {
if (i > 0) {
output.append(", "); //$NON-NLS-1$
}
printStatement(fs.increments[i], 0);
}
}
output.append(") "); //$NON-NLS-1$
// block
if (fs.action == null) {
output.append(';');
} else {
// output.append('\n');
printStatement(fs.action, indent + 1, false);
}
return output;
}
private StringBuilder printAssertStatement(AssertStatement as, int indent) {
printIndent(indent);
output.append("assert "); //$NON-NLS-1$
printExpression(as.assertExpression);
if (as.exceptionArgument != null) {
output.append(": "); //$NON-NLS-1$
printExpression(as.exceptionArgument);
}
return output.append(';');
}
private StringBuilder printThrowStatement(ThrowStatement ts, int indent) {
printIndent(indent).append("throw "); //$NON-NLS-1$
printExpression(ts.exception);
return output.append(';');
}
private StringBuilder printBreakStatement(BreakStatement statement, int indent) {
printIndent(indent).append("break "); //$NON-NLS-1$
if (statement.label != null) {
output.append(statement.label);
}
return output.append(';');
}
private StringBuilder printCaseStatement(CaseStatement statement, int indent) {
printIndent(indent);
if (statement.constantExpression == null) {
output.append("default : "); //$NON-NLS-1$
} else {
output.append("case "); //$NON-NLS-1$
printExpression(statement.constantExpression).append(" : "); //$NON-NLS-1$
}
return output;// output.append(';');
}
private StringBuilder printSwitchStatement(SwitchStatement statement, int indent) {
printIndent(indent).append("switch ("); //$NON-NLS-1$
printExpression(statement.expression).append(") {"); //$NON-NLS-1$
if (statement.statements != null) {
for (int i = 0; i < statement.statements.length; i++) {
output.append('\n');
if (statement.statements[i] instanceof CaseStatement) {
printStatement(statement.statements[i], indent);
} else {
printStatement(statement.statements[i], indent + 2);
}
}
}
output.append("\n"); //$NON-NLS-1$
return printIndent(indent).append('}');
}
private StringBuilder printLocalDeclaration(LocalDeclaration statement, int indent) {
printAbstractVariableDeclarationAsExpression(statement, indent);
switch (statement.getKind()) {
case AbstractVariableDeclaration.ENUM_CONSTANT:
return output.append(',');
default:
return output.append(';');
}
}
private StringBuilder printAbstractVariableDeclarationAsExpression(AbstractVariableDeclaration avd, int indent) {
printIndent(indent);
printModifiers(avd.modifiers);
if (avd.annotations != null) {
printAnnotations(avd.annotations);
}
if (avd.type != null) {
printTypeReference(avd.type).append(' ');
}
output.append(avd.name);
switch (avd.getKind()) {
case AbstractVariableDeclaration.ENUM_CONSTANT:
if (avd.initialization != null) {
printExpression(avd.initialization);
}
break;
default:
if (avd.initialization != null) {
output.append(" = "); //$NON-NLS-1$
printExpression(avd.initialization);
}
}
return output;
}
private StringBuilder printBlock(Block b, int indent, boolean applyIndent) {
if (applyIndent) {
printIndent(indent);
}
output.append("{\n"); //$NON-NLS-1$
printBody(b, indent);
printIndent(indent);
return output.append('}');
}
public StringBuilder printBody(Block b, int indent) {
if (b.statements == null) {
return output;
}
for (int i = 0; i < b.statements.length; i++) {
printStatement(b.statements[i], indent + 1);
output.append('\n');
}
return output;
}
private StringBuilder printTryStatement(TryStatement statement, int indent) {
printIndent(indent).append("try "); //$NON-NLS-1$
printBlock(statement.tryBlock, indent, false);
// catches
if (statement.catchBlocks != null) {
for (int i = 0; i < statement.catchBlocks.length; i++) {
// output.append('\n');
// printIndent(indent).
output.append(" catch ("); //$NON-NLS-1$
printArgument(statement.catchArguments[i]).append(") "); //$NON-NLS-1$
printBlock(statement.catchBlocks[i], indent, false);
// statement.catchBlocks[i].printStatement(indent + 1, output);
}
}
// finally
if (statement.finallyBlock != null) {
// output.append('\n');
// printIndent(indent).
output.append(" finally "); //$NON-NLS-1$
printBlock(statement.finallyBlock, indent, false);// .printStatement(indent + 1, output);
}
return output;
}
private StringBuilder printAssignment(Assignment statement) {
return printAssignment(statement, expressionLevel != 0);
}
private StringBuilder printAssignment(Assignment statement, boolean parens) {
if (parens) {
output.append('(');
}
printExpression(statement.lhs).append(" = ");
printExpression(statement.expression);
if (parens) {
output.append(')');
}
return output;
}
private StringBuilder printMessageSendStatement(MessageSend ms) {
if (!ms.receiver.isImplicitThis()) {
printExpression(ms.receiver).append('.');
}
if (ms.typeArguments != null) {
output.append('<');
int max = ms.typeArguments.length - 1;
for (int j = 0; j < max; j++) {
printTypeReference(ms.typeArguments[j]);
// ms.typeArguments[j].print(0, output);
output.append(", ");//$NON-NLS-1$
}
printTypeReference(ms.typeArguments[max]);
// ms.typeArguments[max].print(0, output);
output.append('>');
}
output.append(ms.selector).append('(');
if (ms.arguments != null) {
for (int i = 0; i < ms.arguments.length; i++) {
if (i > 0) {
output.append(", "); //$NON-NLS-1$
}
printExpression(ms.arguments[i]);
}
}
return output.append(')');
}
protected StringBuilder printQualifiedAllocationExpression(QualifiedAllocationExpression qae, int indent) {
if (qae.enclosingInstance != null) {
printExpression(qae.enclosingInstance).append('.');
}
printAllocationExpression(qae);
if (qae.anonymousType != null) {
printTypeDeclaration(qae.anonymousType, indent, true);
}
return output;
}
protected StringBuilder printTypeDeclaration(TypeDeclaration td, int indent, boolean isAnonymous) {
if (td.javadoc != null) {
throwit(td);
// td.javadoc.print(indent, output);
}
if ((td.bits & ASTNode.IsAnonymousType) == 0) {
printIndent(tab);
printTypeDeclarationHeader(td);
}
printTypeDeclarationBody(td, indent, isAnonymous);
return output;
}
public StringBuilder printTypeDeclarationBody(TypeDeclaration td, int indent, boolean isAnonymous) {
output.append(" {"); //$NON-NLS-1$
if (td.memberTypes != null) {
for (int i = 0; i < td.memberTypes.length; i++) {
if (td.memberTypes[i] != null) {
output.append('\n');
printTypeDeclaration(td.memberTypes[i], indent + 1, false);
}
}
}
if (td.fields != null) {
for (int fieldI = 0; fieldI < td.fields.length; fieldI++) {
if (td.fields[fieldI] != null) {
output.append('\n');
printFieldDeclaration(td.fields[fieldI], indent + 1);
}
}
}
if (td.methods != null) {
for (int i = 0; i < td.methods.length; i++) {
if (td.methods[i] != null) {
AbstractMethodDeclaration amd = td.methods[i];
if (amd instanceof MethodDeclaration) {
output.append('\n');
printMethodDeclaration(((MethodDeclaration) amd), indent + 1);
} else if (amd instanceof ConstructorDeclaration) {
if (!isAnonymous) {
output.append('\n');
// likely to be just a ctor with name 'x' as set in TypeDeclaration.createDefaultConstructorWithBinding
printConstructorDeclaration(((ConstructorDeclaration) amd), indent + 1);
}
} else {
throwit(amd);
}
}
}
}
output.append('\n');
return printIndent(indent).append('}');
}
protected StringBuilder printFieldDeclaration(FieldDeclaration fd, int indent) {
printIndent(indent);
printModifiers(fd.modifiers);
if (fd.annotations != null) {
printAnnotations(fd.annotations);
}
if (fd.type != null) {
printTypeReference(fd.type).append(' ');
}
output.append(fd.name);
switch (fd.getKind()) {
case AbstractVariableDeclaration.ENUM_CONSTANT:
if (fd.initialization != null) {
printExpression(fd.initialization);
}
break;
default:
if (fd.initialization != null) {
output.append(" = "); //$NON-NLS-1$
printExpression(fd.initialization);
}
}
output.append(';');
return output;
}
protected StringBuilder printConstructorDeclaration(ConstructorDeclaration amd, int tab) {
if (amd.javadoc != null) {
throwit();
// amd.javadoc.print(tab, output);
}
printIndent(tab);
if (amd.annotations != null) {
printAnnotations(amd.annotations);
}
printModifiers(amd.modifiers);
TypeParameter[] typeParams = amd.typeParameters();
if (typeParams != null) {
output.append('<');
int max = typeParams.length - 1;
for (int j = 0; j < max; j++) {
printTypeParameter(typeParams[j]);
// typeParams[j].print(0, output);
output.append(", ");//$NON-NLS-1$
}
printTypeParameter(typeParams[max]);
output.append('>');
}
// TODO confirm selector is right name
output.append(amd.selector).append('(');
if (amd.arguments != null) {
for (int i = 0; i < amd.arguments.length; i++) {
if (i > 0) {
output.append(", "); //$NON-NLS-1$
}
printArgument(amd.arguments[i]);
}
}
output.append(')');
if (amd.thrownExceptions != null) {
output.append(" throws "); //$NON-NLS-1$
for (int i = 0; i < amd.thrownExceptions.length; i++) {
if (i > 0) {
output.append(", "); //$NON-NLS-1$
}
throwit();
// this.thrownExceptions[i].print(0, output);
}
}
printBody(amd, tab + 1);
return output;
}
private StringBuilder printMethodDeclaration(MethodDeclaration amd, int tab) {
if (amd.javadoc != null) {
throwit();
// amd.javadoc.print(tab, output);
}
printIndent(tab);
if (amd.annotations != null) {
printAnnotations(amd.annotations);
}
printModifiers(amd.modifiers);
TypeParameter[] typeParams = amd.typeParameters();
if (typeParams != null) {
output.append('<');
int max = typeParams.length - 1;
for (int j = 0; j < max; j++) {
printTypeParameter(typeParams[j]);
// typeParams[j].print(0, output);
output.append(", ");//$NON-NLS-1$
}
printTypeParameter(typeParams[max]);
output.append('>');
}
printReturnType(amd.returnType).append(amd.selector).append('(');
if (amd.arguments != null) {
for (int i = 0; i < amd.arguments.length; i++) {
if (i > 0) {
output.append(", "); //$NON-NLS-1$
}
printArgument(amd.arguments[i]);
}
}
output.append(')');
if (amd.thrownExceptions != null) {
output.append(" throws "); //$NON-NLS-1$
for (int i = 0; i < amd.thrownExceptions.length; i++) {
if (i > 0) {
output.append(", "); //$NON-NLS-1$
}
throwit();
// this.thrownExceptions[i].print(0, output);
}
}
printBody(amd, tab + 1);
return output;
}
public StringBuilder printReturnType(TypeReference tr) {
if (tr == null) {
return output;
}
return printExpression(tr).append(' ');
}
public final static int kind(int flags) {
switch (flags & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) {
case ClassFileConstants.AccInterface:
return TypeDeclaration.INTERFACE_DECL;
case ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation:
return TypeDeclaration.ANNOTATION_TYPE_DECL;
case ClassFileConstants.AccEnum:
return TypeDeclaration.ENUM_DECL;
default:
return TypeDeclaration.CLASS_DECL;
}
}
protected StringBuilder printTypeDeclarationHeader(TypeDeclaration td) {
printModifiers(td.modifiers);
if (td.annotations != null) {
printAnnotations(td.annotations);
}
switch (kind(td.modifiers)) {
case TypeDeclaration.CLASS_DECL:
output.append("class "); //$NON-NLS-1$
break;
case TypeDeclaration.INTERFACE_DECL:
output.append("interface "); //$NON-NLS-1$
break;
case TypeDeclaration.ENUM_DECL:
output.append("enum "); //$NON-NLS-1$
break;
case TypeDeclaration.ANNOTATION_TYPE_DECL:
output.append("@interface "); //$NON-NLS-1$
break;
}
output.append(td.name);
if (td.typeParameters != null) {
output.append("<");//$NON-NLS-1$
for (int i = 0; i < td.typeParameters.length; i++) {
if (i > 0) {
output.append(", "); //$NON-NLS-1$
}
printTypeParameter(td.typeParameters[i]);
// this.typeParameters[i].print(0, output);
}
output.append(">");//$NON-NLS-1$
}
if (td.superclass != null) {
output.append(" extends "); //$NON-NLS-1$
printTypeReference(td.superclass);
}
if (td.superInterfaces != null && td.superInterfaces.length > 0) {
switch (kind(td.modifiers)) {
case TypeDeclaration.CLASS_DECL:
case TypeDeclaration.ENUM_DECL:
output.append(" implements "); //$NON-NLS-1$
break;
case TypeDeclaration.INTERFACE_DECL:
case TypeDeclaration.ANNOTATION_TYPE_DECL:
output.append(" extends "); //$NON-NLS-1$
break;
}
for (int i = 0; i < td.superInterfaces.length; i++) {
if (i > 0) {
output.append(", "); //$NON-NLS-1$
}
printTypeReference(td.superInterfaces[i]);
}
}
return output;
}
protected StringBuilder printTypeParameter(TypeParameter tp) {
output.append(tp.name);
if (tp.type != null) {
output.append(" extends "); //$NON-NLS-1$
printTypeReference(tp.type);
}
if (tp.bounds != null) {
for (int i = 0; i < tp.bounds.length; i++) {
output.append(" & "); //$NON-NLS-1$
printTypeReference(tp.bounds[i]);
}
}
return output;
}
protected StringBuilder printAllocationExpression(AllocationExpression ae) {
if (ae.type != null) { // type null for enum constant initializations
output.append("new "); //$NON-NLS-1$
}
if (ae.typeArguments != null) {
output.append('<');
int max = ae.typeArguments.length - 1;
for (int j = 0; j < max; j++) {
printTypeReference(ae.typeArguments[j]);
output.append(", ");//$NON-NLS-1$
}
printTypeReference(ae.typeArguments[max]);
output.append('>');
}
if (ae.type != null) { // type null for enum constant initializations
printExpression(ae.type);
}
output.append('(');
if (ae.arguments != null) {
for (int i = 0; i < ae.arguments.length; i++) {
if (i > 0) {
output.append(", "); //$NON-NLS-1$
}
printExpression(ae.arguments[i]);
}
}
return output.append(')');
}
}