/******************************************************************************* * Copyright (c) 2002, 2014 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation * Brock Janiczak - Contribution for bug 150741 * Nanda Firdausi - Contribution for bug 298844 * Jesper S Moller - Contribution for bug 402173 * Contribution for bug 402174 * Contribution for bug 402819 * Contribution for bug 402892 * Contribution for bug 403881 *******************************************************************************/ package org.eclipse.jdt.internal.formatter; import java.util.ArrayList; import java.util.Map; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.core.compiler.InvalidInputException; import org.eclipse.jdt.core.formatter.CodeFormatter; import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; import org.eclipse.jdt.internal.compiler.ASTVisitor; 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.AbstractVariableDeclaration; import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration; 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.AssertStatement; 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.ClassLiteralAccess; import org.eclipse.jdt.internal.compiler.ast.Clinit; import org.eclipse.jdt.internal.compiler.ast.CombinedBinaryExpression; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment; import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression; 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.ForStatement; import org.eclipse.jdt.internal.compiler.ast.ForeachStatement; import org.eclipse.jdt.internal.compiler.ast.IfStatement; import org.eclipse.jdt.internal.compiler.ast.ImportReference; 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.IntersectionCastTypeReference; import org.eclipse.jdt.internal.compiler.ast.LabeledStatement; import org.eclipse.jdt.internal.compiler.ast.LambdaExpression; import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; import org.eclipse.jdt.internal.compiler.ast.LongLiteral; 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.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.QualifiedSuperReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.Receiver; 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.StringLiteralConcatenation; import org.eclipse.jdt.internal.compiler.ast.SuperReference; 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.UnionTypeReference; import org.eclipse.jdt.internal.compiler.ast.WhileStatement; import org.eclipse.jdt.internal.compiler.ast.Wildcard; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; import org.eclipse.jdt.internal.compiler.lookup.ClassScope; import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope; import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; import org.eclipse.jdt.internal.compiler.lookup.MethodScope; import org.eclipse.jdt.internal.compiler.parser.Scanner; import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil; import org.eclipse.jdt.internal.formatter.align.Alignment; import org.eclipse.jdt.internal.formatter.align.AlignmentException; import org.eclipse.jface.text.IRegion; import org.eclipse.text.edits.TextEdit; /** * This class is responsible for formatting a valid java source code. * @since 2.1 */ /* <extension id="org.eclipse.jdt.core.newformatter.codeformatter" name="org.eclipse.jdt.core.newformatter.codeformatter" point="org.eclipse.jdt.core.codeFormatter"> <codeFormatter class="org.eclipse.jdt.internal.formatter.CodeFormatterVisitor"> </codeFormatter> </extension> */ @SuppressWarnings({ "rawtypes", "unchecked" }) public class CodeFormatterVisitor extends ASTVisitor { public static class MultiFieldDeclaration extends FieldDeclaration { FieldDeclaration[] declarations; MultiFieldDeclaration(FieldDeclaration[] declarations){ this.declarations = declarations; this.modifiers = declarations[0].modifiers; } } public final static boolean DEBUG = false; private static final int NO_MODIFIERS = 0; /* * Set of expected tokens type for a single type reference. * This array needs to be SORTED. */ private static final int[] SINGLETYPEREFERENCE_EXPECTEDTOKENS = new int[] { TerminalTokens.TokenNameIdentifier, TerminalTokens.TokenNameboolean, TerminalTokens.TokenNamebyte, TerminalTokens.TokenNamechar, TerminalTokens.TokenNamedouble, TerminalTokens.TokenNamefloat, TerminalTokens.TokenNameint, TerminalTokens.TokenNamelong, TerminalTokens.TokenNameshort, TerminalTokens.TokenNamevoid }; private static final int[] CLOSING_GENERICS_EXPECTEDTOKENS = new int[] { TerminalTokens.TokenNameRIGHT_SHIFT, TerminalTokens.TokenNameGREATER, TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT, }; public int lastLocalDeclarationSourceStart; int lastBinaryExpressionAlignmentBreakIndentation; private Scanner localScanner; public DefaultCodeFormatterOptions preferences; public Scribe scribe; // Binary expression positions storage final static long EXPRESSIONS_POS_ENTER_EQUALITY = 1; final static long EXPRESSIONS_POS_ENTER_TWO = 2; final static long EXPRESSIONS_POS_BETWEEN_TWO = 3; final static long EXPRESSIONS_POS_MASK = EXPRESSIONS_POS_BETWEEN_TWO; long expressionsPos; int expressionsDepth = -1; // Array initializers information int arrayInitializersDepth = -1; public CodeFormatterVisitor(DefaultCodeFormatterOptions preferences, Map settings, IRegion[] regions, CodeSnippetParsingUtil codeSnippetParsingUtil, boolean includeComments) { long sourceLevel = settings == null ? ClassFileConstants.JDK1_3 : CompilerOptions.versionToJdkLevel(settings.get(JavaCore.COMPILER_SOURCE)); this.localScanner = new Scanner(true, false, false/*nls*/, sourceLevel/*sourceLevel*/, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/); this.preferences = preferences; this.scribe = new Scribe(this, sourceLevel, regions, codeSnippetParsingUtil, includeComments); } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#acceptProblem(org.eclipse.jdt.core.compiler.IProblem) */ public void acceptProblem(IProblem problem) { super.acceptProblem(problem); } private BinaryExpressionFragmentBuilder buildFragments(BinaryExpression binaryExpression, BlockScope scope) { BinaryExpressionFragmentBuilder builder = new BinaryExpressionFragmentBuilder(); if (binaryExpression instanceof CombinedBinaryExpression) { binaryExpression.traverse(builder, scope); return builder; } switch((binaryExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) { case OperatorIds.MULTIPLY : binaryExpression.left.traverse(builder, scope); builder.operatorsList.add(new Integer(TerminalTokens.TokenNameMULTIPLY)); binaryExpression.right.traverse(builder, scope); break; case OperatorIds.PLUS : binaryExpression.left.traverse(builder, scope); builder.operatorsList.add(new Integer(TerminalTokens.TokenNamePLUS)); binaryExpression.right.traverse(builder, scope); break; case OperatorIds.DIVIDE : binaryExpression.left.traverse(builder, scope); builder.operatorsList.add(new Integer(TerminalTokens.TokenNameDIVIDE)); binaryExpression.right.traverse(builder, scope); break; case OperatorIds.REMAINDER : binaryExpression.left.traverse(builder, scope); builder.operatorsList.add(new Integer(TerminalTokens.TokenNameREMAINDER)); binaryExpression.right.traverse(builder, scope); break; case OperatorIds.XOR : binaryExpression.left.traverse(builder, scope); builder.operatorsList.add(new Integer(TerminalTokens.TokenNameXOR)); binaryExpression.right.traverse(builder, scope); break; case OperatorIds.MINUS : binaryExpression.left.traverse(builder, scope); builder.operatorsList.add(new Integer(TerminalTokens.TokenNameMINUS)); binaryExpression.right.traverse(builder, scope); break; case OperatorIds.OR : binaryExpression.left.traverse(builder, scope); builder.operatorsList.add(new Integer(TerminalTokens.TokenNameOR)); binaryExpression.right.traverse(builder, scope); break; case OperatorIds.AND : binaryExpression.left.traverse(builder, scope); builder.operatorsList.add(new Integer(TerminalTokens.TokenNameAND)); binaryExpression.right.traverse(builder, scope); break; case OperatorIds.AND_AND : binaryExpression.left.traverse(builder, scope); builder.operatorsList.add(new Integer(TerminalTokens.TokenNameAND_AND)); binaryExpression.right.traverse(builder, scope); break; case OperatorIds.OR_OR : binaryExpression.left.traverse(builder, scope); builder.operatorsList.add(new Integer(TerminalTokens.TokenNameOR_OR)); binaryExpression.right.traverse(builder, scope); break; } return builder; } private CascadingMethodInvocationFragmentBuilder buildFragments(MessageSend messageSend, BlockScope scope) { CascadingMethodInvocationFragmentBuilder builder = new CascadingMethodInvocationFragmentBuilder(); messageSend.traverse(builder, scope); return builder; } private boolean commentStartsBlock(int start, int end) { this.localScanner.resetTo(start, end); try { if (this.localScanner.getNextToken() == TerminalTokens.TokenNameLBRACE) { switch(this.localScanner.getNextToken()) { case TerminalTokens.TokenNameCOMMENT_BLOCK : case TerminalTokens.TokenNameCOMMENT_JAVADOC : case TerminalTokens.TokenNameCOMMENT_LINE : return true; } } } catch(InvalidInputException e) { // ignore } return false; } private ASTNode[] computeMergedMemberDeclarations(ASTNode[] nodes){ ArrayList mergedNodes = new ArrayList(); for (int i = 0, max = nodes.length; i < max; i++) { ASTNode currentNode = nodes[i]; if (currentNode instanceof FieldDeclaration) { FieldDeclaration currentField = (FieldDeclaration) currentNode; if (mergedNodes.size() == 0) { // first node mergedNodes.add(currentNode); } else { // we need to check if the previous merged node is a field declaration ASTNode previousMergedNode = (ASTNode) mergedNodes.get(mergedNodes.size() - 1); if (previousMergedNode instanceof MultiFieldDeclaration) { // we merge the current node MultiFieldDeclaration multiFieldDeclaration = (MultiFieldDeclaration) previousMergedNode; int length = multiFieldDeclaration.declarations.length; System.arraycopy(multiFieldDeclaration.declarations, 0, multiFieldDeclaration.declarations= new FieldDeclaration[length+1], 0, length); multiFieldDeclaration.declarations[length] = currentField; } else if (previousMergedNode instanceof FieldDeclaration) { // need to check we need to create a multiple field declaration final FieldDeclaration previousFieldDeclaration = (FieldDeclaration)previousMergedNode; if (currentField.declarationSourceStart == previousFieldDeclaration.declarationSourceStart) { // we create a multi field declaration final MultiFieldDeclaration multiFieldDeclaration = new MultiFieldDeclaration(new FieldDeclaration[]{ previousFieldDeclaration, currentField}); multiFieldDeclaration.annotations = previousFieldDeclaration.annotations; mergedNodes.set(mergedNodes.size() - 1, multiFieldDeclaration); } else { mergedNodes.add(currentNode); } } else { mergedNodes.add(currentNode); } } } else { mergedNodes.add(currentNode); } } if (mergedNodes.size() != nodes.length) { ASTNode[] result = new ASTNode[mergedNodes.size()]; mergedNodes.toArray(result); return result; } else { return nodes; } } private ASTNode[] computeMergedMemberDeclarations(TypeDeclaration typeDeclaration){ int fieldIndex = 0, fieldCount = (typeDeclaration.fields == null) ? 0 : typeDeclaration.fields.length; FieldDeclaration field = fieldCount == 0 ? null : typeDeclaration.fields[fieldIndex]; int fieldStart = field == null ? Integer.MAX_VALUE : field.declarationSourceStart; int methodIndex = 0, methodCount = (typeDeclaration.methods == null) ? 0 : typeDeclaration.methods.length; AbstractMethodDeclaration method = methodCount == 0 ? null : typeDeclaration.methods[methodIndex]; int methodStart = method == null ? Integer.MAX_VALUE : method.declarationSourceStart; int typeIndex = 0, typeCount = (typeDeclaration.memberTypes == null) ? 0 : typeDeclaration.memberTypes.length; TypeDeclaration type = typeCount == 0 ? null : typeDeclaration.memberTypes[typeIndex]; int typeStart = type == null ? Integer.MAX_VALUE : type.declarationSourceStart; final int memberLength = fieldCount+methodCount+typeCount; ASTNode[] members = new ASTNode[memberLength]; if (memberLength != 0) { int index = 0; int previousFieldStart = -1; do { if (fieldStart < methodStart && fieldStart < typeStart) { if (field.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) { // filter out enum constants previousFieldStart = fieldStart; if (++fieldIndex < fieldCount) { // find next field if any fieldStart = (field = typeDeclaration.fields[fieldIndex]).declarationSourceStart; } else { fieldStart = Integer.MAX_VALUE; } continue; } // next member is a field if (fieldStart == previousFieldStart){ ASTNode previousMember = members[index - 1]; if (previousMember instanceof MultiFieldDeclaration) { MultiFieldDeclaration multiField = (MultiFieldDeclaration) previousMember; int length = multiField.declarations.length; System.arraycopy(multiField.declarations, 0, multiField.declarations=new FieldDeclaration[length+1], 0, length); multiField.declarations[length] = field; } else { FieldDeclaration fieldDeclaration = (FieldDeclaration)previousMember; final MultiFieldDeclaration multiFieldDeclaration = new MultiFieldDeclaration(new FieldDeclaration[]{ fieldDeclaration, field}); multiFieldDeclaration.annotations = fieldDeclaration.annotations; members[index - 1] = multiFieldDeclaration; } } else { members[index++] = field; } previousFieldStart = fieldStart; if (++fieldIndex < fieldCount) { // find next field if any fieldStart = (field = typeDeclaration.fields[fieldIndex]).declarationSourceStart; } else { fieldStart = Integer.MAX_VALUE; } } else if (methodStart < fieldStart && methodStart < typeStart) { // next member is a method if (!method.isDefaultConstructor() && !method.isClinit()) { members[index++] = method; } if (++methodIndex < methodCount) { // find next method if any methodStart = (method = typeDeclaration.methods[methodIndex]).declarationSourceStart; } else { methodStart = Integer.MAX_VALUE; } } else { // next member is a type members[index++] = type; if (++typeIndex < typeCount) { // find next type if any typeStart = (type = typeDeclaration.memberTypes[typeIndex]).declarationSourceStart; } else { typeStart = Integer.MAX_VALUE; } } } while ((fieldIndex < fieldCount) || (typeIndex < typeCount) || (methodIndex < methodCount)); if (members.length != index) { System.arraycopy(members, 0, members=new ASTNode[index], 0, index); } } return members; } private boolean dumpBinaryExpression( BinaryExpression binaryExpression, int operator, BlockScope scope) { final int numberOfParens = (binaryExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(binaryExpression, numberOfParens); } BinaryExpressionFragmentBuilder builder = buildFragments(binaryExpression, scope); final int fragmentsSize = builder.size(); if (this.expressionsDepth < 0) { this.expressionsDepth = 0; } else { this.expressionsDepth++; this.expressionsPos <<= 2; } try { this.lastBinaryExpressionAlignmentBreakIndentation = 0; if ((builder.realFragmentsSize() > 1 || fragmentsSize > 4) && numberOfParens == 0) { int scribeLine = this.scribe.line; this.scribe.printComment(); Alignment binaryExpressionAlignment = this.scribe.createAlignment( Alignment.BINARY_EXPRESSION, this.preferences.alignment_for_binary_expression, Alignment.R_OUTERMOST, fragmentsSize, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(binaryExpressionAlignment); boolean ok = false; ASTNode[] fragments = builder.fragments(); int[] operators = builder.operators(); do { try { final int max = fragmentsSize - 1; for (int i = 0; i < max; i++) { ASTNode fragment = fragments[i]; fragment.traverse(this, scope); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (this.scribe.lastNumberOfNewLines == 1) { // a new line has been inserted while printing the comment // hence we need to use the break indentation level before printing next token... this.scribe.indentationLevel = binaryExpressionAlignment.breakIndentationLevel; } if (this.preferences.wrap_before_binary_operator) { this.scribe.alignFragment(binaryExpressionAlignment, i); this.scribe.printNextToken(operators[i], this.preferences.insert_space_before_binary_operator); } else { this.scribe.printNextToken(operators[i], this.preferences.insert_space_before_binary_operator); this.scribe.alignFragment(binaryExpressionAlignment, i); } switch(operators[i]) { case TerminalTokens.TokenNameMINUS : if (isNextToken(TerminalTokens.TokenNameMINUS) || isNextToken(TerminalTokens.TokenNameMINUS_MINUS)) { // the next character is a '-' or '--' (unary operator) this.scribe.space(); } break; case TerminalTokens.TokenNamePLUS : if (isNextToken(TerminalTokens.TokenNamePLUS) || isNextToken(TerminalTokens.TokenNamePLUS_PLUS)) { // the next character is a + or ++ (unary operator) this.scribe.space(); } } if (this.preferences.insert_space_after_binary_operator) { this.scribe.space(); } } fragments[max].traverse(this, scope); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); ok = true; } catch(AlignmentException e){ this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(binaryExpressionAlignment, true); if (this.scribe.line == scribeLine) { // The expression was not broken => reset last break indentation this.lastBinaryExpressionAlignmentBreakIndentation = 0; } else { this.lastBinaryExpressionAlignmentBreakIndentation = binaryExpressionAlignment.breakIndentationLevel; } } else { this.expressionsPos |= EXPRESSIONS_POS_ENTER_TWO; binaryExpression.left.traverse(this, scope); this.expressionsPos &= ~EXPRESSIONS_POS_MASK; this.expressionsPos |= EXPRESSIONS_POS_BETWEEN_TWO; this.scribe.printNextToken(operator, this.preferences.insert_space_before_binary_operator, Scribe.PRESERVE_EMPTY_LINES_IN_BINARY_EXPRESSION); if (operator == TerminalTokens.TokenNameMINUS && isNextToken(TerminalTokens.TokenNameMINUS)) { // the next character is a minus (unary operator) this.scribe.space(); } if (this.preferences.insert_space_after_binary_operator) { this.scribe.space(); } binaryExpression.right.traverse(this, scope); } } finally { this.expressionsDepth--; this.expressionsPos >>= 2; if (this.expressionsDepth < 0) { this.lastBinaryExpressionAlignmentBreakIndentation = 0; } } if (numberOfParens > 0) { manageClosingParenthesizedExpression(binaryExpression, numberOfParens); } return false; } private boolean dumpEqualityExpression( BinaryExpression binaryExpression, int operator, BlockScope scope) { final int numberOfParens = (binaryExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(binaryExpression, numberOfParens); } if (this.expressionsDepth < 0) { this.expressionsDepth = 0; } else { this.expressionsDepth++; this.expressionsPos <<= 2; } try { this.expressionsPos |= EXPRESSIONS_POS_ENTER_EQUALITY; binaryExpression.left.traverse(this, scope); this.scribe.printNextToken(operator, this.preferences.insert_space_before_binary_operator, Scribe.PRESERVE_EMPTY_LINES_IN_EQUALITY_EXPRESSION); if (this.preferences.insert_space_after_binary_operator) { this.scribe.space(); } binaryExpression.right.traverse(this, scope); } finally { this.expressionsDepth--; this.expressionsPos >>= 2; } if (numberOfParens > 0) { manageClosingParenthesizedExpression(binaryExpression, numberOfParens); } return false; } private final TextEdit failedToFormat() { if (DEBUG) { System.out.println("COULD NOT FORMAT \n" + this.scribe.scanner); //$NON-NLS-1$ System.out.println(this.scribe); } return null; } private void format( AbstractMethodDeclaration methodDeclaration, ClassScope scope, boolean isChunkStart, boolean isFirstClassBodyDeclaration) { if (isFirstClassBodyDeclaration) { int newLinesBeforeFirstClassBodyDeclaration = this.preferences.blank_lines_before_first_class_body_declaration; if (newLinesBeforeFirstClassBodyDeclaration > 0) { this.scribe.printEmptyLines(newLinesBeforeFirstClassBodyDeclaration); } } else { final int newLineBeforeChunk = isChunkStart ? this.preferences.blank_lines_before_new_chunk : 0; if (newLineBeforeChunk > 0) { this.scribe.printEmptyLines(newLineBeforeChunk); } } final int newLinesBeforeMethod = this.preferences.blank_lines_before_method; if (newLinesBeforeMethod > 0 && !isFirstClassBodyDeclaration) { this.scribe.printEmptyLines(newLinesBeforeMethod); } else if (this.scribe.line != 0 || this.scribe.column != 1) { this.scribe.printNewLine(); } methodDeclaration.traverse(this, scope); } private void format(FieldDeclaration fieldDeclaration, ASTVisitor visitor, MethodScope scope, boolean isChunkStart, boolean isFirstClassBodyDeclaration) { if (isFirstClassBodyDeclaration) { int newLinesBeforeFirstClassBodyDeclaration = this.preferences.blank_lines_before_first_class_body_declaration; if (newLinesBeforeFirstClassBodyDeclaration > 0) { this.scribe.printEmptyLines(newLinesBeforeFirstClassBodyDeclaration); } } else { int newLineBeforeChunk = isChunkStart ? this.preferences.blank_lines_before_new_chunk : 0; if (newLineBeforeChunk > 0) { this.scribe.printEmptyLines(newLineBeforeChunk); } final int newLinesBeforeField = this.preferences.blank_lines_before_field; if (newLinesBeforeField > 0) { this.scribe.printEmptyLines(newLinesBeforeField); } } Alignment memberAlignment = this.scribe.getMemberAlignment(); this.scribe.printComment(); this.scribe.printModifiers(fieldDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_FIELD); this.scribe.space(); /* * Field type */ fieldDeclaration.type.traverse(this, scope); /* * Field name */ this.scribe.alignFragment(memberAlignment, 0); this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true); formatExtraDimensions(fieldDeclaration.type); /* * Field initialization */ final Expression initialization = fieldDeclaration.initialization; if (initialization != null) { this.scribe.alignFragment(memberAlignment, 1); this.scribe.printNextToken(TerminalTokens.TokenNameEQUAL, this.preferences.insert_space_before_assignment_operator); if (this.preferences.insert_space_after_assignment_operator) { this.scribe.space(); } Alignment assignmentAlignment = this.scribe.createAlignment( Alignment.FIELD_DECLARATION_ASSIGNMENT, this.preferences.alignment_for_assignment, Alignment.R_INNERMOST, 1, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(assignmentAlignment); boolean ok = false; do { try { this.scribe.alignFragment(assignmentAlignment, 0); initialization.traverse(this, scope); ok = true; } catch(AlignmentException e){ this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(assignmentAlignment, true); } this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); if (memberAlignment != null) { this.scribe.alignFragment(memberAlignment, 2); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } else { this.scribe.space(); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } } private void formatExtraDimensions(TypeReference typeReference) { /* * Check for extra dimensions */ int extraDimensions = getDimensions(); if (extraDimensions != 0) { int anchor = typeReference != null ? (typeReference.dimensions() - extraDimensions) : 0; formatDimensions(typeReference, anchor, extraDimensions); } } private void formatLeadingDimensions(TypeReference typeReference) { int leadingDimensions = Math.min(getDimensions(), typeReference != null ? typeReference.dimensions() : 0); if (leadingDimensions != 0) formatDimensions(typeReference, 0, leadingDimensions); } private void formatDimensions(TypeReference typeReference, int anchor, int count) { if (count != 0) { if (this.preferences.insert_space_before_opening_bracket_in_array_type_reference) { this.scribe.space(); } Annotation[][] annotationsOnDimensions = typeReference != null ? typeReference.getAnnotationsOnDimensions(true) : null; for (int i = 0; i < count; i++) { int dimensionIndex = anchor + i; if (annotationsOnDimensions != null && annotationsOnDimensions.length > dimensionIndex) { boolean hadAnnotations = formatInlineAnnotations(annotationsOnDimensions[dimensionIndex], true); if (hadAnnotations && this.preferences.insert_space_before_opening_bracket_in_array_type_reference) this.scribe.space(); } this.scribe.printNextToken(TerminalTokens.TokenNameLBRACKET); if (this.preferences.insert_space_between_brackets_in_array_type_reference) { this.scribe.space(); } this.scribe.printNextToken(TerminalTokens.TokenNameRBRACKET); } } } private void format(ImportReference importRef, boolean isLast) { this.scribe.printNextToken(TerminalTokens.TokenNameimport); if (!isLast) this.scribe.blank_lines_between_import_groups = this.preferences.blank_lines_between_import_groups; this.scribe.space(); if (importRef.isStatic()) { this.scribe.printNextToken(TerminalTokens.TokenNamestatic); this.scribe.space(); } if ((importRef.bits & ASTNode.OnDemand) != 0) { this.scribe.printQualifiedReference(importRef.sourceEnd, false/*do not expect parenthesis*/); this.scribe.printNextToken(TerminalTokens.TokenNameDOT); this.scribe.printNextToken(TerminalTokens.TokenNameMULTIPLY); this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); } else { this.scribe.printQualifiedReference(importRef.sourceEnd, false/*do not expect parenthesis*/); this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); } if (isLast) { this.scribe.blank_lines_between_import_groups = -1; this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.IMPORT_TRAILING_COMMENT); } else { this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.NO_TRAILING_COMMENT); this.scribe.blank_lines_between_import_groups = -1; } this.scribe.printNewLine(); } private void format(MultiFieldDeclaration multiFieldDeclaration, ASTVisitor visitor, MethodScope scope, boolean isChunkStart, boolean isFirstClassBodyDeclaration) { if (isFirstClassBodyDeclaration) { int newLinesBeforeFirstClassBodyDeclaration = this.preferences.blank_lines_before_first_class_body_declaration; if (newLinesBeforeFirstClassBodyDeclaration > 0) { this.scribe.printEmptyLines(newLinesBeforeFirstClassBodyDeclaration); } } else { int newLineBeforeChunk = isChunkStart ? this.preferences.blank_lines_before_new_chunk : 0; if (newLineBeforeChunk > 0) { this.scribe.printEmptyLines(newLineBeforeChunk); } final int newLinesBeforeField = this.preferences.blank_lines_before_field; if (newLinesBeforeField > 0) { this.scribe.printEmptyLines(newLinesBeforeField); } } Alignment fieldAlignment = this.scribe.getMemberAlignment(); this.scribe.printComment(); this.scribe.printModifiers(multiFieldDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_FIELD); this.scribe.space(); multiFieldDeclaration.declarations[0].type.traverse(this, scope); final int multipleFieldDeclarationsLength = multiFieldDeclaration.declarations.length; Alignment multiFieldDeclarationsAlignment =this.scribe.createAlignment( Alignment.MULTIPLE_FIELD, this.preferences.alignment_for_multiple_fields, multipleFieldDeclarationsLength - 1, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(multiFieldDeclarationsAlignment); boolean ok = false; do { try { for (int i = 0, length = multipleFieldDeclarationsLength; i < length; i++) { FieldDeclaration fieldDeclaration = multiFieldDeclaration.declarations[i]; /* * Field name */ if (i == 0) { this.scribe.alignFragment(fieldAlignment, 0); this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true); } else { this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, false); } formatExtraDimensions(fieldDeclaration.type); /* * Field initialization */ final Expression initialization = fieldDeclaration.initialization; if (initialization != null) { if (i == 0) { this.scribe.alignFragment(fieldAlignment, 1); } this.scribe.printNextToken(TerminalTokens.TokenNameEQUAL, this.preferences.insert_space_before_assignment_operator); if (this.preferences.insert_space_after_assignment_operator) { this.scribe.space(); } initialization.traverse(this, scope); } if (i != length - 1) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_multiple_field_declarations); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); this.scribe.alignFragment(multiFieldDeclarationsAlignment, i); if (this.preferences.insert_space_after_comma_in_multiple_field_declarations) { this.scribe.space(); } } else { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.alignFragment(fieldAlignment, 2); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(multiFieldDeclarationsAlignment, true); } /** * @see org.eclipse.jdt.core.formatter.CodeFormatter#format(int, String, int, int, int, String) */ public TextEdit format(String string, ASTNode[] nodes) { // reset the scribe this.scribe.reset(); long startTime = 0; if (DEBUG) { startTime = System.currentTimeMillis(); } final char[] compilationUnitSource = string.toCharArray(); this.localScanner.setSource(compilationUnitSource); this.scribe.resetScanner(compilationUnitSource); if (nodes == null) { return null; } this.lastLocalDeclarationSourceStart = -1; try { formatClassBodyDeclarations(nodes); } catch(AbortFormatting e){ return failedToFormat(); } if (DEBUG){ System.out.println("Formatting time: " + (System.currentTimeMillis() - startTime)); //$NON-NLS-1$ } return this.scribe.getRootEdit(); } /** * @see org.eclipse.jdt.core.formatter.CodeFormatter#format(int, String, int, int, int, String) */ public TextEdit format(String string, CompilationUnitDeclaration compilationUnitDeclaration) { // reset the scribe this.scribe.reset(); if (compilationUnitDeclaration == null || compilationUnitDeclaration.ignoreFurtherInvestigation) { return failedToFormat(); } long startTime = 0; if (DEBUG) { startTime = System.currentTimeMillis(); } final char[] compilationUnitSource = string.toCharArray(); this.localScanner.setSource(compilationUnitSource); this.scribe.resetScanner(compilationUnitSource); this.lastLocalDeclarationSourceStart = -1; try { compilationUnitDeclaration.traverse(this, compilationUnitDeclaration.scope); } catch(AbortFormatting e){ return failedToFormat(); } if (DEBUG){ System.out.println("Formatting time: " + (System.currentTimeMillis() - startTime)); //$NON-NLS-1$ } return this.scribe.getRootEdit(); } /** * @see org.eclipse.jdt.core.formatter.CodeFormatter#format(int, String, int, int, int, String) */ public TextEdit format(String string, ConstructorDeclaration constructorDeclaration) { // reset the scribe this.scribe.reset(); long startTime = 0; if (DEBUG) { startTime = System.currentTimeMillis(); } final char[] compilationUnitSource = string.toCharArray(); this.localScanner.setSource(compilationUnitSource); this.scribe.resetScanner(compilationUnitSource); if (constructorDeclaration == null) { return null; } this.lastLocalDeclarationSourceStart = -1; try { ExplicitConstructorCall explicitConstructorCall = constructorDeclaration.constructorCall; if (explicitConstructorCall != null && !explicitConstructorCall.isImplicitSuper()) { explicitConstructorCall.traverse(this, null); } Statement[] statements = constructorDeclaration.statements; if (statements != null) { formatStatements(null, statements, false); } if (hasComments()) { this.scribe.printNewLine(); } this.scribe.printComment(); } catch(AbortFormatting e){ return failedToFormat(); } if (DEBUG){ System.out.println("Formatting time: " + (System.currentTimeMillis() - startTime)); //$NON-NLS-1$ } return this.scribe.getRootEdit(); } /** * @see org.eclipse.jdt.core.formatter.CodeFormatter#format(int, String, int, int, int, String) */ public TextEdit format(String string, Expression expression) { // reset the scribe this.scribe.reset(); long startTime = 0; if (DEBUG) { startTime = System.currentTimeMillis(); } final char[] compilationUnitSource = string.toCharArray(); this.localScanner.setSource(compilationUnitSource); this.scribe.resetScanner(compilationUnitSource); if (expression == null) { return null; } this.lastLocalDeclarationSourceStart = -1; try { expression.traverse(this, (BlockScope) null); this.scribe.printComment(); } catch(AbortFormatting e){ return failedToFormat(); } if (DEBUG){ System.out.println("Formatting time: " + (System.currentTimeMillis() - startTime)); //$NON-NLS-1$ } return this.scribe.getRootEdit(); } /** * @param source the source of the comment to format */ public void formatComment(int kind, String source, int start, int end, int indentationLevel) { if (source == null) return; this.scribe.printComment(kind, source, start, end, indentationLevel); } private void format(TypeDeclaration typeDeclaration){ /* * Print comments to get proper line number */ this.scribe.printComment(); int line = this.scribe.line; this.scribe.printModifiers(typeDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_TYPE); if (this.scribe.line > line) { // annotations introduced new line, but this is not a line wrapping // see 158267 line = this.scribe.line; } /* * Type name */ switch(TypeDeclaration.kind(typeDeclaration.modifiers)) { case TypeDeclaration.CLASS_DECL : this.scribe.printNextToken(TerminalTokens.TokenNameclass, true); break; case TypeDeclaration.INTERFACE_DECL : this.scribe.printNextToken(TerminalTokens.TokenNameinterface, true); break; case TypeDeclaration.ENUM_DECL : this.scribe.printNextToken(TerminalTokens.TokenNameenum, true); break; case TypeDeclaration.ANNOTATION_TYPE_DECL : this.scribe.printNextToken(TerminalTokens.TokenNameAT, this.preferences.insert_space_before_at_in_annotation_type_declaration); this.scribe.printNextToken(TerminalTokens.TokenNameinterface, this.preferences.insert_space_after_at_in_annotation_type_declaration); break; } this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true); TypeParameter[] typeParameters = typeDeclaration.typeParameters; if (typeParameters != null) { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_parameters); if (this.preferences.insert_space_after_opening_angle_bracket_in_type_parameters) { this.scribe.space(); } int length = typeParameters.length; for (int i = 0; i < length - 1; i++) { typeParameters[i].traverse(this, typeDeclaration.scope); this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_parameters); if (this.preferences.insert_space_after_comma_in_type_parameters) { this.scribe.space(); } } typeParameters[length - 1].traverse(this, typeDeclaration.scope); if (isClosingGenericToken()) { this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_parameters); } if (this.preferences.insert_space_after_closing_angle_bracket_in_type_parameters) { this.scribe.space(); } } /* * Superclass */ final TypeReference superclass = typeDeclaration.superclass; if (superclass != null) { Alignment superclassAlignment =this.scribe.createAlignment( Alignment.SUPER_CLASS, this.preferences.alignment_for_superclass_in_type_declaration, 2, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(superclassAlignment); boolean ok = false; do { try { this.scribe.alignFragment(superclassAlignment, 0); this.scribe.printNextToken(TerminalTokens.TokenNameextends, true); this.scribe.alignFragment(superclassAlignment, 1); this.scribe.space(); superclass.traverse(this, typeDeclaration.scope); ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(superclassAlignment, true); } /* * Super Interfaces */ final TypeReference[] superInterfaces = typeDeclaration.superInterfaces; if (superInterfaces != null) { int alignment_for_superinterfaces; int kind = TypeDeclaration.kind(typeDeclaration.modifiers); switch(kind) { case TypeDeclaration.ENUM_DECL : alignment_for_superinterfaces = this.preferences.alignment_for_superinterfaces_in_enum_declaration; break; default: alignment_for_superinterfaces = this.preferences.alignment_for_superinterfaces_in_type_declaration; break; } int superInterfaceLength = superInterfaces.length; Alignment interfaceAlignment =this.scribe.createAlignment( Alignment.SUPER_INTERFACES, alignment_for_superinterfaces, superInterfaceLength+1, // implements token is first fragment this.scribe.scanner.currentPosition); this.scribe.enterAlignment(interfaceAlignment); boolean ok = false; do { try { this.scribe.alignFragment(interfaceAlignment, 0); if (kind == TypeDeclaration.INTERFACE_DECL) { this.scribe.printNextToken(TerminalTokens.TokenNameextends, true); } else { this.scribe.printNextToken(TerminalTokens.TokenNameimplements, true); } for (int i = 0; i < superInterfaceLength; i++) { if (i > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_superinterfaces); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); this.scribe.alignFragment(interfaceAlignment, i+1); if (this.preferences.insert_space_after_comma_in_superinterfaces) { this.scribe.space(); } superInterfaces[i].traverse(this, typeDeclaration.scope); } else { this.scribe.alignFragment(interfaceAlignment, i+1); this.scribe.space(); superInterfaces[i].traverse(this, typeDeclaration.scope); } } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(interfaceAlignment, true); } /* * Type body */ String class_declaration_brace; boolean space_before_opening_brace; int kind = TypeDeclaration.kind(typeDeclaration.modifiers); switch(kind) { case TypeDeclaration.ENUM_DECL : class_declaration_brace = this.preferences.brace_position_for_enum_declaration; space_before_opening_brace = this.preferences.insert_space_before_opening_brace_in_enum_declaration; break; case TypeDeclaration.ANNOTATION_TYPE_DECL : class_declaration_brace = this.preferences.brace_position_for_annotation_type_declaration; space_before_opening_brace = this.preferences.insert_space_before_opening_brace_in_annotation_type_declaration; break; default: class_declaration_brace = this.preferences.brace_position_for_type_declaration; space_before_opening_brace = this.preferences.insert_space_before_opening_brace_in_type_declaration; break; } formatLeftCurlyBrace(line, class_declaration_brace); formatTypeOpeningBrace(class_declaration_brace, space_before_opening_brace, typeDeclaration); boolean indent_body_declarations_compare_to_header; switch(kind) { case TypeDeclaration.ENUM_DECL : indent_body_declarations_compare_to_header = this.preferences.indent_body_declarations_compare_to_enum_declaration_header; break; case TypeDeclaration.ANNOTATION_TYPE_DECL : indent_body_declarations_compare_to_header = this.preferences.indent_body_declarations_compare_to_annotation_declaration_header; break; default: indent_body_declarations_compare_to_header = this.preferences.indent_body_declarations_compare_to_type_header; break; } if (indent_body_declarations_compare_to_header) { this.scribe.indent(); } if (kind == TypeDeclaration.ENUM_DECL) { FieldDeclaration[] fieldDeclarations = typeDeclaration.fields; boolean hasConstants = false; int length = fieldDeclarations != null ? fieldDeclarations.length : 0; int enumConstantsLength = 0; if (fieldDeclarations != null) { for (int i = 0; i < length; i++) { FieldDeclaration fieldDeclaration = fieldDeclarations[i]; if (fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) { enumConstantsLength++; } else { break; } } hasConstants = enumConstantsLength != 0; if (enumConstantsLength > 1) { Alignment enumConstantsAlignment = this.scribe.createAlignment( Alignment.ENUM_CONSTANTS, this.preferences.alignment_for_enum_constants, enumConstantsLength, this.scribe.scanner.currentPosition, 0, // we don't want to indent enum constants when splitting to a new line false); this.scribe.enterAlignment(enumConstantsAlignment); boolean ok = false; do { try { for (int i = 0; i < enumConstantsLength; i++) { this.scribe.alignFragment(enumConstantsAlignment, i); FieldDeclaration fieldDeclaration = fieldDeclarations[i]; fieldDeclaration.traverse(this, typeDeclaration.initializerScope); if (isNextToken(TerminalTokens.TokenNameCOMMA)) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_enum_declarations); if (this.preferences.insert_space_after_comma_in_enum_declarations) { this.scribe.space(); } this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (fieldDeclaration.initialization instanceof QualifiedAllocationExpression) { this.scribe.printNewLine(); } } } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(enumConstantsAlignment, true); } else if (hasConstants) { // only one enum constant FieldDeclaration fieldDeclaration = fieldDeclarations[0]; fieldDeclaration.traverse(this, typeDeclaration.initializerScope); if (isNextToken(TerminalTokens.TokenNameCOMMA)) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_enum_declarations); if (this.preferences.insert_space_after_comma_in_enum_declarations) { this.scribe.space(); } this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (fieldDeclaration.initialization instanceof QualifiedAllocationExpression) { this.scribe.printNewLine(); } } } } if (isNextToken(TerminalTokens.TokenNameSEMICOLON)) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (hasConstants || ((enumConstantsLength - length) != 0) || typeDeclaration.methods != null || typeDeclaration.memberTypes != null) { // make sure that empty enums don't get a new line this.scribe.printNewLine(); } } else if (hasConstants) { this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); // only had a new line if there is at least one enum constant this.scribe.printNewLine(); } } formatTypeMembers(typeDeclaration); if (indent_body_declarations_compare_to_header) { this.scribe.unIndent(); } switch(kind) { case TypeDeclaration.ENUM_DECL : if (this.preferences.insert_new_line_in_empty_enum_declaration) { this.scribe.printNewLine(); } break; case TypeDeclaration.ANNOTATION_TYPE_DECL : if (this.preferences.insert_new_line_in_empty_annotation_declaration) { this.scribe.printNewLine(); } break; default : if (this.preferences.insert_new_line_in_empty_type_declaration) { this.scribe.printNewLine(); } } this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (class_declaration_brace.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) { this.scribe.unIndent(); } if (hasComments()) { this.scribe.printNewLine(); } } private void format( TypeDeclaration memberTypeDeclaration, ClassScope scope, boolean isChunkStart, boolean isFirstClassBodyDeclaration) { if (isFirstClassBodyDeclaration) { int newLinesBeforeFirstClassBodyDeclaration = this.preferences.blank_lines_before_first_class_body_declaration; if (newLinesBeforeFirstClassBodyDeclaration > 0) { this.scribe.printEmptyLines(newLinesBeforeFirstClassBodyDeclaration); } } else { int newLineBeforeChunk = isChunkStart ? this.preferences.blank_lines_before_new_chunk : 0; if (newLineBeforeChunk > 0) { this.scribe.printEmptyLines(newLineBeforeChunk); } final int newLinesBeforeMember = this.preferences.blank_lines_before_member_type; if (newLinesBeforeMember > 0) { this.scribe.printEmptyLines(newLinesBeforeMember); } } memberTypeDeclaration.traverse(this, scope); } private void formatAnonymousTypeDeclaration(TypeDeclaration typeDeclaration) { /* * Type body */ String anonymous_type_declaration_brace_position = this.preferences.brace_position_for_anonymous_type_declaration; formatTypeOpeningBrace(anonymous_type_declaration_brace_position, this.preferences.insert_space_before_opening_brace_in_anonymous_type_declaration, typeDeclaration); this.scribe.indent(); formatTypeMembers(typeDeclaration); this.scribe.unIndent(); if (this.preferences.insert_new_line_in_empty_anonymous_type_declaration) { this.scribe.printNewLine(); } this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE); if (anonymous_type_declaration_brace_position.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) { this.scribe.unIndent(); } } /** * @param block * @param scope * @param block_brace_position */ private void formatBlock(Block block, BlockScope scope, String block_brace_position, boolean insertSpaceBeforeOpeningBrace) { formatOpeningBrace(block_brace_position, insertSpaceBeforeOpeningBrace); final Statement[] statements = block.statements; if (statements != null) { this.scribe.printNewLine(); if (this.preferences.indent_statements_compare_to_block) { this.scribe.indent(); } formatStatements(scope, statements, true); this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_AT_END_OF_BLOCK); if (this.preferences.indent_statements_compare_to_block) { this.scribe.unIndent(); } } else if (this.preferences.insert_new_line_in_empty_block) { this.scribe.printNewLine(); if (this.preferences.indent_statements_compare_to_block) { this.scribe.indent(); } this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_AT_END_OF_BLOCK); if (this.preferences.indent_statements_compare_to_block) { this.scribe.unIndent(); } } else { if (this.preferences.indent_statements_compare_to_block) { this.scribe.indent(); } this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_AT_END_OF_BLOCK); if (this.preferences.indent_statements_compare_to_block) { this.scribe.unIndent(); } } this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(block_brace_position)) { this.scribe.unIndent(); } } private void formatCascadingMessageSends(CascadingMethodInvocationFragmentBuilder builder, BlockScope scope) { int size = builder.size(); MessageSend[] fragments = builder.fragments(); Expression fragment = fragments[0].receiver; int startingPositionInCascade = 1; if (!fragment.isImplicitThis()) { fragment.traverse(this, scope); } else { MessageSend currentMessageSend = fragments[1]; final int numberOfParens = (currentMessageSend.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(currentMessageSend, numberOfParens); } ASTNode[] arguments = currentMessageSend.arguments; TypeReference[] typeArguments = currentMessageSend.typeArguments; if (typeArguments != null) { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments); if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) { this.scribe.space(); } int length = typeArguments.length; for (int i = 0; i < length - 1; i++) { typeArguments[i].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments); if (this.preferences.insert_space_after_comma_in_type_arguments) { this.scribe.space(); } } typeArguments[length - 1].traverse(this, scope); if (isClosingGenericToken()) { this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments); } if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) { this.scribe.space(); } } this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); // selector this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation); if (arguments != null) { if (this.preferences.insert_space_after_opening_paren_in_method_invocation) { this.scribe.space(); } int argumentLength = arguments.length; Alignment argumentsAlignment = this.scribe.createAlignment( Alignment.MESSAGE_ARGUMENTS, this.preferences.alignment_for_arguments_in_method_invocation, Alignment.R_OUTERMOST, argumentLength, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(argumentsAlignment); boolean okForArguments = false; do { try { for (int j = 0; j < argumentLength; j++) { if (j > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_method_invocation_arguments); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.alignFragment(argumentsAlignment, j); if (j > 0 && this.preferences.insert_space_after_comma_in_method_invocation_arguments) { this.scribe.space(); } arguments[j].traverse(this, scope); } okForArguments = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!okForArguments); this.scribe.exitAlignment(argumentsAlignment, true); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_method_invocation); } else { this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_between_empty_parens_in_method_invocation); } if (numberOfParens > 0) { manageClosingParenthesizedExpression(currentMessageSend, numberOfParens); } startingPositionInCascade = 2; } int tieBreakRule = this.preferences.wrap_outer_expressions_when_nested && size-startingPositionInCascade > 2 ? Alignment.R_OUTERMOST : Alignment.R_INNERMOST; Alignment cascadingMessageSendAlignment = this.scribe.createAlignment( Alignment.CASCADING_MESSAGE_SEND, this.preferences.alignment_for_selector_in_method_invocation, tieBreakRule, size, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(cascadingMessageSendAlignment); boolean ok = false; boolean setStartingColumn = true; switch (this.preferences.alignment_for_arguments_in_method_invocation & Alignment.SPLIT_MASK) { case Alignment.M_COMPACT_FIRST_BREAK_SPLIT: case Alignment.M_NEXT_SHIFTED_SPLIT: case Alignment.M_ONE_PER_LINE_SPLIT: setStartingColumn = false; break; } do { if (setStartingColumn) { cascadingMessageSendAlignment.startingColumn = this.scribe.column; } try { this.scribe.alignFragment(cascadingMessageSendAlignment, 0); this.scribe.printNextToken(TerminalTokens.TokenNameDOT); for (int i = startingPositionInCascade; i < size; i++) { MessageSend currentMessageSend = fragments[i]; final int numberOfParens = (currentMessageSend.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(currentMessageSend, numberOfParens); } TypeReference[] typeArguments = currentMessageSend.typeArguments; if (typeArguments != null) { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments); if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) { this.scribe.space(); } int length = typeArguments.length; for (int j = 0; j < length - 1; j++) { typeArguments[j].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments); if (this.preferences.insert_space_after_comma_in_type_arguments) { this.scribe.space(); } } typeArguments[length - 1].traverse(this, scope); if (isClosingGenericToken()) { this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments); } if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) { this.scribe.space(); } } ASTNode[] arguments = currentMessageSend.arguments; this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); // selector this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation); if (arguments != null) { if (this.preferences.insert_space_after_opening_paren_in_method_invocation) { this.scribe.space(); } int argumentLength = arguments.length; int alignmentMode = this.preferences.alignment_for_arguments_in_method_invocation; Alignment argumentsAlignment = this.scribe.createAlignment( Alignment.MESSAGE_ARGUMENTS, alignmentMode, Alignment.R_OUTERMOST, argumentLength, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(argumentsAlignment); boolean okForArguments = false; do { switch (alignmentMode & Alignment.SPLIT_MASK) { case Alignment.M_COMPACT_SPLIT: case Alignment.M_NEXT_PER_LINE_SPLIT: argumentsAlignment.startingColumn = this.scribe.column; break; } try { for (int j = 0; j < argumentLength; j++) { if (j > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_method_invocation_arguments); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.alignFragment(argumentsAlignment, j); if (j == 0) { int fragmentIndentation = argumentsAlignment.fragmentIndentations[j]; if ((argumentsAlignment.mode & Alignment.M_INDENT_ON_COLUMN) != 0 && fragmentIndentation > 0) { this.scribe.indentationLevel = fragmentIndentation; } } else if (this.preferences.insert_space_after_comma_in_method_invocation_arguments) { this.scribe.space(); } arguments[j].traverse(this, scope); argumentsAlignment.startingColumn = -1; } okForArguments = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!okForArguments); this.scribe.exitAlignment(argumentsAlignment, true); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_method_invocation); } else { this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_between_empty_parens_in_method_invocation); } if (numberOfParens > 0) { manageClosingParenthesizedExpression(currentMessageSend, numberOfParens); } cascadingMessageSendAlignment.startingColumn = -1; if (i < size - 1) { this.scribe.alignFragment(cascadingMessageSendAlignment, i); this.scribe.printNextToken(TerminalTokens.TokenNameDOT); } } ok = true; } catch(AlignmentException e){ this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(cascadingMessageSendAlignment, true); } /* * Merged traversal of member (types, fields, methods) */ private void formatClassBodyDeclarations(ASTNode[] nodes) { final int FIELD = 1, METHOD = 2, TYPE = 3; this.scribe.lastNumberOfNewLines = 1; ASTNode[] mergedNodes = computeMergedMemberDeclarations(nodes); Alignment memberAlignment = this.scribe.createMemberAlignment( Alignment.TYPE_MEMBERS, this.preferences.align_type_members_on_columns ? Alignment.M_MULTICOLUMN : Alignment.M_NO_ALIGNMENT, 4, this.scribe.scanner.currentPosition); this.scribe.enterMemberAlignment(memberAlignment); boolean isChunkStart = false; boolean ok = false; int startIndex = 0; do { try { for (int i = startIndex, max = mergedNodes.length; i < max; i++) { ASTNode member = mergedNodes[i]; if (member instanceof FieldDeclaration) { isChunkStart = memberAlignment.checkChunkStart(FIELD, i, this.scribe.scanner.currentPosition); if (member instanceof MultiFieldDeclaration){ MultiFieldDeclaration multiField = (MultiFieldDeclaration) member; format(multiField, this, null, isChunkStart, i == 0); } else if (member instanceof Initializer) { int newLineBeforeChunk = isChunkStart ? this.preferences.blank_lines_before_new_chunk : 0; if (newLineBeforeChunk > 0 && i != 0) { this.scribe.printEmptyLines(newLineBeforeChunk); } else if (i == 0) { int newLinesBeforeFirstClassBodyDeclaration = this.preferences.blank_lines_before_first_class_body_declaration; if (newLinesBeforeFirstClassBodyDeclaration > 0) { this.scribe.printEmptyLines(newLinesBeforeFirstClassBodyDeclaration); } } Initializer initializer = (Initializer) member; initializer.traverse(this, null); } else { FieldDeclaration field = (FieldDeclaration) member; format(field, this, null, isChunkStart, i == 0); } } else if (member instanceof AbstractMethodDeclaration) { isChunkStart = memberAlignment.checkChunkStart(METHOD, i, this.scribe.scanner.currentPosition); format((AbstractMethodDeclaration) member, null, isChunkStart, i == 0); } else { isChunkStart = memberAlignment.checkChunkStart(TYPE, i, this.scribe.scanner.currentPosition); format((TypeDeclaration)member, null, isChunkStart, i == 0); } while (isNextToken(TerminalTokens.TokenNameSEMICOLON)) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } if (i != max - 1) { this.scribe.printNewLine(); } } ok = true; } catch(AlignmentException e){ startIndex = memberAlignment.chunkStartIndex; this.scribe.redoMemberAlignment(e); } } while (!ok); this.scribe.exitMemberAlignment(memberAlignment); if (hasComments()) { this.scribe.printNewLine(); } this.scribe.printComment(); } private void formatEmptyTypeDeclaration(boolean isFirst) { boolean hasSemiColon = isNextToken(TerminalTokens.TokenNameSEMICOLON); while(isNextToken(TerminalTokens.TokenNameSEMICOLON)) { this.scribe.printComment(); this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } if (hasSemiColon && isFirst) { this.scribe.printNewLine(); } } private void formatGuardClauseBlock(Block block, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNameLBRACE, this.preferences.insert_space_before_opening_brace_in_block); this.scribe.space(); final Statement[] statements = block.statements; statements[0].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE, true); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } private void formatLeftCurlyBrace(final int line, final String bracePosition) { /* * deal with (quite unexpected) comments right before lcurly */ this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_IN_FORMAT_LEFT_CURLY_BRACE); if (DefaultCodeFormatterConstants.NEXT_LINE_ON_WRAP.equals(bracePosition) && (this.scribe.line > line || this.scribe.column >= this.preferences.page_width)) { this.scribe.printNewLine(); } } private void formatLocalDeclaration(LocalDeclaration localDeclaration, BlockScope scope, boolean insertSpaceBeforeComma, boolean insertSpaceAfterComma) { if (!isMultipleLocalDeclaration(localDeclaration)) { if (localDeclaration.modifiers != NO_MODIFIERS || localDeclaration.annotations != null) { this.scribe.printComment(); this.scribe.printModifiers(localDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_LOCAL_VARIABLE); this.scribe.space(); } /* * Argument type */ if (localDeclaration.type != null) { localDeclaration.type.traverse(this, scope); } /* * Print the argument name */ this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true); } else { /* * Print the argument name */ this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, false); } formatExtraDimensions(localDeclaration.type); final Expression initialization = localDeclaration.initialization; if (initialization != null) { /* * Print the method name */ this.scribe.printNextToken(TerminalTokens.TokenNameEQUAL, this.preferences.insert_space_before_assignment_operator); if (this.preferences.insert_space_after_assignment_operator) { this.scribe.space(); } Alignment assignmentAlignment = this.scribe.createAlignment( Alignment.LOCAL_DECLARATION_ASSIGNMENT, this.preferences.alignment_for_assignment, Alignment.R_OUTERMOST, 1, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(assignmentAlignment); boolean ok = false; do { try { this.scribe.alignFragment(assignmentAlignment, 0); initialization.traverse(this, scope); ok = true; } catch(AlignmentException e){ this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(assignmentAlignment, true); } if (isPartOfMultipleLocalDeclaration()) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, insertSpaceBeforeComma); if (insertSpaceAfterComma) { this.scribe.space(); } this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } } private void formatMessageSend( MessageSend messageSend, BlockScope scope, Alignment messageAlignment) { if (messageAlignment != null) { if (!this.preferences.wrap_outer_expressions_when_nested || messageAlignment.canAlign()) { this.scribe.alignFragment(messageAlignment, 0); } this.scribe.printNextToken(TerminalTokens.TokenNameDOT); } TypeReference[] typeArguments = messageSend.typeArguments; if (typeArguments != null) { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments); if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) { this.scribe.space(); } int length = typeArguments.length; for (int i = 0; i < length - 1; i++) { typeArguments[i].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments); if (this.preferences.insert_space_after_comma_in_type_arguments) { this.scribe.space(); } } typeArguments[length - 1].traverse(this, scope); if (isClosingGenericToken()) { this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments); } if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) { this.scribe.space(); } } this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); // selector this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation); final Expression[] arguments = messageSend.arguments; if (arguments != null) { if (this.preferences.insert_space_after_opening_paren_in_method_invocation) { this.scribe.space(); } int argumentsLength = arguments.length; if (argumentsLength > 1) { int alignmentMode = this.preferences.alignment_for_arguments_in_method_invocation; Alignment argumentsAlignment = this.scribe.createAlignment( Alignment.MESSAGE_ARGUMENTS, alignmentMode, argumentsLength, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(argumentsAlignment); boolean ok = false; do { switch (alignmentMode & Alignment.SPLIT_MASK) { case Alignment.M_COMPACT_SPLIT: case Alignment.M_NEXT_PER_LINE_SPLIT: argumentsAlignment.startingColumn = this.scribe.column; break; } try { for (int i = 0; i < argumentsLength; i++) { if (i > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_method_invocation_arguments); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (this.scribe.lastNumberOfNewLines == 1) { // a new line has been inserted while printing the comment // hence we need to use the break indentation level before printing next token... this.scribe.indentationLevel = argumentsAlignment.breakIndentationLevel; } } this.scribe.alignFragment(argumentsAlignment, i); if (i > 0 && this.preferences.insert_space_after_comma_in_method_invocation_arguments) { this.scribe.space(); } int fragmentIndentation = 0; if (i == 0) { int wrappedIndex = argumentsAlignment.wrappedIndex(); if (wrappedIndex >= 0) { fragmentIndentation = argumentsAlignment.fragmentIndentations[wrappedIndex]; if ((argumentsAlignment.mode & Alignment.M_INDENT_ON_COLUMN) != 0 && fragmentIndentation > 0) { this.scribe.indentationLevel = fragmentIndentation; } } } arguments[i].traverse(this, scope); argumentsAlignment.startingColumn = -1; } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(argumentsAlignment, true); } else { arguments[0].traverse(this, scope); } this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_method_invocation); } else { this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_between_empty_parens_in_method_invocation); } } private void formatTryResources( TryStatement tryStatement, boolean spaceBeforeOpenParen, boolean spaceBeforeClosingParen, boolean spaceBeforeFirstResource, boolean spaceBeforeSemicolon, boolean spaceAfterSemicolon, int tryResourcesAligment) { LocalDeclaration[] resources = tryStatement.resources; int length = resources != null ? resources.length : 0; if (length > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, spaceBeforeOpenParen); if (spaceBeforeFirstResource) { this.scribe.space(); } Alignment resourcesAlignment = this.scribe.createAlignment( Alignment.TRY_RESOURCES, tryResourcesAligment, // make sure alignment options for try with resources takes precedence Alignment.R_OUTERMOST, length, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(resourcesAlignment); boolean ok = false; do { switch (tryResourcesAligment & Alignment.SPLIT_MASK) { case Alignment.M_COMPACT_SPLIT: case Alignment.M_NEXT_PER_LINE_SPLIT: resourcesAlignment.startingColumn = this.scribe.column; break; } try { for (int i = 0; i < length; i++) { if (i > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, spaceBeforeSemicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (this.scribe.lastNumberOfNewLines == 1) { // a new line has been inserted while printing the comment // hence we need to use the break indentation level before printing next token... this.scribe.indentationLevel = resourcesAlignment.breakIndentationLevel; } } this.scribe.alignFragment(resourcesAlignment, i); if (i == 0) { int fragmentIndentation = resourcesAlignment.fragmentIndentations[0]; if ((resourcesAlignment.mode & Alignment.M_INDENT_ON_COLUMN) != 0 && fragmentIndentation > 0) { this.scribe.indentationLevel = fragmentIndentation; } } else if (spaceAfterSemicolon) { this.scribe.space(); } resources[i].traverse(this, null); resourcesAlignment.startingColumn = -1; } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(resourcesAlignment, true); if (isNextToken(TerminalTokens.TokenNameSEMICOLON)) { // take care of trailing semicolon this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, spaceBeforeSemicolon); } this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, spaceBeforeClosingParen); } } private void formatMethodArguments( AbstractMethodDeclaration methodDeclaration, boolean spaceBeforeOpenParen, boolean spaceBetweenEmptyParameters, boolean spaceBeforeClosingParen, boolean spaceBeforeFirstParameter, boolean spaceBeforeComma, boolean spaceAfterComma, int methodDeclarationParametersAlignment) { formatMethodArguments( methodDeclaration.receiver, methodDeclaration.arguments, methodDeclaration.scope, spaceBeforeOpenParen, spaceBetweenEmptyParameters, spaceBeforeClosingParen, spaceBeforeFirstParameter, spaceBeforeComma, spaceAfterComma, methodDeclarationParametersAlignment); } private void formatMethodArguments( Receiver receiver, final Argument[] arguments, MethodScope scope, boolean spaceBeforeOpenParen, boolean spaceBetweenEmptyParameters, boolean spaceBeforeClosingParen, boolean spaceBeforeFirstParameter, boolean spaceBeforeComma, boolean spaceAfterComma, int methodDeclarationParametersAlignment) { this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, spaceBeforeOpenParen); if (arguments != null || receiver != null) { if (spaceBeforeFirstParameter) { this.scribe.space(); } int receiverCount = receiver != null ? 1 : 0; int realArgumentLength = arguments != null ? arguments.length : 0; int argumentLength = realArgumentLength + receiverCount; Alignment argumentsAlignment = this.scribe.createAlignment( Alignment.METHOD_ARGUMENTS, methodDeclarationParametersAlignment, argumentLength, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(argumentsAlignment); boolean ok = false; do { switch (methodDeclarationParametersAlignment & Alignment.SPLIT_MASK) { case Alignment.M_COMPACT_SPLIT: case Alignment.M_NEXT_PER_LINE_SPLIT: argumentsAlignment.startingColumn = this.scribe.column; break; } try { for (int i = 0; i < argumentLength; i++) { if (i > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, spaceBeforeComma); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (this.scribe.lastNumberOfNewLines == 1) { // a new line has been inserted while printing the comment // hence we need to use the break indentation level before printing next token... this.scribe.indentationLevel = argumentsAlignment.breakIndentationLevel; } } this.scribe.alignFragment(argumentsAlignment, i); if (i == 0) { int fragmentIndentation = argumentsAlignment.fragmentIndentations[0]; if ((argumentsAlignment.mode & Alignment.M_INDENT_ON_COLUMN) != 0 && fragmentIndentation > 0) { this.scribe.indentationLevel = fragmentIndentation; } } else if (spaceAfterComma) { this.scribe.space(); } if (i < receiverCount) { receiver.traverse(this, scope); } else { arguments[i - receiverCount].traverse(this, scope); } argumentsAlignment.startingColumn = -1; } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(argumentsAlignment, true); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, spaceBeforeClosingParen); } else { this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, spaceBetweenEmptyParameters); } } private void formatEnumConstantArguments( FieldDeclaration enumConstant, boolean spaceBeforeOpenParen, boolean spaceBetweenEmptyParameters, boolean spaceBeforeClosingParen, boolean spaceBeforeFirstParameter, boolean spaceBeforeComma, boolean spaceAfterComma, int methodDeclarationParametersAlignment) { if (!isNextToken(TerminalTokens.TokenNameLPAREN)) { return; } this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, spaceBeforeOpenParen); final Expression[] arguments = ((AllocationExpression) enumConstant.initialization).arguments; if (arguments != null) { int argumentLength = arguments.length; Alignment argumentsAlignment = this.scribe.createAlignment( Alignment.ENUM_CONSTANTS_ARGUMENTS, methodDeclarationParametersAlignment, argumentLength, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(argumentsAlignment); boolean ok = false; do { try { if (spaceBeforeFirstParameter) { this.scribe.space(); } for (int i = 0; i < argumentLength; i++) { if (i > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, spaceBeforeComma); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.alignFragment(argumentsAlignment, i); if (i > 0 && spaceAfterComma) { this.scribe.space(); } arguments[i].traverse(this, (BlockScope) null); } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(argumentsAlignment, true); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, spaceBeforeClosingParen); } else { this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, spaceBetweenEmptyParameters); } } private void formatNecessaryEmptyStatement() { if (this.preferences.put_empty_statement_on_new_line) { this.scribe.printNewLine(); this.scribe.indent(); this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); this.scribe.unIndent(); } else { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } } private void formatOpeningBrace(String bracePosition, boolean insertSpaceBeforeBrace) { if (DefaultCodeFormatterConstants.NEXT_LINE.equals(bracePosition)) { this.scribe.printNewLine(); } else if (DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(bracePosition)) { this.scribe.printNewLine(); this.scribe.indent(); } else if (DefaultCodeFormatterConstants.NEXT_LINE_ON_WRAP.equals(bracePosition) && this.scribe.column >= this.preferences.page_width) { this.scribe.printNewLine(); } this.scribe.printNextToken(TerminalTokens.TokenNameLBRACE, insertSpaceBeforeBrace, Scribe.PRESERVE_EMPTY_LINES_IN_FORMAT_OPENING_BRACE); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.UNMODIFIABLE_TRAILING_COMMENT); } private void formatStatements(BlockScope scope, final Statement[] statements, boolean insertNewLineAfterLastStatement) { int statementsLength = statements.length; for (int i = 0; i < statementsLength; i++) { final Statement statement = statements[i]; if (i > 0 && (statements[i - 1] instanceof EmptyStatement) && !(statement instanceof EmptyStatement)) { this.scribe.printNewLine(); } statement.traverse(this, scope); if (statement instanceof Expression) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (i != statementsLength - 1) { if (!(statement instanceof EmptyStatement) && !(statements[i + 1] instanceof EmptyStatement)) { this.scribe.printNewLine(); } } else if (i == statementsLength - 1 && insertNewLineAfterLastStatement) { this.scribe.printNewLine(); } } else if (statement instanceof LocalDeclaration) { LocalDeclaration currentLocal = (LocalDeclaration) statement; if (i < (statementsLength - 1)) { /* * We need to check that the next statement is a local declaration */ if (statements[i + 1] instanceof LocalDeclaration) { LocalDeclaration nextLocal = (LocalDeclaration) statements[i + 1]; if (currentLocal.declarationSourceStart != nextLocal.declarationSourceStart) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (i != statementsLength - 1) { if (!(statement instanceof EmptyStatement) && !(statements[i + 1] instanceof EmptyStatement)) { this.scribe.printNewLine(); } } else if (i == statementsLength - 1 && insertNewLineAfterLastStatement) { this.scribe.printNewLine(); } } } else { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (i != statementsLength - 1) { if (!(statement instanceof EmptyStatement) && !(statements[i + 1] instanceof EmptyStatement)) { this.scribe.printNewLine(); } } else if (i == statementsLength - 1 && insertNewLineAfterLastStatement) { this.scribe.printNewLine(); } } } else { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (i != statementsLength - 1) { if (!(statement instanceof EmptyStatement) && !(statements[i + 1] instanceof EmptyStatement)) { this.scribe.printNewLine(); } } else if (i == statementsLength - 1 && insertNewLineAfterLastStatement) { this.scribe.printNewLine(); } } } else if (i != statementsLength - 1) { if (!(statement instanceof EmptyStatement) && !(statements[i + 1] instanceof EmptyStatement)) { this.scribe.printNewLine(); } } else if (i == statementsLength - 1 && insertNewLineAfterLastStatement) { this.scribe.printNewLine(); } } } private void formatThrowsClause( AbstractMethodDeclaration methodDeclaration, boolean spaceBeforeComma, boolean spaceAfterComma, int alignmentForThrowsClause) { final TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions; if (thrownExceptions != null) { int thrownExceptionsLength = thrownExceptions.length; Alignment throwsAlignment = this.scribe.createAlignment( Alignment.THROWS, alignmentForThrowsClause, thrownExceptionsLength, // throws is the first token this.scribe.scanner.currentPosition); this.scribe.enterAlignment(throwsAlignment); boolean ok = false; do { try { this.scribe.alignFragment(throwsAlignment, 0); this.scribe.printNextToken(TerminalTokens.TokenNamethrows, true); for (int i = 0; i < thrownExceptionsLength; i++) { if (i > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, spaceBeforeComma); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); this.scribe.alignFragment(throwsAlignment, i); if (spaceAfterComma) { this.scribe.space(); } } else { this.scribe.space(); } thrownExceptions[i].traverse(this, methodDeclaration.scope); } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(throwsAlignment, true); } } /* * Merged traversal of member (types, fields, methods) */ private void formatTypeMembers(TypeDeclaration typeDeclaration) { Alignment memberAlignment = this.scribe.createMemberAlignment( Alignment.TYPE_MEMBERS, this.preferences.align_type_members_on_columns ? Alignment.M_MULTICOLUMN : Alignment.M_NO_ALIGNMENT, 3, this.scribe.scanner.currentPosition); this.scribe.enterMemberAlignment(memberAlignment); ASTNode[] members = computeMergedMemberDeclarations(typeDeclaration); boolean isChunkStart = false; boolean ok = false; int membersLength = members.length; if (membersLength > 0) { int startIndex = 0; do { try { for (int i = startIndex, max = members.length; i < max; i++) { while (isNextToken(TerminalTokens.TokenNameSEMICOLON)) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.printNewLine(); ASTNode member = members[i]; if (member instanceof FieldDeclaration) { isChunkStart = memberAlignment.checkChunkStart(Alignment.CHUNK_FIELD, i, this.scribe.scanner.currentPosition); if (member instanceof MultiFieldDeclaration) { MultiFieldDeclaration multiField = (MultiFieldDeclaration) member; if (multiField.isStatic()) { format(multiField, this, typeDeclaration.staticInitializerScope, isChunkStart, i == 0); } else { format(multiField, this, typeDeclaration.initializerScope, isChunkStart, i == 0); } } else if (member instanceof Initializer) { int newLineBeforeChunk = isChunkStart ? this.preferences.blank_lines_before_new_chunk : 0; if (newLineBeforeChunk > 0 && i != 0) { this.scribe.printEmptyLines(newLineBeforeChunk); } else if (i == 0) { int newLinesBeforeFirstClassBodyDeclaration = this.preferences.blank_lines_before_first_class_body_declaration; if (newLinesBeforeFirstClassBodyDeclaration > 0) { this.scribe.printEmptyLines(newLinesBeforeFirstClassBodyDeclaration); } } Initializer initializer = (Initializer) member; if (initializer.isStatic()) { initializer.traverse(this, typeDeclaration.staticInitializerScope); } else { initializer.traverse(this, typeDeclaration.initializerScope); } } else { FieldDeclaration field = (FieldDeclaration) member; if (field.isStatic()) { format(field, this, typeDeclaration.staticInitializerScope, isChunkStart, i == 0); } else { format(field, this, typeDeclaration.initializerScope, isChunkStart, i == 0); } } } else if (member instanceof AbstractMethodDeclaration) { isChunkStart = memberAlignment.checkChunkStart(Alignment.CHUNK_METHOD, i, this.scribe.scanner.currentPosition); format((AbstractMethodDeclaration) member, typeDeclaration.scope, isChunkStart, i == 0); } else if (member instanceof TypeDeclaration) { isChunkStart = memberAlignment.checkChunkStart(Alignment.CHUNK_TYPE, i, this.scribe.scanner.currentPosition); format((TypeDeclaration)member, typeDeclaration.scope, isChunkStart, i == 0); } while (isNextToken(TerminalTokens.TokenNameSEMICOLON)) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.printNewLine(); // realign to the proper value if (this.scribe.memberAlignment != null) { // select the last alignment this.scribe.indentationLevel = this.scribe.memberAlignment.originalIndentationLevel; } } ok = true; } catch(AlignmentException e){ startIndex = memberAlignment.chunkStartIndex; this.scribe.redoMemberAlignment(e); } } while (!ok); } else if (isNextToken(TerminalTokens.TokenNameSEMICOLON)) { // the only body declaration is an empty declaration (';') this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.printComment(Scribe.DO_NOT_PRESERVE_EMPTY_LINES); this.scribe.exitMemberAlignment(memberAlignment); } private void formatTypeOpeningBraceForEnumConstant(String bracePosition, boolean insertSpaceBeforeBrace, TypeDeclaration typeDeclaration) { int fieldCount = (typeDeclaration.fields == null) ? 0 : typeDeclaration.fields.length; int methodCount = (typeDeclaration.methods == null) ? 0 : typeDeclaration.methods.length; int typeCount = (typeDeclaration.memberTypes == null) ? 0 : typeDeclaration.memberTypes.length; if (methodCount <= 2) { for (int i = 0, max = methodCount; i < max; i++) { final AbstractMethodDeclaration abstractMethodDeclaration = typeDeclaration.methods[i]; if (abstractMethodDeclaration.isDefaultConstructor()) { methodCount--; } else if (abstractMethodDeclaration.isClinit()) { methodCount--; } } } final int memberLength = fieldCount + methodCount+typeCount; boolean insertNewLine = memberLength > 0; if (!insertNewLine) { if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) { insertNewLine = this.preferences.insert_new_line_in_empty_enum_constant; } } formatOpeningBrace(bracePosition, insertSpaceBeforeBrace); if (insertNewLine) { this.scribe.printNewLine(); } } private void formatTypeOpeningBrace(String bracePosition, boolean insertSpaceBeforeBrace, TypeDeclaration typeDeclaration) { int fieldCount = (typeDeclaration.fields == null) ? 0 : typeDeclaration.fields.length; int methodCount = (typeDeclaration.methods == null) ? 0 : typeDeclaration.methods.length; int typeCount = (typeDeclaration.memberTypes == null) ? 0 : typeDeclaration.memberTypes.length; if (methodCount <= 2) { for (int i = 0, max = methodCount; i < max; i++) { final AbstractMethodDeclaration abstractMethodDeclaration = typeDeclaration.methods[i]; if (abstractMethodDeclaration.isDefaultConstructor()) { methodCount--; } else if (abstractMethodDeclaration.isClinit()) { methodCount--; } } } final int memberLength = fieldCount + methodCount + typeCount; boolean insertNewLine = memberLength > 0; if (!insertNewLine) { if (TypeDeclaration.kind(typeDeclaration.modifiers) == TypeDeclaration.ENUM_DECL) { insertNewLine = this.preferences.insert_new_line_in_empty_enum_declaration; } else if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) { insertNewLine = this.preferences.insert_new_line_in_empty_anonymous_type_declaration; } else if (TypeDeclaration.kind(typeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) { insertNewLine = this.preferences.insert_new_line_in_empty_annotation_declaration; } else { insertNewLine = this.preferences.insert_new_line_in_empty_type_declaration; } } formatOpeningBrace(bracePosition, insertSpaceBeforeBrace); if (insertNewLine) { this.scribe.printNewLine(); } } private int getDimensions() { this.localScanner.resetTo(this.scribe.scanner.currentPosition, this.scribe.scannerEndPosition - 1); int dimensions = 0; int balance = 0; try { int token; loop: while ((token = this.localScanner.getNextToken()) != TerminalTokens.TokenNameEOF) { switch(token) { case TerminalTokens.TokenNameRBRACKET: dimensions++; balance--; break; case TerminalTokens.TokenNameAT : skipPastTypeAnnotations(); break; case TerminalTokens.TokenNameCOMMENT_BLOCK : case TerminalTokens.TokenNameCOMMENT_JAVADOC : case TerminalTokens.TokenNameCOMMENT_LINE : break; case TerminalTokens.TokenNameLBRACKET : balance++; break; default: break loop; } } } catch(InvalidInputException e) { // ignore } if (balance == 0) { return dimensions; } return 0; } private void skipPastTypeAnnotations() { // we get here having seen @ int balance = 0; int currentTokenStartPosition = this.localScanner.currentPosition; try { loop: while (true) { currentTokenStartPosition = this.localScanner.currentPosition; int token = this.localScanner.getNextToken(); switch(token) { case TerminalTokens.TokenNameEOF: break loop; case TerminalTokens.TokenNameIdentifier : case TerminalTokens.TokenNameDOT : case TerminalTokens.TokenNameCOMMENT_BLOCK : case TerminalTokens.TokenNameCOMMENT_JAVADOC : case TerminalTokens.TokenNameCOMMENT_LINE : break; case TerminalTokens.TokenNameLPAREN: balance++; break; case TerminalTokens.TokenNameRPAREN: --balance; break; default: if (balance <= 0) break loop; } } } catch(InvalidInputException e) { // ignore } finally { this.localScanner.resetTo(currentTokenStartPosition, this.scribe.scannerEndPosition - 1); } } private boolean hasComments() { this.localScanner.resetTo(this.scribe.scanner.startPosition, this.scribe.scannerEndPosition - 1); try { switch(this.localScanner.getNextToken()) { case TerminalTokens.TokenNameCOMMENT_BLOCK : case TerminalTokens.TokenNameCOMMENT_JAVADOC : case TerminalTokens.TokenNameCOMMENT_LINE : return true; } } catch(InvalidInputException e) { // ignore } return false; } private boolean hasNonAnnotationModifiers() { this.localScanner.resetTo(this.scribe.scanner.currentPosition, this.scribe.scannerEndPosition - 1); try { int token; while ((token = this.localScanner.getNextToken()) != TerminalTokens.TokenNameEOF) { switch(token) { case TerminalTokens.TokenNamedefault : case TerminalTokens.TokenNamepublic : case TerminalTokens.TokenNameprotected : case TerminalTokens.TokenNameprivate : case TerminalTokens.TokenNamestatic : case TerminalTokens.TokenNameabstract : case TerminalTokens.TokenNamefinal : case TerminalTokens.TokenNamenative : case TerminalTokens.TokenNamesynchronized : case TerminalTokens.TokenNametransient : case TerminalTokens.TokenNamevolatile : case TerminalTokens.TokenNamestrictfp : return true; case TerminalTokens.TokenNameAT : skipPastTypeAnnotations(); break; case TerminalTokens.TokenNameCOMMENT_BLOCK : case TerminalTokens.TokenNameCOMMENT_JAVADOC : case TerminalTokens.TokenNameCOMMENT_LINE : break; default: return false; } } } catch(InvalidInputException e) { // ignore } return false; } private boolean isNextToken(int tokenName) { this.localScanner.resetTo(this.scribe.scanner.currentPosition, this.scribe.scannerEndPosition - 1); try { int token = this.localScanner.getNextToken(); loop: while(true) { switch(token) { case TerminalTokens.TokenNameCOMMENT_BLOCK : case TerminalTokens.TokenNameCOMMENT_JAVADOC : case TerminalTokens.TokenNameCOMMENT_LINE : token = this.localScanner.getNextToken(); continue loop; default: break loop; } } return token == tokenName; } catch(InvalidInputException e) { // ignore } return false; } private boolean isNextTokenPunctuation() { this.localScanner.resetTo(this.scribe.scanner.currentPosition, this.scribe.scannerEndPosition - 1); try { int token = this.localScanner.getNextToken(); return !(Scanner.isLiteral(token) || Scanner.isKeyword(token) || Scanner.isIdentifier(token)); } catch(InvalidInputException e) { // ignore } return false; } private boolean isClosingGenericToken() { this.localScanner.resetTo(this.scribe.scanner.currentPosition, this.scribe.scannerEndPosition - 1); try { int token = this.localScanner.getNextToken(); loop: while(true) { switch(token) { case TerminalTokens.TokenNameCOMMENT_BLOCK : case TerminalTokens.TokenNameCOMMENT_JAVADOC : case TerminalTokens.TokenNameCOMMENT_LINE : token = this.localScanner.getNextToken(); continue loop; default: break loop; } } switch(token) { case TerminalTokens.TokenNameGREATER : case TerminalTokens.TokenNameRIGHT_SHIFT : case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT : return true; } } catch(InvalidInputException e) { // ignore } return false; } private boolean isGuardClause(Block block) { return !commentStartsBlock(block.sourceStart, block.sourceEnd) && block.statements != null && block.statements.length == 1 && (block.statements[0] instanceof ReturnStatement || block.statements[0] instanceof ThrowStatement); } private boolean isMultipleLocalDeclaration(LocalDeclaration localDeclaration) { if (localDeclaration.declarationSourceStart == this.lastLocalDeclarationSourceStart) return true; this.lastLocalDeclarationSourceStart = localDeclaration.declarationSourceStart; return false; } private boolean isPartOfMultipleLocalDeclaration() { this.localScanner.resetTo(this.scribe.scanner.currentPosition, this.scribe.scannerEndPosition - 1); try { int token; while ((token = this.localScanner.getNextToken()) != TerminalTokens.TokenNameEOF) { switch(token) { case TerminalTokens.TokenNameCOMMA ://90 return true; case TerminalTokens.TokenNameCOMMENT_BLOCK : case TerminalTokens.TokenNameCOMMENT_JAVADOC : case TerminalTokens.TokenNameCOMMENT_LINE : break; default: return false; } } } catch(InvalidInputException e) { // ignore } return false; } private void manageClosingParenthesizedExpression(Expression expression, int numberOfParens) { for (int i = 0; i < numberOfParens; i++) { this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_parenthesized_expression); } } private void manageOpeningParenthesizedExpression(Expression expression, int numberOfParens) { for (int i = 0; i < numberOfParens; i++) { this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_parenthesized_expression); if (this.preferences.insert_space_after_opening_paren_in_parenthesized_expression) { this.scribe.space(); } } } private void printComment() { this.localScanner.resetTo(this.scribe.scanner.startPosition, this.scribe.scannerEndPosition - 1); try { int token = this.localScanner.getNextToken(); switch(token) { case TerminalTokens.TokenNameCOMMENT_JAVADOC : case TerminalTokens.TokenNameCOMMENT_BLOCK : case TerminalTokens.TokenNameCOMMENT_LINE : this.scribe.printComment(token, Scribe.NO_TRAILING_COMMENT); break; } } catch(InvalidInputException e) { // ignore } } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.AllocationExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( AllocationExpression allocationExpression, BlockScope scope) { // 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt final int numberOfParens = (allocationExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(allocationExpression, numberOfParens); } this.scribe.printNextToken(TerminalTokens.TokenNamenew); TypeReference[] typeArguments = allocationExpression.typeArguments; if (typeArguments != null) { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments); if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) { this.scribe.space(); } int length = typeArguments.length; for (int i = 0; i < length - 1; i++) { typeArguments[i].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments); if (this.preferences.insert_space_after_comma_in_type_arguments) { this.scribe.space(); } } typeArguments[length - 1].traverse(this, scope); if (isClosingGenericToken()) { this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments); } if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) { this.scribe.space(); } } else { this.scribe.space(); } allocationExpression.type.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation); final Expression[] arguments = allocationExpression.arguments; if (arguments != null) { if (this.preferences.insert_space_after_opening_paren_in_method_invocation) { this.scribe.space(); } int argumentLength = arguments.length; Alignment argumentsAlignment =this.scribe.createAlignment( Alignment.ALLOCATION, this.preferences.alignment_for_arguments_in_allocation_expression, argumentLength, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(argumentsAlignment); boolean ok = false; do { try { for (int i = 0; i < argumentLength; i++) { if (i > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_allocation_expression); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.alignFragment(argumentsAlignment, i); if (i > 0 && this.preferences.insert_space_after_comma_in_allocation_expression) { this.scribe.space(); } arguments[i].traverse(this, scope); } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(argumentsAlignment, true); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_method_invocation); } else { this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_between_empty_parens_in_method_invocation); } if (numberOfParens > 0) { manageClosingParenthesizedExpression(allocationExpression, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( AND_AND_Expression and_and_Expression, BlockScope scope) { return dumpBinaryExpression(and_and_Expression, TerminalTokens.TokenNameAND_AND, scope); } public boolean visit( AnnotationMethodDeclaration annotationTypeMemberDeclaration, ClassScope scope) { /* * Print comments to get proper line number */ this.scribe.printComment(); this.scribe.printModifiers(annotationTypeMemberDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_METHOD); this.scribe.space(); /* * Print the method return type */ final TypeReference returnType = annotationTypeMemberDeclaration.returnType; final MethodScope annotationTypeMemberDeclarationScope = annotationTypeMemberDeclaration.scope; if (returnType != null) { returnType.traverse(this, annotationTypeMemberDeclarationScope); } /* * Print the method name */ this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true); this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_annotation_type_member_declaration); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_between_empty_parens_in_annotation_type_member_declaration); /* * Check for extra dimensions */ int extraDimensions = annotationTypeMemberDeclaration.extendedDimensions; if (extraDimensions != 0) { if (this.preferences.insert_space_before_opening_bracket_in_array_type_reference) { this.scribe.space(); } for (int i = 0; i < extraDimensions; i++) { this.scribe.printNextToken(TerminalTokens.TokenNameLBRACKET); if (this.preferences.insert_space_between_brackets_in_array_type_reference) { this.scribe.space(); } this.scribe.printNextToken(TerminalTokens.TokenNameRBRACKET); } } Expression defaultValue = annotationTypeMemberDeclaration.defaultValue; if (defaultValue != null) { this.scribe.printNextToken(TerminalTokens.TokenNamedefault, true); this.scribe.space(); defaultValue.traverse(this, (BlockScope) null); } this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.Argument, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(Argument argument, BlockScope scope) { if (argument.modifiers != NO_MODIFIERS || argument.annotations != null) { this.scribe.printComment(); this.scribe.printModifiers(argument.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_PARAMETER, !hasNonAnnotationModifiers()); this.scribe.space(); } /* * Argument type */ TypeReference argumentType = argument.type; if (argumentType != null) { if (argumentType instanceof UnionTypeReference) { formatMultiCatchArguments( argument, this.preferences.insert_space_before_binary_operator, this.preferences.insert_space_after_binary_operator, this.preferences.alignment_for_union_type_in_multicatch, scope); } else { argumentType.traverse(this, scope); } } if (argument.isVarArgs()) { Annotation [][] annotationsOnDimensions = argumentType.getAnnotationsOnDimensions(true); if (annotationsOnDimensions != null) { Annotation [] varargAnnotations = annotationsOnDimensions[annotationsOnDimensions.length - 1]; if (varargAnnotations != null) { formatInlineAnnotations(varargAnnotations, true); } } this.scribe.printNextToken(TerminalTokens.TokenNameELLIPSIS, this.preferences.insert_space_before_ellipsis); if (this.preferences.insert_space_after_ellipsis) { this.scribe.space(); } this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, false); } else { if (argument.isReceiver()) { this.scribe.space(); NameReference qualifyingName = ((Receiver) argument).qualifyingName; if (qualifyingName != null) { qualifyingName.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameDOT, false); } this.scribe.printNextToken(TerminalTokens.TokenNamethis, false); } else { /* * Print the argument name */ this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, argument.type != null); } } formatExtraDimensions(argumentType); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( ArrayAllocationExpression arrayAllocationExpression, BlockScope scope) { final int numberOfParens = (arrayAllocationExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(arrayAllocationExpression, numberOfParens); } this.scribe.printNextToken(TerminalTokens.TokenNamenew); this.scribe.space(); arrayAllocationExpression.type.traverse(this, scope); final Expression[] dimensions = arrayAllocationExpression.dimensions; int dimensionsLength = dimensions.length; for (int i = 0; i < dimensionsLength; i++) { if (arrayAllocationExpression.annotationsOnDimensions != null) { formatInlineAnnotations(arrayAllocationExpression.annotationsOnDimensions[i], true); } if (this.preferences.insert_space_before_opening_bracket_in_array_allocation_expression) { this.scribe.space(); } this.scribe.printNextToken(TerminalTokens.TokenNameLBRACKET, false); if (dimensions[i] != null) { if (this.preferences.insert_space_after_opening_bracket_in_array_allocation_expression) { this.scribe.space(); } dimensions[i].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameRBRACKET, this.preferences.insert_space_before_closing_bracket_in_array_allocation_expression); } else { this.scribe.printNextToken(TerminalTokens.TokenNameRBRACKET, this.preferences.insert_space_between_empty_brackets_in_array_allocation_expression); } } final ArrayInitializer initializer = arrayAllocationExpression.initializer; if (initializer != null) { initializer.traverse(this, scope); } if (numberOfParens > 0) { manageClosingParenthesizedExpression(arrayAllocationExpression, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ArrayInitializer, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(ArrayInitializer arrayInitializer, BlockScope scope) { final int numberOfParens = (arrayInitializer.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(arrayInitializer, numberOfParens); } if (this.arrayInitializersDepth < 0) { this.arrayInitializersDepth = 0; } else { this.arrayInitializersDepth++; } int arrayInitializerIndentationLevel = this.scribe.indentationLevel; try { final Expression[] expressions = arrayInitializer.expressions; if (expressions != null) { String array_initializer_brace_position = this.preferences.brace_position_for_array_initializer; formatOpeningBrace(array_initializer_brace_position, this.preferences.insert_space_before_opening_brace_in_array_initializer); int expressionsLength = expressions.length; final boolean insert_new_line_after_opening_brace = this.preferences.insert_new_line_after_opening_brace_in_array_initializer; boolean ok = false; Alignment arrayInitializerAlignment = null; if (expressionsLength > 1) { if (insert_new_line_after_opening_brace) { this.scribe.printNewLine(); } arrayInitializerAlignment = this.scribe.createAlignment( Alignment.ARRAY_INITIALIZER, this.preferences.alignment_for_expressions_in_array_initializer, Alignment.R_OUTERMOST, expressionsLength, this.scribe.scanner.currentPosition, this.preferences.continuation_indentation_for_array_initializer, true); if (insert_new_line_after_opening_brace) { arrayInitializerAlignment.fragmentIndentations[0] = arrayInitializerAlignment.breakIndentationLevel; } this.scribe.enterAlignment(arrayInitializerAlignment); do { try { this.scribe.alignFragment(arrayInitializerAlignment, 0); if (this.preferences.insert_space_after_opening_brace_in_array_initializer) { this.scribe.space(); } expressions[0].traverse(this, scope); for (int i = 1; i < expressionsLength; i++) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_array_initializer); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); this.scribe.alignFragment(arrayInitializerAlignment, i); if (this.preferences.insert_space_after_comma_in_array_initializer) { this.scribe.space(); } expressions[i].traverse(this, scope); if (i == expressionsLength - 1) { if (isNextToken(TerminalTokens.TokenNameCOMMA)) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_array_initializer); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } } } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(arrayInitializerAlignment, true); } else { // Use an alignment with no break in case when the array initializer // is not inside method arguments alignments if (this.scribe.currentAlignment == null || this.scribe.currentAlignment.kind != Alignment.MESSAGE_ARGUMENTS) { arrayInitializerAlignment = this.scribe.createAlignment( Alignment.ARRAY_INITIALIZER, this.preferences.alignment_for_expressions_in_array_initializer, Alignment.R_OUTERMOST, 0, this.scribe.scanner.currentPosition, this.preferences.continuation_indentation_for_array_initializer, true); this.scribe.enterAlignment(arrayInitializerAlignment); } do { try { if (insert_new_line_after_opening_brace) { this.scribe.printNewLine(); this.scribe.indent(); } // we don't need to use an alignment if (this.preferences.insert_space_after_opening_brace_in_array_initializer) { this.scribe.space(); } else { this.scribe.needSpace = false; } expressions[0].traverse(this, scope); if (isNextToken(TerminalTokens.TokenNameCOMMA)) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_array_initializer); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } if (insert_new_line_after_opening_brace) { this.scribe.unIndent(); } ok = true; } catch (AlignmentException e) { if (arrayInitializerAlignment == null) throw e; this.scribe.redoAlignment(e); } } while (!ok); if (arrayInitializerAlignment != null) { this.scribe.exitAlignment(arrayInitializerAlignment, true); } } if (this.preferences.insert_new_line_before_closing_brace_in_array_initializer) { this.scribe.printNewLine(); } else if (this.preferences.insert_space_before_closing_brace_in_array_initializer) { this.scribe.space(); } this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE, false, Scribe.PRESERVE_EMPTY_LINES_IN_CLOSING_ARRAY_INITIALIZER + (arrayInitializerIndentationLevel << 16)); if (array_initializer_brace_position.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) { this.scribe.unIndent(); } } else { boolean keepEmptyArrayInitializerOnTheSameLine = this.preferences.keep_empty_array_initializer_on_one_line; String array_initializer_brace_position = this.preferences.brace_position_for_array_initializer; if (keepEmptyArrayInitializerOnTheSameLine) { this.scribe.printNextToken(TerminalTokens.TokenNameLBRACE, this.preferences.insert_space_before_opening_brace_in_array_initializer); if (isNextToken(TerminalTokens.TokenNameCOMMA)) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_array_initializer); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE, this.preferences.insert_space_between_empty_braces_in_array_initializer); } else { formatOpeningBrace(array_initializer_brace_position, this.preferences.insert_space_before_opening_brace_in_array_initializer); if (isNextToken(TerminalTokens.TokenNameCOMMA)) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_array_initializer); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE, this.preferences.insert_space_between_empty_braces_in_array_initializer); if (array_initializer_brace_position.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) { this.scribe.unIndent(); } } } } finally { this.arrayInitializersDepth--; } if (numberOfParens > 0) { manageClosingParenthesizedExpression(arrayInitializer, numberOfParens); } return false; } private void formatArrayQualifiedTypeReference(ArrayQualifiedTypeReference arrayQualifiedTypeReference) { final int numberOfParens = (arrayQualifiedTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(arrayQualifiedTypeReference, numberOfParens); } formatQualifiedTypeReference(arrayQualifiedTypeReference); formatLeadingDimensions(arrayQualifiedTypeReference); if (numberOfParens > 0) { manageClosingParenthesizedExpression(arrayQualifiedTypeReference, numberOfParens); } } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( ArrayQualifiedTypeReference arrayQualifiedTypeReference, BlockScope scope) { formatArrayQualifiedTypeReference(arrayQualifiedTypeReference); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference, org.eclipse.jdt.internal.compiler.lookup.ClassScope) */ public boolean visit( ArrayQualifiedTypeReference arrayQualifiedTypeReference, ClassScope scope) { formatArrayQualifiedTypeReference(arrayQualifiedTypeReference); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ArrayReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(ArrayReference arrayReference, BlockScope scope) { final int numberOfParens = (arrayReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(arrayReference, numberOfParens); } arrayReference.receiver.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameLBRACKET, this.preferences.insert_space_before_opening_bracket_in_array_reference); if (this.preferences.insert_space_after_opening_bracket_in_array_reference) { this.scribe.space(); } arrayReference.position.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameRBRACKET, this.preferences.insert_space_before_closing_bracket_in_array_reference); if (numberOfParens > 0) { manageClosingParenthesizedExpression(arrayReference, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( ArrayTypeReference arrayTypeReference, BlockScope scope) { final int numberOfParens = (arrayTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(arrayTypeReference, numberOfParens); } if (arrayTypeReference.annotations != null) { formatInlineAnnotations(arrayTypeReference.annotations[0], false); } this.scribe.printNextToken(SINGLETYPEREFERENCE_EXPECTEDTOKENS); int dimensions = getDimensions(); if (dimensions != 0) { formatDimensions(arrayTypeReference, 0, dimensions); } if (numberOfParens > 0) { manageClosingParenthesizedExpression(arrayTypeReference, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference, org.eclipse.jdt.internal.compiler.lookup.ClassScope) */ public boolean visit( ArrayTypeReference arrayTypeReference, ClassScope scope) { final int numberOfParens = (arrayTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(arrayTypeReference, numberOfParens); } if (arrayTypeReference.annotations != null) { formatInlineAnnotations(arrayTypeReference.annotations[0], false); } this.scribe.printNextToken(SINGLETYPEREFERENCE_EXPECTEDTOKENS); int dimensions = getDimensions(); if (dimensions != 0) { formatDimensions(arrayTypeReference, 0, dimensions); } if (numberOfParens > 0) { manageClosingParenthesizedExpression(arrayTypeReference, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.AssertStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(AssertStatement assertStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNameassert); this.scribe.space(); assertStatement.assertExpression.traverse(this, scope); if (assertStatement.exceptionArgument != null) { this.scribe.printNextToken(TerminalTokens.TokenNameCOLON, this.preferences.insert_space_before_colon_in_assert); if (this.preferences.insert_space_after_colon_in_assert) { this.scribe.space(); } assertStatement.exceptionArgument.traverse(this, scope); } this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.Assignment, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(Assignment assignment, BlockScope scope) { final int numberOfParens = (assignment.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(assignment, numberOfParens); } assignment.lhs.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameEQUAL, this.preferences.insert_space_before_assignment_operator); if (this.preferences.insert_space_after_assignment_operator) { this.scribe.space(); } Alignment assignmentAlignment = this.scribe.createAlignment( Alignment.ASSIGNMENT, this.preferences.alignment_for_assignment, Alignment.R_OUTERMOST, 1, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(assignmentAlignment); boolean ok = false; do { try { this.scribe.alignFragment(assignmentAlignment, 0); assignment.expression.traverse(this, scope); ok = true; } catch(AlignmentException e){ this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(assignmentAlignment, true); if (numberOfParens > 0) { manageClosingParenthesizedExpression(assignment, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.BinaryExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(BinaryExpression binaryExpression, BlockScope scope) { switch((binaryExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) { case OperatorIds.AND : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameAND, scope); case OperatorIds.DIVIDE : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameDIVIDE, scope); case OperatorIds.GREATER : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameGREATER, scope); case OperatorIds.GREATER_EQUAL : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameGREATER_EQUAL, scope); case OperatorIds.LEFT_SHIFT : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameLEFT_SHIFT, scope); case OperatorIds.LESS : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameLESS, scope); case OperatorIds.LESS_EQUAL : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameLESS_EQUAL, scope); case OperatorIds.MINUS : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameMINUS, scope); case OperatorIds.MULTIPLY : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameMULTIPLY, scope); case OperatorIds.OR : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameOR, scope); case OperatorIds.PLUS : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNamePLUS, scope); case OperatorIds.REMAINDER : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameREMAINDER, scope); case OperatorIds.RIGHT_SHIFT : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameRIGHT_SHIFT, scope); case OperatorIds.UNSIGNED_RIGHT_SHIFT : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT, scope); case OperatorIds.XOR : return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameXOR, scope); default: throw new IllegalStateException(); } } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.Block, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(Block block, BlockScope scope) { formatBlock(block, scope, this.preferences.brace_position_for_block, this.preferences.insert_space_before_opening_brace_in_block); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.BreakStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(BreakStatement breakStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNamebreak); if (breakStatement.label != null) { this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true); } this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.CaseStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(CaseStatement caseStatement, BlockScope scope) { if (caseStatement.constantExpression == null) { this.scribe.printNextToken(TerminalTokens.TokenNamedefault); this.scribe.printNextToken(TerminalTokens.TokenNameCOLON, this.preferences.insert_space_before_colon_in_default); } else { this.scribe.printNextToken(TerminalTokens.TokenNamecase); this.scribe.space(); caseStatement.constantExpression.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameCOLON, this.preferences.insert_space_before_colon_in_case); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.CastExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(CastExpression castExpression, BlockScope scope) { final int numberOfParens = (castExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(castExpression, numberOfParens); } this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN); if (this.preferences.insert_space_after_opening_paren_in_cast) { this.scribe.space(); } castExpression.type.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_cast); if (this.preferences.insert_space_after_closing_paren_in_cast) { this.scribe.space(); } castExpression.expression.traverse(this, scope); if (numberOfParens > 0) { manageClosingParenthesizedExpression(castExpression, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.CharLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(CharLiteral charLiteral, BlockScope scope) { final int numberOfParens = (charLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(charLiteral, numberOfParens); } this.scribe.printNextToken(TerminalTokens.TokenNameCharacterLiteral); if (numberOfParens > 0) { manageClosingParenthesizedExpression(charLiteral, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(ClassLiteralAccess classLiteral, BlockScope scope) { final int numberOfParens = (classLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(classLiteral, numberOfParens); } classLiteral.type.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameDOT); this.scribe.printNextToken(TerminalTokens.TokenNameclass); if (numberOfParens > 0) { manageClosingParenthesizedExpression(classLiteral, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.Clinit, org.eclipse.jdt.internal.compiler.lookup.ClassScope) */ public boolean visit(Clinit clinit, ClassScope scope) { return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration, org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope) */ public boolean visit( CompilationUnitDeclaration compilationUnitDeclaration, CompilationUnitScope scope) { // fake new line to handle empty lines before package declaration or import declarations this.scribe.lastNumberOfNewLines = 1; // Set header end position final TypeDeclaration[] types = compilationUnitDeclaration.types; int headerEndPosition = types == null ? compilationUnitDeclaration.sourceEnd : types[0].declarationSourceStart; this.scribe.setHeaderComment(headerEndPosition); /* * Package declaration */ ImportReference currentPackage = compilationUnitDeclaration.currentPackage; final boolean hasPackage = currentPackage != null; if (hasPackage) { printComment(); int blankLinesBeforePackage = this.preferences.blank_lines_before_package; if (blankLinesBeforePackage > 0) { this.scribe.printEmptyLines(blankLinesBeforePackage); } this.scribe.printModifiers(currentPackage.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_PACKAGE); this.scribe.space(); // dump the package keyword this.scribe.printNextToken(TerminalTokens.TokenNamepackage); this.scribe.space(); this.scribe.printQualifiedReference(compilationUnitDeclaration.currentPackage.sourceEnd, false/*do not expect parenthesis*/); this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); int blankLinesAfterPackage = this.preferences.blank_lines_after_package; if (blankLinesAfterPackage > 0) { this.scribe.printEmptyLines(blankLinesAfterPackage); } else { this.scribe.printNewLine(); } } else { this.scribe.printComment(); } /* * Import statements */ final ImportReference[] imports = compilationUnitDeclaration.imports; if (imports != null) { if (hasPackage) { int blankLinesBeforeImports = this.preferences.blank_lines_before_imports; if (blankLinesBeforeImports > 0) { this.scribe.printEmptyLines(blankLinesBeforeImports); } } int importLength = imports.length; if (importLength != 1) { format(imports[0], false); for (int i = 1; i < importLength - 1; i++) { format(imports[i], false); } format(imports[importLength - 1], true); } else { format(imports[0], true); } int blankLinesAfterImports = this.preferences.blank_lines_after_imports; if (blankLinesAfterImports > 0) { this.scribe.printEmptyLines(blankLinesAfterImports); } } formatEmptyTypeDeclaration(true); int blankLineBetweenTypeDeclarations = this.preferences.blank_lines_between_type_declarations; /* * Type declarations */ if (types != null) { int typesLength = types.length; for (int i = 0; i < typesLength - 1; i++) { types[i].traverse(this, scope); formatEmptyTypeDeclaration(false); if (blankLineBetweenTypeDeclarations != 0) { this.scribe.printEmptyLines(blankLineBetweenTypeDeclarations); } else { this.scribe.printNewLine(); } } types[typesLength - 1].traverse(this, scope); } this.scribe.printEndOfCompilationUnit(); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.CompoundAssignment, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( CompoundAssignment compoundAssignment, BlockScope scope) { final int numberOfParens = (compoundAssignment.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(compoundAssignment, numberOfParens); } compoundAssignment.lhs.traverse(this, scope); /* * Print the operator */ int operator; switch(compoundAssignment.operator) { case OperatorIds.PLUS : operator = TerminalTokens.TokenNamePLUS_EQUAL; break; case OperatorIds.MINUS : operator = TerminalTokens.TokenNameMINUS_EQUAL; break; case OperatorIds.MULTIPLY : operator = TerminalTokens.TokenNameMULTIPLY_EQUAL; break; case OperatorIds.DIVIDE : operator = TerminalTokens.TokenNameDIVIDE_EQUAL; break; case OperatorIds.AND : operator = TerminalTokens.TokenNameAND_EQUAL; break; case OperatorIds.OR : operator = TerminalTokens.TokenNameOR_EQUAL; break; case OperatorIds.XOR : operator = TerminalTokens.TokenNameXOR_EQUAL; break; case OperatorIds.REMAINDER : operator = TerminalTokens.TokenNameREMAINDER_EQUAL; break; case OperatorIds.LEFT_SHIFT : operator = TerminalTokens.TokenNameLEFT_SHIFT_EQUAL; break; case OperatorIds.RIGHT_SHIFT : operator = TerminalTokens.TokenNameRIGHT_SHIFT_EQUAL; break; default: // OperatorIds.UNSIGNED_RIGHT_SHIFT : operator = TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL; } this.scribe.printNextToken(operator, this.preferences.insert_space_before_assignment_operator); if (this.preferences.insert_space_after_assignment_operator) { this.scribe.space(); } Alignment assignmentAlignment = this.scribe.createAlignment( Alignment.COMPOUND_ASSIGNMENT, this.preferences.alignment_for_assignment, Alignment.R_OUTERMOST, 1, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(assignmentAlignment); boolean ok = false; do { try { this.scribe.alignFragment(assignmentAlignment, 0); compoundAssignment.expression.traverse(this, scope); ok = true; } catch(AlignmentException e){ this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(assignmentAlignment, true); if (numberOfParens > 0) { manageClosingParenthesizedExpression(compoundAssignment, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( ConditionalExpression conditionalExpression, BlockScope scope) { final int numberOfParens = (conditionalExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(conditionalExpression, numberOfParens); } conditionalExpression.condition.traverse(this, scope); Alignment conditionalExpressionAlignment =this.scribe.createAlignment( Alignment.CONDITIONAL_EXPRESSION, this.preferences.alignment_for_conditional_expression, 2, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(conditionalExpressionAlignment); boolean ok = false; do { try { this.scribe.alignFragment(conditionalExpressionAlignment, 0); this.scribe.printNextToken(TerminalTokens.TokenNameQUESTION, this.preferences.insert_space_before_question_in_conditional); if (this.preferences.insert_space_after_question_in_conditional) { this.scribe.space(); } conditionalExpression.valueIfTrue.traverse(this, scope); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); this.scribe.alignFragment(conditionalExpressionAlignment, 1); this.scribe.printNextToken(TerminalTokens.TokenNameCOLON, this.preferences.insert_space_before_colon_in_conditional); if (this.preferences.insert_space_after_colon_in_conditional) { this.scribe.space(); } conditionalExpression.valueIfFalse.traverse(this, scope); ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(conditionalExpressionAlignment, true); if (numberOfParens > 0) { manageClosingParenthesizedExpression(conditionalExpression, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration, org.eclipse.jdt.internal.compiler.lookup.ClassScope) */ public boolean visit( ConstructorDeclaration constructorDeclaration, ClassScope scope) { if (constructorDeclaration.ignoreFurtherInvestigation) { this.scribe.printComment(); if (this.scribe.indentationLevel != 0) { this.scribe.printIndentationIfNecessary(); } this.scribe.scanner.resetTo(constructorDeclaration.declarationSourceEnd + 1, this.scribe.scannerEndPosition - 1); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); switch(this.scribe.scanner.source[this.scribe.scanner.currentPosition]) { case '\n' : this.scribe.scanner.currentPosition++; this.scribe.lastNumberOfNewLines = 1; break; case '\r' : this.scribe.scanner.currentPosition++; if (this.scribe.scanner.source[this.scribe.scanner.currentPosition] == '\n') { this.scribe.scanner.currentPosition++; } this.scribe.lastNumberOfNewLines = 1; } return false; } /* * Print comments to get proper line number */ this.scribe.printComment(); int line = this.scribe.line; this.scribe.printModifiers(constructorDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_METHOD); if (this.scribe.line > line) { // annotations introduced new line, but this is not a line wrapping // see 158267 line = this.scribe.line; } this.scribe.space(); TypeParameter[] typeParameters = constructorDeclaration.typeParameters; if (typeParameters != null) { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_parameters); if (this.preferences.insert_space_after_opening_angle_bracket_in_type_parameters) { this.scribe.space(); } int length = typeParameters.length; for (int i = 0; i < length - 1; i++) { typeParameters[i].traverse(this, constructorDeclaration.scope); this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_parameters); if (this.preferences.insert_space_after_comma_in_type_parameters) { this.scribe.space(); } } typeParameters[length - 1].traverse(this, constructorDeclaration.scope); if (isClosingGenericToken()) { this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_parameters); } if (this.preferences.insert_space_after_closing_angle_bracket_in_type_parameters) { this.scribe.space(); } } /* * Print the method name */ this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true); formatMethodArguments( constructorDeclaration, this.preferences.insert_space_before_opening_paren_in_constructor_declaration, this.preferences.insert_space_between_empty_parens_in_constructor_declaration, this.preferences.insert_space_before_closing_paren_in_constructor_declaration, this.preferences.insert_space_after_opening_paren_in_constructor_declaration, this.preferences.insert_space_before_comma_in_constructor_declaration_parameters, this.preferences.insert_space_after_comma_in_constructor_declaration_parameters, this.preferences.alignment_for_parameters_in_constructor_declaration); formatThrowsClause( constructorDeclaration, this.preferences.insert_space_before_comma_in_constructor_declaration_throws, this.preferences.insert_space_after_comma_in_constructor_declaration_throws, this.preferences.alignment_for_throws_clause_in_constructor_declaration); if (!constructorDeclaration.isNative() && !constructorDeclaration.isAbstract()) { /* * Method body */ String constructor_declaration_brace = this.preferences.brace_position_for_constructor_declaration; formatLeftCurlyBrace(line, constructor_declaration_brace); formatOpeningBrace(constructor_declaration_brace, this.preferences.insert_space_before_opening_brace_in_constructor_declaration); final int numberOfBlankLinesAtBeginningOfMethodBody = this.preferences.blank_lines_at_beginning_of_method_body; if (numberOfBlankLinesAtBeginningOfMethodBody > 0) { this.scribe.printEmptyLines(numberOfBlankLinesAtBeginningOfMethodBody); } if (constructorDeclaration.constructorCall != null && !constructorDeclaration.constructorCall.isImplicitSuper()) { this.scribe.printNewLine(); if (this.preferences.indent_statements_compare_to_body) { this.scribe.indent(); } constructorDeclaration.constructorCall.traverse(this, constructorDeclaration.scope); if (this.preferences.indent_statements_compare_to_body) { this.scribe.unIndent(); } } final Statement[] statements = constructorDeclaration.statements; if (statements != null) { this.scribe.printNewLine(); if (this.preferences.indent_statements_compare_to_body) { this.scribe.indent(); } formatStatements(constructorDeclaration.scope, statements, true); this.scribe.printComment(); if (this.preferences.indent_statements_compare_to_body) { this.scribe.unIndent(); } } else { if (this.preferences.insert_new_line_in_empty_method_body) { this.scribe.printNewLine(); } if (this.preferences.indent_statements_compare_to_body) { this.scribe.indent(); } this.scribe.printComment(); if (this.preferences.indent_statements_compare_to_body) { this.scribe.unIndent(); } } this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (constructor_declaration_brace.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) { this.scribe.unIndent(); } } else { // no method body this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ContinueStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(ContinueStatement continueStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNamecontinue); if (continueStatement.label != null) { this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true); } this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.DoStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(DoStatement doStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNamedo); final int line = this.scribe.line; final Statement action = doStatement.action; if (action != null) { if (action instanceof Block) { formatLeftCurlyBrace(line, this.preferences.brace_position_for_block); action.traverse(this, scope); } else if (action instanceof EmptyStatement) { /* * This is an empty statement */ formatNecessaryEmptyStatement(); } else { this.scribe.printNewLine(); this.scribe.indent(); action.traverse(this, scope); if (action instanceof Expression) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.printNewLine(); this.scribe.unIndent(); } } else { /* * This is an empty statement */ formatNecessaryEmptyStatement(); } if (this.preferences.insert_new_line_before_while_in_do_statement) { this.scribe.printNewLine(); } this.scribe.printNextToken(TerminalTokens.TokenNamewhile, this.preferences.insert_space_after_closing_brace_in_block); this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_while); if (this.preferences.insert_space_after_opening_paren_in_while) { this.scribe.space(); } doStatement.condition.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_while); this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.DoubleLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(DoubleLiteral doubleLiteral, BlockScope scope) { final int numberOfParens = (doubleLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(doubleLiteral, numberOfParens); } if (isNextToken(TerminalTokens.TokenNameMINUS)) { this.scribe.printNextToken(TerminalTokens.TokenNameMINUS); } this.scribe.printNextToken(TerminalTokens.TokenNameDoubleLiteral); if (numberOfParens > 0) { manageClosingParenthesizedExpression(doubleLiteral, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.EmptyStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(EmptyStatement statement, BlockScope scope) { if (this.preferences.put_empty_statement_on_new_line) { this.scribe.printNewLine(); } this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); return false; } // field is an enum constant public boolean visit(FieldDeclaration enumConstant, MethodScope scope) { /* * Print comments to get proper line number */ this.scribe.printComment(); final int line = this.scribe.line; this.scribe.printModifiers(enumConstant.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_FIELD); this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, false); formatEnumConstantArguments( enumConstant, this.preferences.insert_space_before_opening_paren_in_enum_constant, this.preferences.insert_space_between_empty_parens_in_enum_constant, this.preferences.insert_space_before_closing_paren_in_enum_constant, this.preferences.insert_space_after_opening_paren_in_enum_constant, this.preferences.insert_space_before_comma_in_enum_constant_arguments, this.preferences.insert_space_after_comma_in_enum_constant_arguments, this.preferences.alignment_for_arguments_in_enum_constant); Expression initialization = enumConstant.initialization; if (initialization instanceof QualifiedAllocationExpression) { TypeDeclaration typeDeclaration = ((QualifiedAllocationExpression) initialization).anonymousType; int fieldsCount = typeDeclaration.fields == null ? 0 : typeDeclaration.fields.length; int methodsCount = typeDeclaration.methods == null ? 0 : typeDeclaration.methods.length; int membersCount = typeDeclaration.memberTypes == null ? 0 : typeDeclaration.memberTypes.length; /* * Type body */ String enum_constant_brace = this.preferences.brace_position_for_enum_constant; formatLeftCurlyBrace(line, enum_constant_brace); formatTypeOpeningBraceForEnumConstant(enum_constant_brace, this.preferences.insert_space_before_opening_brace_in_enum_constant, typeDeclaration); if (this.preferences.indent_body_declarations_compare_to_enum_constant_header) { this.scribe.indent(); } if (fieldsCount != 0 || methodsCount != 0 || membersCount != 0) { formatTypeMembers(typeDeclaration); } if (this.preferences.indent_body_declarations_compare_to_enum_constant_header) { this.scribe.unIndent(); } if (this.preferences.insert_new_line_in_empty_enum_constant) { this.scribe.printNewLine(); } this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (enum_constant_brace.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) { this.scribe.unIndent(); } if (hasComments()) { this.scribe.printNewLine(); } } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.EqualExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(EqualExpression equalExpression, BlockScope scope) { if ((equalExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT == OperatorIds.EQUAL_EQUAL) { return dumpEqualityExpression(equalExpression, TerminalTokens.TokenNameEQUAL_EQUAL, scope); } else { return dumpEqualityExpression(equalExpression, TerminalTokens.TokenNameNOT_EQUAL, scope); } } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( ExplicitConstructorCall explicitConstructor, BlockScope scope) { if (explicitConstructor.isImplicitSuper()) { return false; } final Expression qualification = explicitConstructor.qualification; if (qualification != null) { qualification.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameDOT); } TypeReference[] typeArguments = explicitConstructor.typeArguments; if (typeArguments != null) { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments); if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) { this.scribe.space(); } int length = typeArguments.length; for (int i = 0; i < length - 1; i++) { typeArguments[i].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments); if (this.preferences.insert_space_after_comma_in_type_arguments) { this.scribe.space(); } } typeArguments[length - 1].traverse(this, scope); if (isClosingGenericToken()) { this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments); } if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) { this.scribe.space(); } } if (explicitConstructor.isSuperAccess()) { this.scribe.printNextToken(TerminalTokens.TokenNamesuper); } else { this.scribe.printNextToken(TerminalTokens.TokenNamethis); } this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation); final Expression[] arguments = explicitConstructor.arguments; if (arguments != null) { if (this.preferences.insert_space_after_opening_paren_in_method_invocation) { this.scribe.space(); } int argumentLength = arguments.length; Alignment argumentsAlignment =this.scribe.createAlignment( Alignment.EXPLICIT_CONSTRUCTOR_CALL, this.preferences.alignment_for_arguments_in_explicit_constructor_call, argumentLength, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(argumentsAlignment); boolean ok = false; do { try { for (int i = 0; i < argumentLength; i++) { if (i > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_explicit_constructor_call_arguments); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.alignFragment(argumentsAlignment, i); if (i > 0 && this.preferences.insert_space_after_comma_in_explicit_constructor_call_arguments) { this.scribe.space(); } arguments[i].traverse(this, scope); } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(argumentsAlignment, true); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_method_invocation); } else { this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_between_empty_parens_in_method_invocation); } this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.FalseLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(FalseLiteral falseLiteral, BlockScope scope) { final int numberOfParens = (falseLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(falseLiteral, numberOfParens); } this.scribe.printNextToken(TerminalTokens.TokenNamefalse); if (numberOfParens > 0) { manageClosingParenthesizedExpression(falseLiteral, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.FieldReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(FieldReference fieldReference, BlockScope scope) { final int numberOfParens = (fieldReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(fieldReference, numberOfParens); } fieldReference.receiver.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameDOT); this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); if (numberOfParens > 0) { manageClosingParenthesizedExpression(fieldReference, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.FloatLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(FloatLiteral floatLiteral, BlockScope scope) { final int numberOfParens = (floatLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(floatLiteral, numberOfParens); } if (isNextToken(TerminalTokens.TokenNameMINUS)) { this.scribe.printNextToken(TerminalTokens.TokenNameMINUS); } this.scribe.printNextToken(TerminalTokens.TokenNameFloatingPointLiteral); if (numberOfParens > 0) { manageClosingParenthesizedExpression(floatLiteral, numberOfParens); } return false; } public boolean visit(ForeachStatement forStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNamefor); final int line = this.scribe.line; this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_for); if (this.preferences.insert_space_after_opening_paren_in_for) { this.scribe.space(); } formatLocalDeclaration(forStatement.elementVariable, scope, false, false); this.scribe.printNextToken(TerminalTokens.TokenNameCOLON, this.preferences.insert_space_before_colon_in_for); if (this.preferences.insert_space_after_colon_in_for) { this.scribe.space(); } forStatement.collection.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_for); final Statement action = forStatement.action; if (action != null) { if (action instanceof Block) { formatLeftCurlyBrace(line, this.preferences.brace_position_for_block); action.traverse(this, scope); } else if (action instanceof EmptyStatement) { /* * This is an empty statement */ formatNecessaryEmptyStatement(); } else { this.scribe.indent(); this.scribe.printNewLine(); action.traverse(this, scope); this.scribe.unIndent(); } if (action instanceof Expression) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } } else { /* * This is an empty statement */ formatNecessaryEmptyStatement(); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ForStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(ForStatement forStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNamefor); final int line = this.scribe.line; this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_for); if (this.preferences.insert_space_after_opening_paren_in_for) { this.scribe.space(); } final Statement[] initializations = forStatement.initializations; if (initializations != null) { int length = initializations.length; for (int i = 0; i < length; i++) { if (initializations[i] instanceof LocalDeclaration) { formatLocalDeclaration((LocalDeclaration) initializations[i], scope, this.preferences.insert_space_before_comma_in_for_inits, this.preferences.insert_space_after_comma_in_for_inits); } else { initializations[i].traverse(this, scope); if (i >= 0 && (i < length - 1)) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_for_inits); if (this.preferences.insert_space_after_comma_in_for_inits) { this.scribe.space(); } this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } } } } this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon_in_for); final Expression condition = forStatement.condition; if (condition != null) { if (this.preferences.insert_space_after_semicolon_in_for) { this.scribe.space(); } condition.traverse(this, scope); } this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon_in_for); final Statement[] increments = forStatement.increments; if (increments != null) { if (this.preferences.insert_space_after_semicolon_in_for) { this.scribe.space(); } for (int i = 0, length = increments.length; i < length; i++) { increments[i].traverse(this, scope); if (i != length - 1) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_for_increments); if (this.preferences.insert_space_after_comma_in_for_increments) { this.scribe.space(); } this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } } } this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_for); final Statement action = forStatement.action; if (action != null) { if (action instanceof Block) { formatLeftCurlyBrace(line, this.preferences.brace_position_for_block); action.traverse(this, scope); } else if (action instanceof EmptyStatement) { /* * This is an empty statement */ formatNecessaryEmptyStatement(); } else { this.scribe.indent(); this.scribe.printNewLine(); action.traverse(this, scope); this.scribe.unIndent(); } if (action instanceof Expression) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } } else { /* * This is an empty statement */ formatNecessaryEmptyStatement(); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.IfStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(IfStatement ifStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNameif); final int line = this.scribe.line; this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_if); if (this.preferences.insert_space_after_opening_paren_in_if) { this.scribe.space(); } ifStatement.condition.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_if); final Statement thenStatement = ifStatement.thenStatement; final Statement elseStatement = ifStatement.elseStatement; boolean thenStatementIsBlock = false; if (thenStatement != null) { if (thenStatement instanceof Block) { thenStatementIsBlock = true; if (isGuardClause((Block)thenStatement) && elseStatement == null && this.preferences.keep_guardian_clause_on_one_line) { /* * Need a specific formatting for guard clauses * guard clauses are block with a single return or throw * statement */ formatGuardClauseBlock((Block) thenStatement, scope); } else { formatLeftCurlyBrace(line, this.preferences.brace_position_for_block); thenStatement.traverse(this, scope); if (elseStatement != null && (this.preferences.insert_new_line_before_else_in_if_statement)) { this.scribe.printNewLine(); } } } else if (elseStatement == null && this.preferences.keep_simple_if_on_one_line) { Alignment compactIfAlignment = this.scribe.createAlignment( Alignment.COMPACT_IF, this.preferences.alignment_for_compact_if, Alignment.R_OUTERMOST, 1, this.scribe.scanner.currentPosition, 1, false); this.scribe.enterAlignment(compactIfAlignment); boolean ok = false; do { try { this.scribe.alignFragment(compactIfAlignment, 0); this.scribe.space(); thenStatement.traverse(this, scope); if (thenStatement instanceof Expression) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(compactIfAlignment, true); } else if (this.preferences.keep_then_statement_on_same_line) { this.scribe.space(); thenStatement.traverse(this, scope); if (thenStatement instanceof Expression) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } if (elseStatement != null) { this.scribe.printNewLine(); } } else { this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); this.scribe.printNewLine(); this.scribe.indent(); thenStatement.traverse(this, scope); if (thenStatement instanceof Expression) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } if (elseStatement != null) { this.scribe.printNewLine(); } this.scribe.unIndent(); } } if (elseStatement != null) { if (thenStatementIsBlock) { this.scribe.printNextToken(TerminalTokens.TokenNameelse, this.preferences.insert_space_after_closing_brace_in_block, Scribe.PRESERVE_EMPTY_LINES_BEFORE_ELSE); } else { this.scribe.printNextToken(TerminalTokens.TokenNameelse, true, Scribe.PRESERVE_EMPTY_LINES_BEFORE_ELSE); } if (elseStatement instanceof Block) { elseStatement.traverse(this, scope); } else if (elseStatement instanceof IfStatement) { if (!this.preferences.compact_else_if) { this.scribe.printNewLine(); this.scribe.indent(); } this.scribe.space(); elseStatement.traverse(this, scope); if (!this.preferences.compact_else_if) { this.scribe.unIndent(); } } else if (this.preferences.keep_else_statement_on_same_line) { this.scribe.space(); elseStatement.traverse(this, scope); if (elseStatement instanceof Expression) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } } else { this.scribe.printNewLine(); this.scribe.indent(); elseStatement.traverse(this, scope); if (elseStatement instanceof Expression) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.unIndent(); } } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.IntersectionCastTypeReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(IntersectionCastTypeReference intersectionCastTypeReference, BlockScope scope) { int length = intersectionCastTypeReference.typeReferences == null ? 0 : intersectionCastTypeReference.typeReferences.length; for (int i = 0; i < length; i++) { intersectionCastTypeReference.typeReferences[i].traverse(this, scope); if (i != length - 1) { // Borrowing the formatting option from binary operators this.scribe.printNextToken(TerminalTokens.TokenNameAND, this.preferences.insert_space_before_binary_operator); if (this.preferences.insert_space_after_binary_operator) { this.scribe.space(); } } } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.Initializer, org.eclipse.jdt.internal.compiler.lookup.MethodScope) */ public boolean visit(Initializer initializer, MethodScope scope) { if (initializer.isStatic()) { this.scribe.printNextToken(TerminalTokens.TokenNamestatic); } initializer.block.traverse(this, scope); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( InstanceOfExpression instanceOfExpression, BlockScope scope) { final int numberOfParens = (instanceOfExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(instanceOfExpression, numberOfParens); } instanceOfExpression.expression.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameinstanceof, true); this.scribe.space(); instanceOfExpression.type.traverse(this, scope); if (numberOfParens > 0) { manageClosingParenthesizedExpression(instanceOfExpression, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.IntLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(IntLiteral intLiteral, BlockScope scope) { final int numberOfParens = (intLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(intLiteral, numberOfParens); } if (isNextToken(TerminalTokens.TokenNameMINUS)) { this.scribe.printNextToken(TerminalTokens.TokenNameMINUS); } this.scribe.printNextToken(TerminalTokens.TokenNameIntegerLiteral); if (numberOfParens > 0) { manageClosingParenthesizedExpression(intLiteral, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.LabeledStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(LabeledStatement labeledStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); this.scribe.printNextToken(TerminalTokens.TokenNameCOLON, this.preferences.insert_space_before_colon_in_labeled_statement); if (this.preferences.insert_space_after_colon_in_labeled_statement) { this.scribe.space(); } if (this.preferences.insert_new_line_after_label) { this.scribe.printNewLine(); } final Statement statement = labeledStatement.statement; statement.traverse(this, scope); if (statement instanceof Expression) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.LambdaExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(LambdaExpression lambdaExpression, BlockScope scope) { final int numberOfParens = (lambdaExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(lambdaExpression, numberOfParens); } if (isNextToken(TerminalTokens.TokenNameLPAREN)) { // Format arguments formatMethodArguments( null, lambdaExpression.arguments(), lambdaExpression.getScope(), this.preferences.insert_space_before_opening_paren_in_method_declaration, this.preferences.insert_space_between_empty_parens_in_method_declaration, this.preferences.insert_space_before_closing_paren_in_method_declaration, this.preferences.insert_space_after_opening_paren_in_method_declaration, this.preferences.insert_space_before_comma_in_method_declaration_parameters, this.preferences.insert_space_after_comma_in_method_declaration_parameters, this.preferences.alignment_for_parameters_in_method_declaration); } else { // This MUST be a single, untyped parameter this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); } if (this.preferences.insert_space_before_lambda_arrow) this.scribe.space(); this.scribe.printNextToken(TerminalTokens.TokenNameARROW); if (this.preferences.insert_space_after_lambda_arrow) this.scribe.space(); final Statement body = lambdaExpression.body(); if (body instanceof Block) { formatBlock((Block) body, scope, this.preferences.brace_position_for_lambda_body, this.preferences.insert_space_before_opening_brace_in_block); } else { body.traverse(this, scope); } if (numberOfParens > 0) { manageClosingParenthesizedExpression(lambdaExpression, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(LocalDeclaration localDeclaration, BlockScope scope) { formatLocalDeclaration(localDeclaration, scope, this.preferences.insert_space_before_comma_in_multiple_local_declarations, this.preferences.insert_space_after_comma_in_multiple_local_declarations); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.LongLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(LongLiteral longLiteral, BlockScope scope) { final int numberOfParens = (longLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(longLiteral, numberOfParens); } if (isNextToken(TerminalTokens.TokenNameMINUS)) { this.scribe.printNextToken(TerminalTokens.TokenNameMINUS); } this.scribe.printNextToken(TerminalTokens.TokenNameLongLiteral); if (numberOfParens > 0) { manageClosingParenthesizedExpression(longLiteral, numberOfParens); } return false; } public boolean visit(MarkerAnnotation annotation, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNameAT); if (this.preferences.insert_space_after_at_in_annotation) { this.scribe.space(); } this.scribe.printQualifiedReference(annotation.sourceEnd, false/*do not expect parenthesis*/); return false; } public boolean visit(MarkerAnnotation annotation, ClassScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNameAT); if (this.preferences.insert_space_after_at_in_annotation) { this.scribe.space(); } this.scribe.printQualifiedReference(annotation.sourceEnd, false/*do not expect parenthesis*/); return false; } public boolean visit(MemberValuePair pair, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); this.scribe.printNextToken(TerminalTokens.TokenNameEQUAL, this.preferences.insert_space_before_assignment_operator); if (this.preferences.insert_space_after_assignment_operator) { this.scribe.space(); } pair.value.traverse(this, scope); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.MessageSend, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(MessageSend messageSend, BlockScope scope) { final int numberOfParens = (messageSend.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(messageSend, numberOfParens); } CascadingMethodInvocationFragmentBuilder builder = buildFragments(messageSend, scope); if (builder.size() >= 3 && numberOfParens == 0) { formatCascadingMessageSends(builder, scope); } else { Alignment messageAlignment = null; if (!messageSend.receiver.isImplicitThis()) { messageSend.receiver.traverse(this, scope); int alignmentMode = this.preferences.alignment_for_selector_in_method_invocation; messageAlignment = this.scribe.createAlignment( Alignment.MESSAGE_SEND, alignmentMode, 1, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(messageAlignment); boolean ok = false; do { switch (alignmentMode & Alignment.SPLIT_MASK) { case Alignment.M_COMPACT_SPLIT: case Alignment.M_NEXT_PER_LINE_SPLIT: messageAlignment.startingColumn = this.scribe.column; break; } try { formatMessageSend(messageSend, scope, messageAlignment); ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(messageAlignment, true); } else { formatMessageSend(messageSend, scope, null); } } if (numberOfParens > 0) { manageClosingParenthesizedExpression(messageSend, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration, org.eclipse.jdt.internal.compiler.lookup.ClassScope) */ public boolean visit( MethodDeclaration methodDeclaration, ClassScope scope) { if (methodDeclaration.ignoreFurtherInvestigation) { this.scribe.printComment(); if (this.scribe.indentationLevel != 0) { this.scribe.printIndentationIfNecessary(); } this.scribe.scanner.resetTo(methodDeclaration.declarationSourceEnd + 1, this.scribe.scannerEndPosition - 1); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (!this.scribe.scanner.atEnd()) { switch(this.scribe.scanner.source[this.scribe.scanner.currentPosition]) { case '\n' : this.scribe.scanner.currentPosition++; this.scribe.lastNumberOfNewLines = 1; break; case '\r' : this.scribe.scanner.currentPosition++; if (this.scribe.scanner.source[this.scribe.scanner.currentPosition] == '\n') { this.scribe.scanner.currentPosition++; } this.scribe.lastNumberOfNewLines = 1; } } return false; } /* * Print comments to get proper line number */ this.scribe.printComment(); int line = this.scribe.line; // Create alignment Alignment methodDeclAlignment = this.scribe.createAlignment( Alignment.METHOD_DECLARATION, this.preferences.alignment_for_method_declaration, Alignment.R_INNERMOST, 3, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(methodDeclAlignment); boolean ok = false; final MethodScope methodDeclarationScope = methodDeclaration.scope; do { try { this.scribe.printModifiers(methodDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_METHOD); int fragmentIndex = 0; this.scribe.alignFragment(methodDeclAlignment, fragmentIndex); if (this.scribe.line > line) { // annotations introduced new line, but this is not a line wrapping // see 158267 line = this.scribe.line; } this.scribe.space(); TypeParameter[] typeParameters = methodDeclaration.typeParameters; if (typeParameters != null) { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_parameters); if (this.preferences.insert_space_after_opening_angle_bracket_in_type_parameters) { this.scribe.space(); } int length = typeParameters.length; for (int i = 0; i < length - 1; i++) { typeParameters[i].traverse(this, methodDeclaration.scope); this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_parameters); if (this.preferences.insert_space_after_comma_in_type_parameters) { this.scribe.space(); } } typeParameters[length - 1].traverse(this, methodDeclaration.scope); if (isClosingGenericToken()) { this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_parameters); } if (this.preferences.insert_space_after_closing_angle_bracket_in_type_parameters) { this.scribe.space(); } this.scribe.alignFragment(methodDeclAlignment, ++fragmentIndex); } /* * Print the method return type */ final TypeReference returnType = methodDeclaration.returnType; if (returnType != null) { returnType.traverse(this, methodDeclarationScope); } this.scribe.alignFragment(methodDeclAlignment, ++fragmentIndex); /* * Print the method name */ this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true); // Format arguments formatMethodArguments( methodDeclaration, this.preferences.insert_space_before_opening_paren_in_method_declaration, this.preferences.insert_space_between_empty_parens_in_method_declaration, this.preferences.insert_space_before_closing_paren_in_method_declaration, this.preferences.insert_space_after_opening_paren_in_method_declaration, this.preferences.insert_space_before_comma_in_method_declaration_parameters, this.preferences.insert_space_after_comma_in_method_declaration_parameters, this.preferences.alignment_for_parameters_in_method_declaration); formatExtraDimensions(methodDeclaration.returnType); // Format throws formatThrowsClause( methodDeclaration, this.preferences.insert_space_before_comma_in_method_declaration_throws, this.preferences.insert_space_after_comma_in_method_declaration_throws, this.preferences.alignment_for_throws_clause_in_method_declaration); ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(methodDeclAlignment, true); if (!methodDeclaration.isNative() && !methodDeclaration.isAbstract() && ((methodDeclaration.modifiers & ExtraCompilerModifiers.AccSemicolonBody) == 0)) { /* * Method body */ String method_declaration_brace = this.preferences.brace_position_for_method_declaration; formatLeftCurlyBrace(line, method_declaration_brace); formatOpeningBrace(method_declaration_brace, this.preferences.insert_space_before_opening_brace_in_method_declaration); final int numberOfBlankLinesAtBeginningOfMethodBody = this.preferences.blank_lines_at_beginning_of_method_body; if (numberOfBlankLinesAtBeginningOfMethodBody > 0) { this.scribe.printEmptyLines(numberOfBlankLinesAtBeginningOfMethodBody); } final Statement[] statements = methodDeclaration.statements; if (statements != null) { this.scribe.printNewLine(); if (this.preferences.indent_statements_compare_to_body) { this.scribe.indent(); } formatStatements(methodDeclarationScope, statements, true); this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_AT_END_OF_METHOD_DECLARATION); if (this.preferences.indent_statements_compare_to_body) { this.scribe.unIndent(); } } else { if (this.preferences.insert_new_line_in_empty_method_body) { this.scribe.printNewLine(); } if (this.preferences.indent_statements_compare_to_body) { this.scribe.indent(); } this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_AT_END_OF_METHOD_DECLARATION); if (this.preferences.indent_statements_compare_to_body) { this.scribe.unIndent(); } } this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (method_declaration_brace.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) { this.scribe.unIndent(); } } else { // no method body this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.COMPLEX_TRAILING_COMMENT); } return false; } public boolean visit(NormalAnnotation annotation, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNameAT); if (this.preferences.insert_space_after_at_in_annotation) { this.scribe.space(); } this.scribe.printQualifiedReference(annotation.sourceEnd, false/*do not expect parenthesis*/); this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_annotation); if (this.preferences.insert_space_after_opening_paren_in_annotation) { this.scribe.space(); } MemberValuePair[] memberValuePairs = annotation.memberValuePairs; if (memberValuePairs != null) { int length = memberValuePairs.length; Alignment annotationAlignment = this.scribe.createAlignment( Alignment.ANNOTATION_MEMBERS_VALUE_PAIRS, this.preferences.alignment_for_arguments_in_annotation, length, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(annotationAlignment); boolean ok = false; do { try { for (int i = 0; i < length; i++) { if (i > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_annotation); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.alignFragment(annotationAlignment, i); if (i > 0 && this.preferences.insert_space_after_comma_in_annotation) { this.scribe.space(); } memberValuePairs[i].traverse(this, scope); } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(annotationAlignment, true); } this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_annotation); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.NullLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(NullLiteral nullLiteral, BlockScope scope) { final int numberOfParens = (nullLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(nullLiteral, numberOfParens); } this.scribe.printNextToken(TerminalTokens.TokenNamenull); if (numberOfParens > 0) { manageClosingParenthesizedExpression(nullLiteral, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(OR_OR_Expression or_or_Expression, BlockScope scope) { return dumpBinaryExpression(or_or_Expression, TerminalTokens.TokenNameOR_OR, scope); } public boolean visit( ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, BlockScope scope) { final int numberOfParens = (parameterizedQualifiedTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(parameterizedQualifiedTypeReference, numberOfParens); } TypeReference[][] typeArguments = parameterizedQualifiedTypeReference.typeArguments; int length = typeArguments.length; for (int i = 0; i < length; i++) { if (parameterizedQualifiedTypeReference.annotations != null) { formatInlineAnnotations(parameterizedQualifiedTypeReference.annotations[i], false); } this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); TypeReference[] typeArgument = typeArguments[i]; if (typeArgument != null) { int typeArgumentLength = typeArgument.length; if (typeArgumentLength > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference); if (this.preferences.insert_space_after_opening_angle_bracket_in_parameterized_type_reference) { this.scribe.space(); } for (int j = 0; j < typeArgumentLength - 1; j++) { typeArgument[j].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_parameterized_type_reference); if (this.preferences.insert_space_after_comma_in_parameterized_type_reference) { this.scribe.space(); } } typeArgument[typeArgumentLength - 1].traverse(this, scope); if (isClosingGenericToken()) { this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_parameterized_type_reference); } } else { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference); this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS); } } if (i < length - 1) { this.scribe.printNextToken(TerminalTokens.TokenNameDOT); } } formatLeadingDimensions(parameterizedQualifiedTypeReference); if (numberOfParens > 0) { manageClosingParenthesizedExpression(parameterizedQualifiedTypeReference, numberOfParens); } return false; } public boolean visit( ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, ClassScope scope) { final int numberOfParens = (parameterizedQualifiedTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(parameterizedQualifiedTypeReference, numberOfParens); } TypeReference[][] typeArguments = parameterizedQualifiedTypeReference.typeArguments; int length = typeArguments.length; for (int i = 0; i < length; i++) { if (parameterizedQualifiedTypeReference.annotations != null) { formatInlineAnnotations(parameterizedQualifiedTypeReference.annotations[i], false); } this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); TypeReference[] typeArgument = typeArguments[i]; if (typeArgument != null) { int typeArgumentLength = typeArgument.length; if (typeArgumentLength > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference); if (this.preferences.insert_space_after_opening_angle_bracket_in_parameterized_type_reference) { this.scribe.space(); } for (int j = 0; j < typeArgumentLength - 1; j++) { typeArgument[j].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_parameterized_type_reference); if (this.preferences.insert_space_after_comma_in_parameterized_type_reference) { this.scribe.space(); } } typeArgument[typeArgumentLength - 1].traverse(this, scope); if (isClosingGenericToken()) { this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_parameterized_type_reference); } } else { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference); this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS); } } if (i < length - 1) { this.scribe.printNextToken(TerminalTokens.TokenNameDOT); } } formatLeadingDimensions(parameterizedQualifiedTypeReference); if (numberOfParens > 0) { manageClosingParenthesizedExpression(parameterizedQualifiedTypeReference, numberOfParens); } return false; } public boolean visit( ParameterizedSingleTypeReference parameterizedSingleTypeReference, BlockScope scope) { final int numberOfParens = (parameterizedSingleTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(parameterizedSingleTypeReference, numberOfParens); } if (parameterizedSingleTypeReference.annotations != null) { formatInlineAnnotations(parameterizedSingleTypeReference.annotations[0], false); } this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); TypeReference[] typeArguments = parameterizedSingleTypeReference.typeArguments; int typeArgumentsLength = typeArguments.length; if (typeArgumentsLength > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference); if (this.preferences.insert_space_after_opening_angle_bracket_in_parameterized_type_reference) { this.scribe.space(); } for (int i = 0; i < typeArgumentsLength - 1; i++) { typeArguments[i].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_parameterized_type_reference); if (this.preferences.insert_space_after_comma_in_parameterized_type_reference) { this.scribe.space(); } } typeArguments[typeArgumentsLength - 1].traverse(this, scope); if (isClosingGenericToken()) { this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_parameterized_type_reference); } } else { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference); this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS); } formatLeadingDimensions(parameterizedSingleTypeReference); if (numberOfParens > 0) { manageClosingParenthesizedExpression(parameterizedSingleTypeReference, numberOfParens); } return false; } public boolean visit( ParameterizedSingleTypeReference parameterizedSingleTypeReference, ClassScope scope) { final int numberOfParens = (parameterizedSingleTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(parameterizedSingleTypeReference, numberOfParens); } if (parameterizedSingleTypeReference.annotations != null) { formatInlineAnnotations(parameterizedSingleTypeReference.annotations[0], false); } this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); TypeReference[] typeArguments = parameterizedSingleTypeReference.typeArguments; int typeArgumentsLength = typeArguments.length; if (typeArgumentsLength > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference); if (this.preferences.insert_space_after_opening_angle_bracket_in_parameterized_type_reference) { this.scribe.space(); } for (int i = 0; i < typeArgumentsLength - 1; i++) { typeArguments[i].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_parameterized_type_reference); if (this.preferences.insert_space_after_comma_in_parameterized_type_reference) { this.scribe.space(); } } typeArguments[typeArgumentsLength - 1].traverse(this, scope); if (isClosingGenericToken()) { this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_parameterized_type_reference); } } else { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference); this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS); } formatLeadingDimensions(parameterizedSingleTypeReference); if (numberOfParens > 0) { manageClosingParenthesizedExpression(parameterizedSingleTypeReference, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.PostfixExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( PostfixExpression postfixExpression, BlockScope scope) { final int numberOfParens = (postfixExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(postfixExpression, numberOfParens); } postfixExpression.lhs.traverse(this, scope); int operator = postfixExpression.operator == OperatorIds.PLUS ? TerminalTokens.TokenNamePLUS_PLUS : TerminalTokens.TokenNameMINUS_MINUS; this.scribe.printNextToken(operator, this.preferences.insert_space_before_postfix_operator); if (this.preferences.insert_space_after_postfix_operator) { this.scribe.space(); } if (numberOfParens > 0) { manageClosingParenthesizedExpression(postfixExpression, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.PrefixExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(PrefixExpression prefixExpression, BlockScope scope) { final int numberOfParens = (prefixExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(prefixExpression, numberOfParens); } int operator = prefixExpression.operator == OperatorIds.PLUS ? TerminalTokens.TokenNamePLUS_PLUS : TerminalTokens.TokenNameMINUS_MINUS; this.scribe.printNextToken(operator, this.preferences.insert_space_before_prefix_operator); if (this.preferences.insert_space_after_prefix_operator) { this.scribe.space(); } prefixExpression.lhs.traverse(this, scope); if (numberOfParens > 0) { manageClosingParenthesizedExpression(prefixExpression, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( QualifiedAllocationExpression qualifiedAllocationExpression, BlockScope scope) { final int numberOfParens = (qualifiedAllocationExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(qualifiedAllocationExpression, numberOfParens); } final Expression enclosingInstance = qualifiedAllocationExpression.enclosingInstance; if (enclosingInstance != null) { enclosingInstance.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameDOT); } this.scribe.printNextToken(TerminalTokens.TokenNamenew); // used for the new line on wrap style of formatting TypeReference[] typeArguments = qualifiedAllocationExpression.typeArguments; if (typeArguments != null) { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments); if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) { this.scribe.space(); } int length = typeArguments.length; for (int i = 0; i < length - 1; i++) { typeArguments[i].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments); if (this.preferences.insert_space_after_comma_in_type_arguments) { this.scribe.space(); } } typeArguments[length - 1].traverse(this, scope); if (isClosingGenericToken()) { this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments); } if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) { this.scribe.space(); } } else { this.scribe.space(); } final int line = this.scribe.line; qualifiedAllocationExpression.type.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation); final Expression[] arguments = qualifiedAllocationExpression.arguments; if (arguments != null) { if (this.preferences.insert_space_after_opening_paren_in_method_invocation) { this.scribe.space(); } int argumentLength = arguments.length; Alignment argumentsAlignment =this.scribe.createAlignment( Alignment.ALLOCATION, this.preferences.alignment_for_arguments_in_qualified_allocation_expression, argumentLength, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(argumentsAlignment); boolean ok = false; do { try { for (int i = 0; i < argumentLength; i++) { if (i > 0) { this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_allocation_expression); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.alignFragment(argumentsAlignment, i); if (i > 0 && this.preferences.insert_space_after_comma_in_allocation_expression) { this.scribe.space(); } arguments[i].traverse(this, scope); } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(argumentsAlignment, true); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_method_invocation); } else { this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_between_empty_parens_in_method_invocation); } final TypeDeclaration anonymousType = qualifiedAllocationExpression.anonymousType; if (anonymousType != null) { formatLeftCurlyBrace(line, this.preferences.brace_position_for_anonymous_type_declaration); formatAnonymousTypeDeclaration(anonymousType); } if (numberOfParens > 0) { manageClosingParenthesizedExpression(qualifiedAllocationExpression, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( QualifiedNameReference qualifiedNameReference, BlockScope scope) { final int numberOfParens = (qualifiedNameReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(qualifiedNameReference, numberOfParens); } this.scribe.printQualifiedReference(qualifiedNameReference.sourceEnd, numberOfParens>=0/*expect parenthesis*/); if (numberOfParens > 0) { manageClosingParenthesizedExpression(qualifiedNameReference, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( QualifiedSuperReference qualifiedSuperReference, BlockScope scope) { final int numberOfParens = (qualifiedSuperReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(qualifiedSuperReference, numberOfParens); } qualifiedSuperReference.qualification.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameDOT); this.scribe.printNextToken(TerminalTokens.TokenNamesuper); if (numberOfParens > 0) { manageClosingParenthesizedExpression(qualifiedSuperReference, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( QualifiedThisReference qualifiedThisReference, BlockScope scope) { final int numberOfParens = (qualifiedThisReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(qualifiedThisReference, numberOfParens); } qualifiedThisReference.qualification.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameDOT); this.scribe.printNextToken(TerminalTokens.TokenNamethis); if (numberOfParens > 0) { manageClosingParenthesizedExpression(qualifiedThisReference, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( QualifiedTypeReference qualifiedTypeReference, BlockScope scope) { final int numberOfParens = (qualifiedTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(qualifiedTypeReference, numberOfParens); } formatQualifiedTypeReference(qualifiedTypeReference); if (numberOfParens > 0) { manageClosingParenthesizedExpression(qualifiedTypeReference, numberOfParens); } return false; } private void formatQualifiedTypeReference(QualifiedTypeReference qualifiedTypeReference) { for (int i = 0, length = qualifiedTypeReference.tokens.length; i < length; ++i) { if (i != 0) this.scribe.printNextToken(TerminalTokens.TokenNameDOT, false); if (qualifiedTypeReference.annotations != null) { formatInlineAnnotations(qualifiedTypeReference.annotations[i], false); this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, false); } else { this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, false); } } } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference, org.eclipse.jdt.internal.compiler.lookup.ClassScope) */ public boolean visit( QualifiedTypeReference qualifiedTypeReference, ClassScope scope) { final int numberOfParens = (qualifiedTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(qualifiedTypeReference, numberOfParens); } formatQualifiedTypeReference(qualifiedTypeReference); if (numberOfParens > 0) { manageClosingParenthesizedExpression(qualifiedTypeReference, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression referenceExpression, BlockScope blockScope) { referenceExpression.lhs.traverse(this, blockScope); this.scribe.printNextToken(TerminalTokens.TokenNameCOLON_COLON); TypeReference[] typeArguments = referenceExpression.typeArguments; if (typeArguments != null) { this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments); if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) { this.scribe.space(); } int length = typeArguments.length; for (int i = 0; i < length - 1; i++) { typeArguments[i].traverse(this, blockScope); this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments); if (this.preferences.insert_space_after_comma_in_type_arguments) { this.scribe.space(); } } typeArguments[length - 1].traverse(this, blockScope); if (isClosingGenericToken()) { this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments); } if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) { this.scribe.space(); } } this.scribe.printNextToken(referenceExpression.isMethodReference() ? TerminalTokens.TokenNameIdentifier : TerminalTokens.TokenNamenew); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ReturnStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(ReturnStatement returnStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNamereturn); final Expression expression = returnStatement.expression; if (expression != null) { final int numberOfParens = (expression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if ((numberOfParens != 0 && this.preferences.insert_space_before_parenthesized_expression_in_return) || numberOfParens == 0) { this.scribe.space(); } expression.traverse(this, scope); } /* * Print the semi-colon */ this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); return false; } public boolean visit(SingleMemberAnnotation annotation, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNameAT); if (this.preferences.insert_space_after_at_in_annotation) { this.scribe.space(); } this.scribe.printQualifiedReference(annotation.sourceEnd, false/*do not expect parenthesis*/); this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_annotation); if (this.preferences.insert_space_after_opening_paren_in_annotation) { this.scribe.space(); } annotation.memberValue.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_annotation); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.SingleNameReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(SingleNameReference singleNameReference, BlockScope scope) { final int numberOfParens = (singleNameReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(singleNameReference, numberOfParens); } this.scribe.printNextToken(SINGLETYPEREFERENCE_EXPECTEDTOKENS); if (numberOfParens > 0) { manageClosingParenthesizedExpression(singleNameReference, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( SingleTypeReference singleTypeReference, BlockScope scope) { final int numberOfParens = (singleTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(singleTypeReference, numberOfParens); } if (singleTypeReference.annotations != null) { formatInlineAnnotations(singleTypeReference.annotations[0], false); } this.scribe.printNextToken(SINGLETYPEREFERENCE_EXPECTEDTOKENS); if (numberOfParens > 0) { manageClosingParenthesizedExpression(singleTypeReference, numberOfParens); } return false; } private boolean formatInlineAnnotations(final Annotation[] annotations, boolean spaceBefore) { if (annotations != null ) { if (spaceBefore) this.scribe.space(); int length = annotations.length; for (int i = 0; i < length; ++i) { if (i != 0) this.scribe.space(); annotations[i].traverse(this, (BlockScope)null); } if (length > 0 && (!this.isNextTokenPunctuation() || this.isNextToken(TerminalTokens.TokenNameLBRACKET))) { this.scribe.space(); } if (this.scribe.formatter.preferences.insert_new_line_after_type_annotation) { this.scribe.printNewLine(); } return true; } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference, org.eclipse.jdt.internal.compiler.lookup.ClassScope) */ public boolean visit( SingleTypeReference singleTypeReference, ClassScope scope) { final int numberOfParens = (singleTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(singleTypeReference, numberOfParens); } if (singleTypeReference.annotations != null) { formatInlineAnnotations(singleTypeReference.annotations[0], false); } this.scribe.printNextToken(SINGLETYPEREFERENCE_EXPECTEDTOKENS); if (numberOfParens > 0) { manageClosingParenthesizedExpression(singleTypeReference, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.StringLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(StringLiteral stringLiteral, BlockScope scope) { final int numberOfParens = (stringLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(stringLiteral, numberOfParens); } this.scribe.checkNLSTag(stringLiteral.sourceStart); this.scribe.printNextToken(TerminalTokens.TokenNameStringLiteral); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (numberOfParens > 0) { manageClosingParenthesizedExpression(stringLiteral, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.NullLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(StringLiteralConcatenation stringLiteral, BlockScope scope) { final int numberOfParens = (stringLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(stringLiteral, numberOfParens); } this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_IN_STRING_LITERAL_CONCATENATION); ASTNode[] fragments = stringLiteral.literals; int fragmentsSize = stringLiteral.counter; Alignment binaryExpressionAlignment = this.scribe.createAlignment( Alignment.STRING_CONCATENATION, this.preferences.alignment_for_binary_expression, Alignment.R_OUTERMOST, fragmentsSize, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(binaryExpressionAlignment); boolean ok = false; do { try { for (int i = 0; i < fragmentsSize - 1; i++) { ASTNode fragment = fragments[i]; fragment.traverse(this, scope); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (this.scribe.lastNumberOfNewLines == 1) { // a new line has been inserted by printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT) this.scribe.indentationLevel = binaryExpressionAlignment.breakIndentationLevel; } this.scribe.alignFragment(binaryExpressionAlignment, i); this.scribe.printNextToken(TerminalTokens.TokenNamePLUS, this.preferences.insert_space_before_binary_operator); if (this.preferences.insert_space_after_binary_operator) { this.scribe.space(); } } fragments[fragmentsSize - 1].traverse(this, scope); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); ok = true; } catch(AlignmentException e){ this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(binaryExpressionAlignment, true); if (numberOfParens > 0) { manageClosingParenthesizedExpression(stringLiteral, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.SuperReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(SuperReference superReference, BlockScope scope) { final int numberOfParens = (superReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(superReference, numberOfParens); } this.scribe.printNextToken(TerminalTokens.TokenNamesuper); if (numberOfParens > 0) { manageClosingParenthesizedExpression(superReference, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.SwitchStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(SwitchStatement switchStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNameswitch); this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_switch); if (this.preferences.insert_space_after_opening_paren_in_switch) { this.scribe.space(); } switchStatement.expression.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_switch); /* * Type body */ String switch_brace = this.preferences.brace_position_for_switch; formatOpeningBrace(switch_brace, this.preferences.insert_space_before_opening_brace_in_switch); this.scribe.printNewLine(); final Statement[] statements = switchStatement.statements; int switchIndentationLevel = this.scribe.indentationLevel; int caseIndentation = 0; int statementIndentation = 0; int breakIndentation = 0; if (this.preferences.indent_switchstatements_compare_to_switch) { caseIndentation++; statementIndentation++; breakIndentation++; } if (this.preferences.indent_switchstatements_compare_to_cases) { statementIndentation++; } if (this.preferences.indent_breaks_compare_to_cases) { breakIndentation++; } boolean wasACase = false; boolean wasABreak = false; if (statements != null) { int statementsLength = statements.length; for (int i = 0; i < statementsLength; i++) { final Statement statement = statements[i]; if (statement instanceof CaseStatement) { if (wasABreak) { this.scribe.setIndentation(switchIndentationLevel, caseIndentation); this.scribe.printComment(); } else { if (wasACase) { this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_IN_SWITCH_CASE); } else { this.scribe.printComment(); } this.scribe.setIndentation(switchIndentationLevel, caseIndentation); } if (wasACase) { this.scribe.printNewLine(); } statement.traverse(this, scope); // Print following trailing (if any) comment at statement indentation this.scribe.setIndentation(switchIndentationLevel, statementIndentation); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.COMPLEX_TRAILING_COMMENT); wasACase = true; wasABreak = false; } else if (statement instanceof BreakStatement) { this.scribe.setIndentation(switchIndentationLevel, breakIndentation); if (wasACase) { this.scribe.printNewLine(); } this.scribe.printComment(); statement.traverse(this, scope); wasACase = false; wasABreak = true; } else if (statement instanceof Block) { this.scribe.setIndentation(switchIndentationLevel, wasACase ? caseIndentation : statementIndentation); this.scribe.printComment(); String bracePosition = wasACase ? this.preferences.brace_position_for_block_in_case : this.preferences.brace_position_for_block; formatBlock((Block) statement, scope, bracePosition, this.preferences.insert_space_before_opening_brace_in_block); wasACase = false; wasABreak = false; } else { this.scribe.setIndentation(switchIndentationLevel, statementIndentation); this.scribe.printNewLine(); this.scribe.printComment(); statement.traverse(this, scope); wasACase = false; wasABreak = false; } if (statement instanceof Expression) { /* * Print the semi-colon */ this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); this.scribe.printNewLine(); } else if (statement instanceof LocalDeclaration) { LocalDeclaration currentLocal = (LocalDeclaration) statement; if (i < (statementsLength - 1)) { /* * We need to check that the next statement is a local declaration */ if (statements[i + 1] instanceof LocalDeclaration) { LocalDeclaration nextLocal = (LocalDeclaration) statements[i + 1]; if (currentLocal.declarationSourceStart != nextLocal.declarationSourceStart) { /* * Print the semi-colon */ this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); this.scribe.printNewLine(); } } else { /* * Print the semi-colon */ this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); this.scribe.printNewLine(); } } else { /* * Print the semi-colon */ this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); this.scribe.printNewLine(); } } else if (!wasACase) { this.scribe.printNewLine(); } } } this.scribe.printNewLine(); if (wasABreak) { this.scribe.setIndentation(switchIndentationLevel, 0); this.scribe.printComment(); } else { this.scribe.printComment(); this.scribe.setIndentation(switchIndentationLevel, 0); } this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (switch_brace.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) { this.scribe.unIndent(); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( SynchronizedStatement synchronizedStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNamesynchronized); final int line = this.scribe.line; this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_synchronized); if (this.preferences.insert_space_after_opening_paren_in_synchronized) { this.scribe.space(); } synchronizedStatement.expression.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_synchronized); formatLeftCurlyBrace(line, this.preferences.brace_position_for_block); synchronizedStatement.block.traverse(this, scope); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ThisReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(ThisReference thisReference, BlockScope scope) { if (!thisReference.isImplicitThis()) { final int numberOfParens = (thisReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(thisReference, numberOfParens); } this.scribe.printNextToken(TerminalTokens.TokenNamethis); if (numberOfParens > 0) { manageClosingParenthesizedExpression(thisReference, numberOfParens); } } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ThrowStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(ThrowStatement throwStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNamethrow); Expression expression = throwStatement.exception; final int numberOfParens = (expression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if ((numberOfParens > 0 && this.preferences.insert_space_before_parenthesized_expression_in_throw) || numberOfParens == 0) { this.scribe.space(); } expression.traverse(this, scope); /* * Print the semi-colon */ this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.TrueLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(TrueLiteral trueLiteral, BlockScope scope) { final int numberOfParens = (trueLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(trueLiteral, numberOfParens); } this.scribe.printNextToken(TerminalTokens.TokenNametrue); if (numberOfParens > 0) { manageClosingParenthesizedExpression(trueLiteral, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.TryStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(TryStatement tryStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNametry); formatTryResources( tryStatement, this.preferences.insert_space_before_opening_paren_in_try, this.preferences.insert_space_before_closing_paren_in_try, this.preferences.insert_space_after_opening_paren_in_try, this.preferences.insert_space_before_semicolon_in_try_resources, this.preferences.insert_space_after_semicolon_in_try_resources, this.preferences.alignment_for_resources_in_try); tryStatement.tryBlock.traverse(this, scope); if (tryStatement.catchArguments != null) { for (int i = 0, max = tryStatement.catchBlocks.length; i < max; i++) { if (this.preferences.insert_new_line_before_catch_in_try_statement) { this.scribe.printNewLine(); } this.scribe.printNextToken(TerminalTokens.TokenNamecatch, this.preferences.insert_space_after_closing_brace_in_block); final int line = this.scribe.line; this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_catch); if (this.preferences.insert_space_after_opening_paren_in_catch) { this.scribe.space(); } tryStatement.catchArguments[i].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_catch); formatLeftCurlyBrace(line, this.preferences.brace_position_for_block); tryStatement.catchBlocks[i].traverse(this, scope); } } if (tryStatement.finallyBlock != null) { if (this.preferences.insert_new_line_before_finally_in_try_statement) { this.scribe.printNewLine(); } this.scribe.printNextToken(TerminalTokens.TokenNamefinally, this.preferences.insert_space_after_closing_brace_in_block); tryStatement.finallyBlock.traverse(this, scope); } return false; } private void formatMultiCatchArguments(Argument argument, boolean spaceBeforePipe, boolean spaceAfterPipe, int multiCatchAlignment, BlockScope scope) { UnionTypeReference unionType = (UnionTypeReference) argument.type; int length = unionType.typeReferences != null ? unionType.typeReferences.length : 0; if (length > 0) { Alignment argumentsAlignment = this.scribe.createAlignment( Alignment.MULTI_CATCH, multiCatchAlignment, length, this.scribe.scanner.currentPosition); this.scribe.enterAlignment(argumentsAlignment); boolean ok = false; do { switch (multiCatchAlignment & Alignment.SPLIT_MASK) { case Alignment.M_COMPACT_SPLIT: case Alignment.M_NEXT_PER_LINE_SPLIT: argumentsAlignment.startingColumn = this.scribe.column; break; } try { for (int i = 0; i < length; i++) { if (i > 0) { if (this.preferences.wrap_before_or_operator_multicatch) { this.scribe.alignFragment(argumentsAlignment, i); } this.scribe.printNextToken(TerminalTokens.TokenNameOR, spaceBeforePipe); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); if (this.scribe.lastNumberOfNewLines == 1) { // a new line has been inserted while printing the comment // hence we need to use the break indentation level before printing next token... this.scribe.indentationLevel = argumentsAlignment.breakIndentationLevel; } if (!this.preferences.wrap_before_or_operator_multicatch) { this.scribe.alignFragment(argumentsAlignment, i); } } if (i == 0) { this.scribe.alignFragment(argumentsAlignment, i); int fragmentIndentation = argumentsAlignment.fragmentIndentations[0]; if ((argumentsAlignment.mode & Alignment.M_INDENT_ON_COLUMN) != 0 && fragmentIndentation > 0) { this.scribe.indentationLevel = fragmentIndentation; } } else if (spaceAfterPipe) { this.scribe.space(); } unionType.typeReferences[i].traverse(this, scope); argumentsAlignment.startingColumn = -1; } ok = true; } catch (AlignmentException e) { this.scribe.redoAlignment(e); } } while (!ok); this.scribe.exitAlignment(argumentsAlignment, true); } } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( TypeDeclaration localTypeDeclaration, BlockScope scope) { format(localTypeDeclaration); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration, org.eclipse.jdt.internal.compiler.lookup.ClassScope) */ public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) { format(memberTypeDeclaration); return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration, org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope) */ public boolean visit( TypeDeclaration typeDeclaration, CompilationUnitScope scope) { format(typeDeclaration); return false; } public boolean visit(TypeParameter typeParameter, BlockScope scope) { if (typeParameter.annotations != null) { formatInlineAnnotations(typeParameter.annotations, false); } this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); if (typeParameter.type != null) { this.scribe.space(); this.scribe.printNextToken(TerminalTokens.TokenNameextends, true); this.scribe.space(); typeParameter.type.traverse(this, scope); } final TypeReference[] bounds = typeParameter.bounds; if (bounds != null) { this.scribe.printNextToken(TerminalTokens.TokenNameAND, this.preferences.insert_space_before_and_in_type_parameter); if (this.preferences.insert_space_after_and_in_type_parameter) { this.scribe.space(); } int boundsLength = bounds.length; for (int i = 0; i < boundsLength - 1; i++) { bounds[i].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameAND, this.preferences.insert_space_before_and_in_type_parameter); if (this.preferences.insert_space_after_and_in_type_parameter) { this.scribe.space(); } } bounds[boundsLength - 1].traverse(this, scope); } return false; } public boolean visit(TypeParameter typeParameter, ClassScope scope) { if (typeParameter.annotations != null) { formatInlineAnnotations(typeParameter.annotations, false); } this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); if (typeParameter.type != null) { this.scribe.space(); this.scribe.printNextToken(TerminalTokens.TokenNameextends, true); this.scribe.space(); typeParameter.type.traverse(this, scope); } final TypeReference[] bounds = typeParameter.bounds; if (bounds != null) { this.scribe.printNextToken(TerminalTokens.TokenNameAND, this.preferences.insert_space_before_and_in_type_parameter); if (this.preferences.insert_space_after_and_in_type_parameter) { this.scribe.space(); } int boundsLength = bounds.length; for (int i = 0; i < boundsLength - 1; i++) { bounds[i].traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameAND, this.preferences.insert_space_before_and_in_type_parameter); if (this.preferences.insert_space_after_and_in_type_parameter) { this.scribe.space(); } } bounds[boundsLength - 1].traverse(this, scope); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.UnaryExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(UnaryExpression unaryExpression, BlockScope scope) { final int numberOfParens = (unaryExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens > 0) { manageOpeningParenthesizedExpression(unaryExpression, numberOfParens); } /* * Print the operator */ int operator; int operatorValue = (unaryExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT; switch(operatorValue) { case OperatorIds.PLUS: operator = TerminalTokens.TokenNamePLUS; break; case OperatorIds.MINUS: operator = TerminalTokens.TokenNameMINUS; break; case OperatorIds.TWIDDLE: operator = TerminalTokens.TokenNameTWIDDLE; break; default: operator = TerminalTokens.TokenNameNOT; } this.scribe.printNextToken(operator, this.preferences.insert_space_before_unary_operator); if (this.preferences.insert_space_after_unary_operator) { this.scribe.space(); } Expression expression = unaryExpression.expression; if (expression instanceof PrefixExpression) { PrefixExpression prefixExpression = (PrefixExpression) expression; final int numberOfParensForExpression = (prefixExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParensForExpression == 0) { switch(operatorValue) { case OperatorIds.PLUS: if (prefixExpression.operator == OperatorIds.PLUS) { this.scribe.space(); } break; case OperatorIds.MINUS: if (prefixExpression.operator == OperatorIds.MINUS) { this.scribe.space(); } break; } } } else if (expression instanceof UnaryExpression) { UnaryExpression unaryExpression2 = (UnaryExpression) expression; final int numberOfParensForExpression = (unaryExpression2.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParensForExpression == 0) { int operatorValue2 = (unaryExpression2.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT; switch(operatorValue) { case OperatorIds.PLUS: if (operatorValue2 == OperatorIds.PLUS) { this.scribe.space(); } break; case OperatorIds.MINUS: if (operatorValue2 == OperatorIds.MINUS) { this.scribe.space(); } break; } } } expression.traverse(this, scope); if (numberOfParens > 0) { manageClosingParenthesizedExpression(unaryExpression, numberOfParens); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.UnionTypeReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( UnionTypeReference unionTypeReference, BlockScope scope) { TypeReference[] typeReferences = unionTypeReference.typeReferences; for (int i = 0, max = typeReferences.length; i < max; i++) { if (i != 0) { this.scribe.printNextToken(TerminalTokens.TokenNameOR, true); this.scribe.space(); } typeReferences[i].traverse(this, scope); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.UnionTypeReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit( UnionTypeReference unionTypeReference, ClassScope scope) { TypeReference[] typeReferences = unionTypeReference.typeReferences; for (int i = 0, max = typeReferences.length; i < max; i++) { if (i != 0) { this.scribe.printNextToken(TerminalTokens.TokenNameOR, true); this.scribe.space(); } typeReferences[i].traverse(this, scope); } return false; } /** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.WhileStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(WhileStatement whileStatement, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNamewhile); final int line = this.scribe.line; this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_while); if (this.preferences.insert_space_after_opening_paren_in_while) { this.scribe.space(); } whileStatement.condition.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_while); final Statement action = whileStatement.action; if (action != null) { if (action instanceof Block) { formatLeftCurlyBrace(line, this.preferences.brace_position_for_block); action.traverse(this, scope); } else if (action instanceof EmptyStatement) { /* * This is an empty statement */ formatNecessaryEmptyStatement(); } else { this.scribe.printNewLine(); this.scribe.indent(); action.traverse(this, scope); if (action instanceof Expression) { this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon); this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT); } this.scribe.unIndent(); } } else { /* * This is an empty statement */ formatNecessaryEmptyStatement(); } return false; } public boolean visit(Wildcard wildcard, BlockScope scope) { if (wildcard.annotations != null) { if (formatInlineAnnotations(wildcard.annotations[0], false)) this.scribe.space(); } this.scribe.printNextToken(TerminalTokens.TokenNameQUESTION, this.preferences.insert_space_before_question_in_wilcard); switch(wildcard.kind) { case Wildcard.SUPER : this.scribe.printNextToken(TerminalTokens.TokenNamesuper, true); this.scribe.space(); wildcard.bound.traverse(this, scope); break; case Wildcard.EXTENDS : this.scribe.printNextToken(TerminalTokens.TokenNameextends, true); this.scribe.space(); wildcard.bound.traverse(this, scope); break; case Wildcard.UNBOUND : if (this.preferences.insert_space_after_question_in_wilcard) { this.scribe.space(); } } return false; } public boolean visit(Wildcard wildcard, ClassScope scope) { if (wildcard.annotations != null) { if (formatInlineAnnotations(wildcard.annotations[0], false)) this.scribe.space(); } this.scribe.printNextToken(TerminalTokens.TokenNameQUESTION, this.preferences.insert_space_before_question_in_wilcard); switch(wildcard.kind) { case Wildcard.SUPER : this.scribe.printNextToken(TerminalTokens.TokenNamesuper, true); this.scribe.space(); wildcard.bound.traverse(this, scope); break; case Wildcard.EXTENDS : this.scribe.printNextToken(TerminalTokens.TokenNameextends, true); this.scribe.space(); wildcard.bound.traverse(this, scope); break; case Wildcard.UNBOUND : if (this.preferences.insert_space_after_question_in_wilcard) { this.scribe.space(); } } return false; } }