X-Git-Url: http://secure.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaIndenter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaIndenter.java index 39a3b29..d6b5cf1 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaIndenter.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaIndenter.java @@ -15,20 +15,23 @@ import net.sourceforge.phpdt.core.formatter.DefaultCodeFormatterConstants; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import org.eclipse.core.runtime.Plugin; -import org.eclipse.jface.text.Assert; +//incastrix +//import org.eclipse.jface.text.Assert; +import org.eclipse.core.runtime.Assert; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.TextUtilities; import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; - /** * Uses the {@link net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner}to * get the indentation level for a certain position in a document. * *

- * An instance holds some internal position in the document and is therefore - * not threadsafe. + * An instance holds some internal position in the document and is therefore not + * threadsafe. *

* * @since 3.0 @@ -37,82 +40,97 @@ public class JavaIndenter { /** The document being scanned. */ private IDocument fDocument; + /** The indentation accumulated by findPreviousIndenationUnit. */ private int fIndent; + /** * The absolute (character-counted) indentation offset for special cases * (method defs, array initializers) */ private int fAlign; + /** The stateful scanposition for the indentation methods. */ private int fPosition; + /** The previous position. */ private int fPreviousPos; + /** The most recent token. */ private int fToken; + /** The line of fPosition. */ private int fLine; + /** - * The scanner we will use to scan the document. It has to be installed - * on the same document as the one we get. + * The scanner we will use to scan the document. It has to be installed on + * the same document as the one we get. */ private JavaHeuristicScanner fScanner; - + /** * Creates a new instance. * - * @param document the document to scan - * @param scanner the {@link JavaHeuristicScanner} to be used for scanning - * the document. It must be installed on the same IDocument. + * @param document + * the document to scan + * @param scanner + * the {@link JavaHeuristicScanner} to be used for scanning the + * document. It must be installed on the same + * IDocument. */ public JavaIndenter(IDocument document, JavaHeuristicScanner scanner) { Assert.isNotNull(document); Assert.isNotNull(scanner); - fDocument= document; - fScanner= scanner; + fDocument = document; + fScanner = scanner; } - + /** * Computes the indentation at the reference point of position. * - * @param offset the offset in the document + * @param offset + * the offset in the document * @return a String which reflects the indentation at the line in which the - * reference position to offset resides, or null - * if it cannot be determined + * reference position to offset resides, or + * null if it cannot be determined */ - public StringBuffer getReferenceIndentation(int offset) { - return getReferenceIndentation(offset, false); - } - +// public StringBuffer getReferenceIndentation(int offset) { +// return getReferenceIndentation(offset, false); +// } + /** * Computes the indentation at the reference point of position. * - * @param offset the offset in the document - * @param assumeOpeningBrace true if an opening brace should be assumed + * @param offset + * the offset in the document + * @param assumeOpeningBrace + * true if an opening brace should be assumed * @return a String which reflects the indentation at the line in which the - * reference position to offset resides, or null - * if it cannot be determined + * reference position to offset resides, or + * null if it cannot be determined */ - private StringBuffer getReferenceIndentation(int offset, boolean assumeOpeningBrace) { + private StringBuffer getReferenceIndentation(int offset, + boolean assumeOpeningBrace) { int unit; if (assumeOpeningBrace) - unit= findReferencePosition(offset, Symbols.TokenLBRACE); + unit = findReferencePosition(offset, Symbols.TokenLBRACE); else - unit= findReferencePosition(offset, peekChar(offset)); - + unit = findReferencePosition(offset, peekChar(offset)); + // if we were unable to find anything, return null if (unit == JavaHeuristicScanner.NOT_FOUND) return null; - + return getLeadingWhitespace(unit); - + } - + /** * Computes the indentation at offset. * - * @param offset the offset in the document + * @param offset + * the offset in the document * @return a String which reflects the correct indentation for the line in * which offset resides, or null if it cannot be * determined @@ -120,58 +138,65 @@ public class JavaIndenter { public StringBuffer computeIndentation(int offset) { return computeIndentation(offset, false); } - + /** * Computes the indentation at offset. * - * @param offset the offset in the document - * @param assumeOpeningBrace true if an opening brace should be assumed + * @param offset + * the offset in the document + * @param assumeOpeningBrace + * true if an opening brace should be assumed * @return a String which reflects the correct indentation for the line in * which offset resides, or null if it cannot be * determined */ - public StringBuffer computeIndentation(int offset, boolean assumeOpeningBrace) { - - StringBuffer indent= getReferenceIndentation(offset, assumeOpeningBrace); - + public StringBuffer computeIndentation(int offset, + boolean assumeOpeningBrace) { + + StringBuffer indent = getReferenceIndentation(offset, + assumeOpeningBrace); + // handle special alignment if (fAlign != JavaHeuristicScanner.NOT_FOUND) { try { // a special case has been detected. - IRegion line= fDocument.getLineInformationOfOffset(fAlign); - int lineOffset= line.getOffset(); + IRegion line = fDocument.getLineInformationOfOffset(fAlign); + int lineOffset = line.getOffset(); return createIndent(lineOffset, fAlign); } catch (BadLocationException e) { return null; } } - + if (indent == null) return null; - + // add additional indent - indent.append(createIndent(fIndent)); + //indent.append(createIndent(fIndent)); + indent.insert(0, createIndent(fIndent)); if (fIndent < 0) unindent(indent); - + return indent; } /** * Returns the indentation of the line at offset as a - * StringBuffer. If the offset is not valid, the empty string - * is returned. + * StringBuffer. If the offset is not valid, the empty + * string is returned. * - * @param offset the offset in the document + * @param offset + * the offset in the document * @return the indentation (leading whitespace) of the line in which - * offset is located + * offset is located */ private StringBuffer getLeadingWhitespace(int offset) { - StringBuffer indent= new StringBuffer(); + StringBuffer indent = new StringBuffer(); try { - IRegion line= fDocument.getLineInformationOfOffset(offset); - int lineOffset= line.getOffset(); - int nonWS= fScanner.findNonWhitespaceForwardInAnyPartition(lineOffset, lineOffset + line.getLength()); + IRegion line = fDocument.getLineInformationOfOffset(offset); + int lineOffset = line.getOffset(); + int nonWS = fScanner.findNonWhitespaceForwardInAnyPartition( + lineOffset, lineOffset + line.getLength()); indent.append(fDocument.get(lineOffset, nonWS - lineOffset)); return indent; } catch (BadLocationException e) { @@ -182,14 +207,15 @@ public class JavaIndenter { /** * Reduces indentation in indent by one indentation unit. * - * @param indent the indentation to be modified + * @param indent + * the indentation to be modified */ private void unindent(StringBuffer indent) { - CharSequence oneIndent= createIndent(); - int i= indent.lastIndexOf(oneIndent.toString()); //$NON-NLS-1$ + CharSequence oneIndent = createIndent(); + int i = indent.lastIndexOf(oneIndent.toString()); //$NON-NLS-1$ if (i != -1) { indent.delete(i, i + oneIndent.length()); - } + } } /** @@ -198,33 +224,35 @@ public class JavaIndenter { * [start, indent), with every character replaced by a space except for * tabs, which are kept as such. * - *

Every run of the number of spaces that make up a tab are replaced - * by a tab character.

+ *

+ * Every run of the number of spaces that make up a tab are replaced by a + * tab character. + *

* * @return the indentation corresponding to the document content specified * by start and indent */ private StringBuffer createIndent(int start, int indent) { - final int tabLen= prefTabLength(); - StringBuffer ret= new StringBuffer(); + final int tabLen = prefTabLength(); + StringBuffer ret = new StringBuffer(); try { - int spaces= 0; + int spaces = 0; while (start < indent) { - - char ch= fDocument.getChar(start); + + char ch = fDocument.getChar(start); if (ch == '\t') { ret.append('\t'); - spaces= 0; - } else if (tabLen == -1){ + spaces = 0; + } else if (tabLen == -1) { ret.append(' '); } else { spaces++; if (spaces == tabLen) { ret.append('\t'); - spaces= 0; + spaces = 0; } } - + start++; } // remainder @@ -233,10 +261,10 @@ public class JavaIndenter { else while (spaces-- > 0) ret.append(' '); - + } catch (BadLocationException e) { } - + return ret; } @@ -244,39 +272,46 @@ public class JavaIndenter { * Creates a string that represents the given number of indents (can be * spaces or tabs..) * - * @param indent the requested indentation level. + * @param indent + * the requested indentation level. * * @return the indentation specified by indent */ - private StringBuffer createIndent(int indent) { - StringBuffer oneIndent= createIndent(); + public StringBuffer createIndent(int indent) { + StringBuffer oneIndent = createIndent(); - StringBuffer ret= new StringBuffer(); + StringBuffer ret = new StringBuffer(); while (indent-- > 0) ret.append(oneIndent); - + return ret; } - + /** - * Creates a string that represents one indent (can be - * spaces or tabs..) + * Creates a string that represents one indent (can be spaces or tabs..) * * @return one indentation */ private StringBuffer createIndent() { - // get a sensible default when running without the infrastructure for testing - StringBuffer oneIndent= new StringBuffer(); -// JavaCore plugin= JavaCore.getJavaCore(); + // get a sensible default when running without the infrastructure for + // testing + StringBuffer oneIndent = new StringBuffer(); + // JavaCore plugin= JavaCore.getJavaCore(); PHPeclipsePlugin plugin = PHPeclipsePlugin.getDefault(); if (plugin == null) { oneIndent.append('\t'); } else { - if (JavaCore.SPACE.equals(JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR))) { - int tabLen= Integer.parseInt(JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE)); - for (int i= 0; i < tabLen; i++) + if (JavaCore.SPACE + .equals(JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR))) { + int tabLen = Integer + .parseInt(JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE)); + for (int i = 0; i < tabLen; i++) oneIndent.append(' '); - } else if (JavaCore.TAB.equals(JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR))) + } else if (JavaCore.TAB + .equals(JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR))) oneIndent.append('\t'); else oneIndent.append('\t'); // default @@ -285,654 +320,733 @@ public class JavaIndenter { } /** - * Returns the reference position regarding to indentation for offset, - * or NOT_FOUND. This method calls - * {@link #findReferencePosition(int, int) findReferencePosition(offset, nextChar)} where - * nextChar is the next character after offset. + * Returns the reference position regarding to indentation for + * offset, or NOT_FOUND. This method calls + * {@link #findReferencePosition(int, int) findReferencePosition(offset, nextChar)} + * where nextChar is the next character after + * offset. * - * @param offset the offset for which the reference is computed + * @param offset + * the offset for which the reference is computed * @return the reference statement relative to which offset * should be indented, or {@link JavaHeuristicScanner#NOT_FOUND} */ - public int findReferencePosition(int offset) { - return findReferencePosition(offset, peekChar(offset)); - } - +// public int findReferencePosition(int offset) { +// return findReferencePosition(offset, peekChar(offset)); +// } + /** * Peeks the next char in the document that comes after offset * on the same line as offset. * - * @param offset the offset into document - * @return the token symbol of the next element, or TokenEOF if there is none + * @param offset + * the offset into document + * @return the token symbol of the next element, or TokenEOF if there is + * none */ private int peekChar(int offset) { if (offset < fDocument.getLength()) { try { - IRegion line= fDocument.getLineInformationOfOffset(offset); - int lineOffset= line.getOffset(); - int next= fScanner.nextToken(offset, lineOffset + line.getLength()); + IRegion line = fDocument.getLineInformationOfOffset(offset); + int lineOffset = line.getOffset(); + int next = fScanner.nextToken(offset, lineOffset + + line.getLength()); return next; } catch (BadLocationException e) { } } return Symbols.TokenEOF; } - + /** - * Returns the reference position regarding to indentation for position, - * or NOT_FOUND. + * Returns the reference position regarding to indentation for + * position, or NOT_FOUND. * - *

If peekNextChar is true, the next token after - * offset is read and taken into account when computing the - * indentation. Currently, if the next token is the first token on the line - * (i.e. only preceded by whitespace), the following tokens are specially - * handled: + *

+ * If peekNextChar is true, the next token + * after offset is read and taken into account when computing + * the indentation. Currently, if the next token is the first token on the + * line (i.e. only preceded by whitespace), the following tokens are + * specially handled: *

* - * @param offset the offset for which the reference is computed - * @param nextToken the next token to assume in the document + * @param offset + * the offset for which the reference is computed + * @param nextToken + * the next token to assume in the document * @return the reference statement relative to which offset * should be indented, or {@link JavaHeuristicScanner#NOT_FOUND} */ public int findReferencePosition(int offset, int nextToken) { - boolean danglingElse= false; - boolean unindent= false; - boolean indent= false; - boolean matchBrace= false; - boolean matchParen= false; - boolean matchCase= false; - - // account for unindenation characters already typed in, but after position + boolean danglingElse = false; + boolean unindent = false; + boolean indent = false; + boolean matchBrace = false; + boolean matchParen = false; + boolean matchCase = false; + + // account for unindenation characters already typed in, but after + // position // if they are on a line by themselves, the indentation gets adjusted // accordingly // - // also account for a dangling else + // also account for a dangling else if (offset < fDocument.getLength()) { try { - IRegion line= fDocument.getLineInformationOfOffset(offset); - int lineOffset= line.getOffset(); - int prevPos= Math.max(offset - 1, 0); - boolean isFirstTokenOnLine= fDocument.get(lineOffset, prevPos + 1 - lineOffset).trim().length() == 0; - int prevToken= fScanner.previousToken(prevPos, JavaHeuristicScanner.UNBOUND); - boolean bracelessBlockStart= fScanner.isBracelessBlockStart(prevPos, JavaHeuristicScanner.UNBOUND); - - switch (nextToken) { - case Symbols.TokenEOF: - case Symbols.TokenELSE: - danglingElse= true; - break; - case Symbols.TokenCASE: - case Symbols.TokenDEFAULT: - if (isFirstTokenOnLine) - matchCase= true; - break; - case Symbols.TokenLBRACE: // for opening-brace-on-new-line style -// if (bracelessBlockStart && !prefIndentBracesForBlocks()) -// unindent= true; -// else if ((prevToken == Symbols.TokenCOLON || prevToken == Symbols.TokenEQUAL || prevToken == Symbols.TokenRBRACKET) && !prefIndentBracesForArrays()) -// unindent= true; -// else if (!bracelessBlockStart && prefIndentBracesForMethods()) -// indent= true; -// break; - if (bracelessBlockStart ) - unindent= true; - else if ((prevToken == Symbols.TokenCOLON || prevToken == Symbols.TokenEQUAL || prevToken == Symbols.TokenRBRACKET) ) - unindent= true; - else if (!bracelessBlockStart) - indent= true; - break; - case Symbols.TokenRBRACE: // closing braces get unindented - if (isFirstTokenOnLine) - matchBrace= true; - break; - case Symbols.TokenRPAREN: - if (isFirstTokenOnLine) - matchParen= true; - break; + IRegion line = fDocument.getLineInformationOfOffset(offset); + int lineOffset = line.getOffset(); + int prevPos = Math.max(offset - 1, 0); + boolean isFirstTokenOnLine = fDocument.get(lineOffset, + prevPos + 1 - lineOffset).trim().length() == 0; + int prevToken = fScanner.previousToken(prevPos, + JavaHeuristicScanner.UNBOUND); + if (prevToken == Symbols.TokenEOF && nextToken == Symbols.TokenEOF) { + ITypedRegion partition = TextUtilities.getPartition(fDocument, IPHPPartitions.PHP_PARTITIONING, offset, true); + if (partition.getType().equals(IPHPPartitions.PHP_SINGLELINE_COMMENT)) { + fAlign = fScanner.getPosition(); + } else { + fAlign = JavaHeuristicScanner.NOT_FOUND; } + return JavaHeuristicScanner.NOT_FOUND; + } + boolean bracelessBlockStart = fScanner.isBracelessBlockStart( + prevPos, JavaHeuristicScanner.UNBOUND); + + switch (nextToken) { + case Symbols.TokenEOF: + case Symbols.TokenELSE: + danglingElse = true; + break; + case Symbols.TokenCASE: + case Symbols.TokenDEFAULT: + if (isFirstTokenOnLine) + matchCase = true; + break; + case Symbols.TokenLBRACE: // for opening-brace-on-new-line + // style + // if (bracelessBlockStart && !prefIndentBracesForBlocks()) + // unindent= true; + // else if ((prevToken == Symbols.TokenCOLON || prevToken == + // Symbols.TokenEQUAL || prevToken == Symbols.TokenRBRACKET) && + // !prefIndentBracesForArrays()) + // unindent= true; + // else if (!bracelessBlockStart && + // prefIndentBracesForMethods()) + // indent= true; + // break; + if (bracelessBlockStart) + unindent = true; + else if ((prevToken == Symbols.TokenCOLON + || prevToken == Symbols.TokenEQUAL || prevToken == Symbols.TokenRBRACKET)) + unindent = true; + else if (!bracelessBlockStart) + indent = true; + break; + case Symbols.TokenRBRACE: // closing braces get unindented + if (isFirstTokenOnLine) + matchBrace = true; + break; + case Symbols.TokenRPAREN: + if (isFirstTokenOnLine) + matchParen = true; + break; + } } catch (BadLocationException e) { } } else { // assume an else could come if we are at the end of file - danglingElse= true; + danglingElse = true; } - - int ref= findReferencePosition(offset, danglingElse, matchBrace, matchParen, matchCase); + + int ref = findReferencePosition(offset, danglingElse, matchBrace, + matchParen, matchCase); if (unindent) fIndent--; if (indent) fIndent++; return ref; } - + /** - * Returns the reference position regarding to indentation for position, - * or NOT_FOUND.fIndent will contain the - * relative indentation (in indentation units, not characters) after the - * call. If there is a special alignment (e.g. for a method declaration - * where parameters should be aligned), fAlign will contain - * the absolute position of the alignment reference in fDocument, - * otherwise fAlign is set to JavaHeuristicScanner.NOT_FOUND. + * Returns the reference position regarding to indentation for + * position, or NOT_FOUND.fIndent + * will contain the relative indentation (in indentation units, not + * characters) after the call. If there is a special alignment (e.g. for a + * method declaration where parameters should be aligned), + * fAlign will contain the absolute position of the alignment + * reference in fDocument, otherwise fAlign + * is set to JavaHeuristicScanner.NOT_FOUND. * - * @param offset the offset for which the reference is computed - * @param danglingElse whether a dangling else should be assumed at position - * @param matchBrace whether the position of the matching brace should be + * @param offset + * the offset for which the reference is computed + * @param danglingElse + * whether a dangling else should be assumed at + * position + * @param matchBrace + * whether the position of the matching brace should be returned + * instead of doing code analysis + * @param matchParen + * whether the position of the matching parenthesis should be * returned instead of doing code analysis - * @param matchParen whether the position of the matching parenthesis - * should be returned instead of doing code analysis - * @param matchCase whether the position of a switch statement reference - * should be returned (either an earlier case statement or the - * switch block brace) + * @param matchCase + * whether the position of a switch statement reference should be + * returned (either an earlier case statement or the switch block + * brace) * @return the reference statement relative to which position * should be indented, or {@link JavaHeuristicScanner#NOT_FOUND} */ - public int findReferencePosition(int offset, boolean danglingElse, boolean matchBrace, boolean matchParen, boolean matchCase) { - fIndent= 0; // the indentation modification - fAlign= JavaHeuristicScanner.NOT_FOUND; - fPosition= offset; - + public int findReferencePosition(int offset, boolean danglingElse, + boolean matchBrace, boolean matchParen, boolean matchCase) { + fIndent = 0; // the indentation modification + fAlign = JavaHeuristicScanner.NOT_FOUND; + fPosition = offset; + // forward cases - // an unindentation happens sometimes if the next token is special, namely on braces, parens and case labels - // align braces, but handle the case where we align with the method declaration start instead of + // an unindentation happens sometimes if the next token is special, + // namely on braces, parens and case labels + // align braces, but handle the case where we align with the method + // declaration start instead of // the opening brace. -// if (matchBrace) { -// if (skipScope(Symbols.TokenLBRACE, Symbols.TokenRBRACE)) { -// try { -// // align with the opening brace that is on a line by its own -// int lineOffset= fDocument.getLineOffset(fLine); -// if (lineOffset <= fPosition && fDocument.get(lineOffset, fPosition - lineOffset).trim().length() == 0) -// return fPosition; -// } catch (BadLocationException e) { -// // concurrent modification - walk default path -// } -// // if the opening brace is not on the start of the line, skip to the start -// int pos= skipToStatementStart(true, true); -// fIndent= 0; // indent is aligned with reference position -// return pos; -// } else { -// // if we can't find the matching brace, the heuristic is to unindent -// // by one against the normal position -// int pos= findReferencePosition(offset, danglingElse, false, matchParen, matchCase); -// fIndent--; -// return pos; -// } -// } - + if (matchBrace) { + if (skipScope(Symbols.TokenLBRACE, Symbols.TokenRBRACE)) { + try { + // align with the opening brace that is on a line by its own + int lineOffset = fDocument.getLineOffset(fLine); + if (lineOffset <= fPosition + && fDocument + .get(lineOffset, fPosition - lineOffset) + .trim().length() == 0) + return fPosition; + } catch (BadLocationException e) { + // concurrent modification - walk default path + } + // if the opening brace is not on the start of the line, skip to + // the start + int pos = skipToStatementStart(true, true); + fIndent = 0; // indent is aligned with reference position + return pos; + } else { + // if we can't find the matching brace, the heuristic is to + // unindent + // by one against the normal position + int pos = findReferencePosition(offset, danglingElse, false, + matchParen, matchCase); + fIndent--; + return pos; + } + } + // align parenthesis' if (matchParen) { if (skipScope(Symbols.TokenLPAREN, Symbols.TokenRPAREN)) return fPosition; else { - // if we can't find the matching paren, the heuristic is to unindent + // if we can't find the matching paren, the heuristic is to + // unindent // by one against the normal position - int pos= findReferencePosition(offset, danglingElse, matchBrace, false, matchCase); + int pos = findReferencePosition(offset, danglingElse, + matchBrace, false, matchCase); fIndent--; return pos; } } - - // the only reliable way to get case labels aligned (due to many different styles of using braces in a block) + + // the only reliable way to get case labels aligned (due to many + // different styles of using braces in a block) // is to go for another case statement, or the scope opening brace -// if (matchCase) { -// return matchCaseAlignment(); -// } - + if (matchCase) { + return matchCaseAlignment(); + } + nextToken(); switch (fToken) { - case Symbols.TokenRBRACE: - // skip the block and fall through - // if we can't complete the scope, reset the scan position - int pos= fPosition; - if (!skipScope()) - fPosition= pos; - case Symbols.TokenSEMICOLON: - // this is the 90% case: after a statement block - // the end of the previous statement / block previous.end - // search to the end of the statement / block before the previous; the token just after that is previous.start - return skipToStatementStart(danglingElse, false); - + case Symbols.TokenRBRACE: + // skip the block and fall through + // if we can't complete the scope, reset the scan position + int pos = fPosition; + if (!skipScope()) + fPosition = pos; + case Symbols.TokenSEMICOLON: + // this is the 90% case: after a statement block + // the end of the previous statement / block previous.end + // search to the end of the statement / block before the previous; + // the token just after that is previous.start + return skipToStatementStart(danglingElse, false); + // scope introduction: special treat who special is - case Symbols.TokenLPAREN: - case Symbols.TokenLBRACE: - case Symbols.TokenLBRACKET: - return handleScopeIntroduction(offset + 1); - - case Symbols.TokenEOF: - // trap when hitting start of document - return 0; - - case Symbols.TokenEQUAL: - // indent assignments - fIndent= prefAssignmentIndent(); + case Symbols.TokenLPAREN: + case Symbols.TokenLBRACE: + case Symbols.TokenLBRACKET: + return handleScopeIntroduction(offset + 1); + + case Symbols.TokenEOF: + // trap when hitting start of document + return 0; + + case Symbols.TokenEQUAL: + // indent assignments + fIndent = prefAssignmentIndent(); + return fPosition; + + case Symbols.TokenCOLON: + // TODO handle ternary deep indentation + fIndent = prefCaseBlockIndent(); + return fPosition; + + case Symbols.TokenQUESTIONMARK: + if (prefTernaryDeepAlign()) { + setFirstElementAlignment(fPosition, offset + 1); return fPosition; - - case Symbols.TokenCOLON: - // TODO handle ternary deep indentation - fIndent= prefCaseBlockIndent(); + } else { + fIndent = prefTernaryIndent(); return fPosition; - - case Symbols.TokenQUESTIONMARK: - if (prefTernaryDeepAlign()) { - setFirstElementAlignment(fPosition, offset + 1); - return fPosition; - } else { - fIndent= prefTernaryIndent(); + } + + // indentation for blockless introducers: + case Symbols.TokenDO: + case Symbols.TokenWHILE: + case Symbols.TokenELSE: + fIndent = prefSimpleIndent(); + return fPosition; + case Symbols.TokenRPAREN: + int line = fLine; + if (skipScope(Symbols.TokenLPAREN, Symbols.TokenRPAREN)) { + int scope = fPosition; + nextToken(); + if (fToken == Symbols.TokenIF || fToken == Symbols.TokenWHILE + || fToken == Symbols.TokenFOR) { + fIndent = prefSimpleIndent(); return fPosition; } - - // indentation for blockless introducers: - case Symbols.TokenDO: - case Symbols.TokenWHILE: - case Symbols.TokenELSE: - fIndent= prefSimpleIndent(); - return fPosition; - case Symbols.TokenRPAREN: - int line= fLine; - if (skipScope(Symbols.TokenLPAREN, Symbols.TokenRPAREN)) { - int scope= fPosition; - nextToken(); - if (fToken == Symbols.TokenIF || fToken == Symbols.TokenWHILE || fToken == Symbols.TokenFOR) { - fIndent= prefSimpleIndent(); - return fPosition; - } - fPosition= scope; - if (looksLikeMethodDecl()) { - return skipToStatementStart(danglingElse, false); - } + fPosition = scope; + if (looksLikeMethodDecl()) { + return skipToStatementStart(danglingElse, false); } - // restore - fPosition= offset; - fLine= line; - // else: fall through to default - - case Symbols.TokenCOMMA: - // inside a list of some type - // easy if there is already a list item before with its own indentation - we just align - // if not: take the start of the list ( LPAREN, LBRACE, LBRACKET ) and either align or - // indent by list-indent - default: - // inside whatever we don't know about: similar to the list case: - // if we are inside a continued expression, then either align with a previous line that has indentation - // or indent from the expression start line (either a scope introducer or the start of the expr). - return skipToPreviousListItemOrListStart(); - + } + // restore + fPosition = offset; + fLine = line; + // else: fall through to default + + case Symbols.TokenCOMMA: + // inside a list of some type + // easy if there is already a list item before with its own + // indentation - we just align + // if not: take the start of the list ( LPAREN, LBRACE, LBRACKET ) + // and either align or + // indent by list-indent + default: + // inside whatever we don't know about: similar to the list case: + // if we are inside a continued expression, then either align with a + // previous line that has indentation + // or indent from the expression start line (either a scope + // introducer or the start of the expr). + return skipToPreviousListItemOrListStart(); + } } /** * Skips to the start of a statement that ends at the current position. * - * @param danglingElse whether to indent aligned with the last if - * @param isInBlock whether the current position is inside a block, which limits the search scope to the next scope introducer - * @return the reference offset of the start of the statement + * @param danglingElse + * whether to indent aligned with the last if + * @param isInBlock + * whether the current position is inside a block, which limits + * the search scope to the next scope introducer + * @return the reference offset of the start of the statement */ private int skipToStatementStart(boolean danglingElse, boolean isInBlock) { while (true) { nextToken(); - + if (isInBlock) { switch (fToken) { - // exit on all block introducers - case Symbols.TokenIF: - case Symbols.TokenELSE: - case Symbols.TokenSYNCHRONIZED: - case Symbols.TokenCOLON: - case Symbols.TokenSTATIC: - case Symbols.TokenCATCH: - case Symbols.TokenDO: - case Symbols.TokenWHILE: - case Symbols.TokenFINALLY: - case Symbols.TokenFOR: - case Symbols.TokenTRY: - return fPosition; - - case Symbols.TokenSWITCH: - fIndent= prefCaseIndent(); - return fPosition; + // exit on all block introducers + case Symbols.TokenIF: + case Symbols.TokenELSE: + case Symbols.TokenSYNCHRONIZED: + case Symbols.TokenCOLON: + case Symbols.TokenSTATIC: + case Symbols.TokenCATCH: + case Symbols.TokenDO: + case Symbols.TokenWHILE: + case Symbols.TokenFINALLY: + case Symbols.TokenFOR: + case Symbols.TokenTRY: + return fPosition; + + case Symbols.TokenSWITCH: + fIndent = prefCaseIndent(); + return fPosition; } } - + switch (fToken) { - // scope introduction through: LPAREN, LBRACE, LBRACKET - // search stop on SEMICOLON, RBRACE, COLON, EOF - // -> the next token is the start of the statement (i.e. previousPos when backward scanning) - case Symbols.TokenLPAREN: - case Symbols.TokenLBRACE: - case Symbols.TokenLBRACKET: - case Symbols.TokenSEMICOLON: - case Symbols.TokenEOF: - return fPreviousPos; - - case Symbols.TokenCOLON: - int pos= fPreviousPos; - if (!isConditional()) - return pos; - break; - - case Symbols.TokenRBRACE: - // RBRACE is a little tricky: it can be the end of an array definition, but - // usually it is the end of a previous block - pos= fPreviousPos; // store state - if (skipScope() && looksLikeArrayInitializerIntro()) - continue; // it's an array - else - return pos; // it's not - do as with all the above - + // scope introduction through: LPAREN, LBRACE, LBRACKET + // search stop on SEMICOLON, RBRACE, COLON, EOF + // -> the next token is the start of the statement (i.e. previousPos + // when backward scanning) + case Symbols.TokenLPAREN: + case Symbols.TokenLBRACE: + case Symbols.TokenLBRACKET: + case Symbols.TokenSEMICOLON: + case Symbols.TokenEOF: + return fPreviousPos; + + case Symbols.TokenCOLON: + int pos = fPreviousPos; + if (!isConditional()) + return pos; + break; + + case Symbols.TokenRBRACE: + // RBRACE is a little tricky: it can be the end of an array + // definition, but + // usually it is the end of a previous block + pos = fPreviousPos; // store state + if (skipScope() && looksLikeArrayInitializerIntro()) + continue; // it's an array + else + return pos; // it's not - do as with all the above + // scopes: skip them - case Symbols.TokenRPAREN: - case Symbols.TokenRBRACKET: - pos= fPreviousPos; - if (skipScope()) - break; - else - return pos; - - // IF / ELSE: align the position after the conditional block with the if + case Symbols.TokenRPAREN: + case Symbols.TokenRBRACKET: + pos = fPreviousPos; + if (skipScope()) + break; + else + return pos; + + // IF / ELSE: align the position after the conditional block + // with the if // so we are ready for an else, except if danglingElse is false // in order for this to work, we must skip an else to its if - case Symbols.TokenIF: - if (danglingElse) - return fPosition; - else - break; - case Symbols.TokenELSE: - // skip behind the next if, as we have that one covered - pos= fPosition; - if (skipNextIF()) - break; - else - return pos; - - case Symbols.TokenDO: - // align the WHILE position with its do + case Symbols.TokenIF: + if (danglingElse) return fPosition; - - case Symbols.TokenWHILE: - // this one is tricky: while can be the start of a while loop - // or the end of a do - while - pos= fPosition; - if (hasMatchingDo()) { - // continue searching from the DO on - break; - } else { - // continue searching from the WHILE on - fPosition= pos; - break; - } - default: - // keep searching - + else + break; + case Symbols.TokenELSE: + // skip behind the next if, as we have that one covered + pos = fPosition; + if (skipNextIF()) + break; + else + return pos; + + case Symbols.TokenDO: + // align the WHILE position with its do + return fPosition; + + case Symbols.TokenWHILE: + // this one is tricky: while can be the start of a while loop + // or the end of a do - while + pos = fPosition; + if (hasMatchingDo()) { + // continue searching from the DO on + break; + } else { + // continue searching from the WHILE on + fPosition = pos; + break; + } + default: + // keep searching + } } } - + /** - * Returns true if the colon at the current position is part of a conditional - * (ternary) expression, false otherwise. + * Returns true if the colon at the current position is part of a + * conditional (ternary) expression, false otherwise. * - * @return true if the colon at the current position is part of a conditional + * @return true if the colon at the current position is part of a + * conditional */ private boolean isConditional() { while (true) { nextToken(); switch (fToken) { - - // search for case, otherwise return true - case Symbols.TokenIDENT: - continue; - case Symbols.TokenCASE: - return false; - - default: - return true; + + // search for case, otherwise return true + case Symbols.TokenIDENT: + continue; + case Symbols.TokenCASE: + return false; + + default: + return true; } } } /** * Returns as a reference any previous switch labels (case - * or default) or the offset of the brace that scopes the switch - * statement. Sets fIndent to prefCaseIndent upon - * a match. - * + * or default) or the offset of the brace that scopes the + * switch statement. Sets fIndent to + * prefCaseIndent upon a match. + * * @return the reference offset for a switch label */ -// private int matchCaseAlignment() { -// while (true) { -// nextToken(); -// switch (fToken) { -// // invalid cases: another case label or an LBRACE must come before a case -// // -> bail out with the current position -// case Symbols.TokenLPAREN: -// case Symbols.TokenLBRACKET: -// case Symbols.TokenEOF: -// return fPosition; -// case Symbols.TokenLBRACE: -// // opening brace of switch statement -// fIndent= prefCaseIndent(); -// return fPosition; -// case Symbols.TokenCASE: -// case Symbols.TokenDEFAULT: -// // align with previous label -// fIndent= 0; -// return fPosition; -// -// // scopes: skip them -// case Symbols.TokenRPAREN: -// case Symbols.TokenRBRACKET: -// case Symbols.TokenRBRACE: -// skipScope(); -// break; -// -// default: -// // keep searching -// continue; -// -// } -// } -// } + private int matchCaseAlignment() { + while (true) { + nextToken(); + switch (fToken) { + // invalid cases: another case label or an LBRACE must come before a + // case + // -> bail out with the current position + case Symbols.TokenLPAREN: + case Symbols.TokenLBRACKET: + case Symbols.TokenEOF: + return fPosition; + case Symbols.TokenLBRACE: + // opening brace of switch statement + fIndent = 1; //prefCaseIndent() is for Java + return fPosition; + case Symbols.TokenCASE: + case Symbols.TokenDEFAULT: + // align with previous label + fIndent = 0; + return fPosition; + // scopes: skip them + case Symbols.TokenRPAREN: + case Symbols.TokenRBRACKET: + case Symbols.TokenRBRACE: + skipScope(); + break; + default: + // keep searching + continue; + } + } + } - /** - * Returns the reference position for a list element. The algorithm - * tries to match any previous indentation on the same list. If there is none, - * the reference position returned is determined depending on the type of list: + /** + * Returns the reference position for a list element. The algorithm tries to + * match any previous indentation on the same list. If there is none, the + * reference position returned is determined depending on the type of list: * The indentation will either match the list scope introducer (e.g. for * method declarations), so called deep indents, or simply increase the - * indentation by a number of standard indents. See also {@link #handleScopeIntroduction(int)}. + * indentation by a number of standard indents. See also + * {@link #handleScopeIntroduction(int)}. * - * @return the reference position for a list item: either a previous list item - * that has its own indentation, or the list introduction start. + * @return the reference position for a list item: either a previous list + * item that has its own indentation, or the list introduction + * start. */ private int skipToPreviousListItemOrListStart() { - int startLine= fLine; - int startPosition= fPosition; + int startLine = fLine; + int startPosition = fPosition; while (true) { nextToken(); - + // if any line item comes with its own indentation, adapt to it if (fLine < startLine) { try { - int lineOffset= fDocument.getLineOffset(startLine); - int bound= Math.min(fDocument.getLength(), startPosition + 1); - fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(lineOffset, bound); + int lineOffset = fDocument.getLineOffset(startLine); + int bound = Math.min(fDocument.getLength(), + startPosition + 1); + fAlign = fScanner.findNonWhitespaceForwardInAnyPartition( + lineOffset, bound); } catch (BadLocationException e) { // ignore and return just the position } return startPosition; } - + switch (fToken) { - // scopes: skip them - case Symbols.TokenRPAREN: - case Symbols.TokenRBRACKET: - case Symbols.TokenRBRACE: - skipScope(); - break; - - // scope introduction: special treat who special is - case Symbols.TokenLPAREN: - case Symbols.TokenLBRACE: - case Symbols.TokenLBRACKET: - return handleScopeIntroduction(startPosition + 1); - - case Symbols.TokenSEMICOLON: - return fPosition; - case Symbols.TokenQUESTIONMARK: - if (prefTernaryDeepAlign()) { - setFirstElementAlignment(fPosition - 1, fPosition + 1); - return fPosition; - } else { - fIndent= prefTernaryIndent(); - return fPosition; - } - case Symbols.TokenEOF: - return 0; - + // scopes: skip them + case Symbols.TokenRPAREN: + case Symbols.TokenRBRACKET: + case Symbols.TokenRBRACE: + skipScope(); + break; + + // scope introduction: special treat who special is + case Symbols.TokenLPAREN: + case Symbols.TokenLBRACE: + case Symbols.TokenLBRACKET: + return handleScopeIntroduction(startPosition + 1); + + case Symbols.TokenSEMICOLON: + return fPosition; + case Symbols.TokenQUESTIONMARK: + if (prefTernaryDeepAlign()) { + setFirstElementAlignment(fPosition - 1, fPosition + 1); + } else { + fIndent = prefTernaryIndent(); + } + return fPosition; + case Symbols.TokenEOF: + return 0; + + case Symbols.TokenEQUAL: + // indent assignments + fIndent= prefAssignmentIndent(); + return fPosition; } } } - + /** - * Skips a scope and positions the cursor (fPosition) on the - * token that opens the scope. Returns true if a matching peer - * could be found, false otherwise. The current token when calling - * must be one out of Symbols.TokenRPAREN, Symbols.TokenRBRACE, - * and Symbols.TokenRBRACKET. + * Skips a scope and positions the cursor (fPosition) on + * the token that opens the scope. Returns true if a matching + * peer could be found, false otherwise. The current token + * when calling must be one out of Symbols.TokenRPAREN, + * Symbols.TokenRBRACE, and + * Symbols.TokenRBRACKET. * - * @return true if a matching peer was found, false otherwise + * @return true if a matching peer was found, + * false otherwise */ private boolean skipScope() { switch (fToken) { - case Symbols.TokenRPAREN: - return skipScope(Symbols.TokenLPAREN, Symbols.TokenRPAREN); - case Symbols.TokenRBRACKET: - return skipScope(Symbols.TokenLBRACKET, Symbols.TokenRBRACKET); - case Symbols.TokenRBRACE: - return skipScope(Symbols.TokenLBRACE, Symbols.TokenRBRACE); - default: - Assert.isTrue(false); - return false; + case Symbols.TokenRPAREN: + return skipScope(Symbols.TokenLPAREN, Symbols.TokenRPAREN); + case Symbols.TokenRBRACKET: + return skipScope(Symbols.TokenLBRACKET, Symbols.TokenRBRACKET); + case Symbols.TokenRBRACE: + return skipScope(Symbols.TokenLBRACE, Symbols.TokenRBRACE); + default: + Assert.isTrue(false); + return false; } } /** - * Handles the introduction of a new scope. The current token must be one out - * of Symbols.TokenLPAREN, Symbols.TokenLBRACE, - * and Symbols.TokenLBRACKET. Returns as the reference position - * either the token introducing the scope or - if available - the first - * java token after that. + * Handles the introduction of a new scope. The current token must be one + * out of Symbols.TokenLPAREN, + * Symbols.TokenLBRACE, and + * Symbols.TokenLBRACKET. Returns as the reference position + * either the token introducing the scope or - if available - the first java + * token after that. * - *

Depending on the type of scope introduction, the indentation will align - * (deep indenting) with the reference position (fAlign will be - * set to the reference position) or fIndent will be set to - * the number of indentation units. + *

+ * Depending on the type of scope introduction, the indentation will align + * (deep indenting) with the reference position (fAlign will + * be set to the reference position) or fIndent will be set + * to the number of indentation units. *

* - * @param bound the bound for the search for the first token after the scope - * introduction. + * @param bound + * the bound for the search for the first token after the scope + * introduction. * @return */ private int handleScopeIntroduction(int bound) { switch (fToken) { - // scope introduction: special treat who special is - case Symbols.TokenLPAREN: - int pos= fPosition; // store - - // special: method declaration deep indentation - if (looksLikeMethodDecl()) { - if (prefMethodDeclDeepIndent()) + // scope introduction: special treat who special is + case Symbols.TokenLPAREN: + int pos = fPosition; // store + + // special: method declaration deep indentation + if (looksLikeMethodDecl()) { + if (prefMethodDeclDeepIndent()) + return setFirstElementAlignment(pos, bound); + else { + fIndent = prefMethodDeclIndent(); + return pos; + } + } else { + fPosition = pos; + if (looksLikeMethodCall()) { + if (prefMethodCallDeepIndent()) return setFirstElementAlignment(pos, bound); else { - fIndent= prefMethodDeclIndent(); + fIndent = prefMethodCallIndent(); return pos; } - } else { - fPosition= pos; - if (looksLikeMethodCall()) { - if (prefMethodCallDeepIndent()) - return setFirstElementAlignment(pos, bound); - else { - fIndent= prefMethodCallIndent(); - return pos; - } - } else if (prefParenthesisDeepIndent()) - return setFirstElementAlignment(pos, bound); - } - - // normal: return the parenthesis as reference - fIndent= prefParenthesisIndent(); - return pos; - - case Symbols.TokenLBRACE: - pos= fPosition; // store - - // special: array initializer - if (looksLikeArrayInitializerIntro()) - if (prefArrayDeepIndent()) - return setFirstElementAlignment(pos, bound); - else - fIndent= prefArrayIndent(); - else - fIndent= prefBlockIndent(); - - // normal: skip to the statement start before the scope introducer - // opening braces are often on differently ending indents than e.g. a method definition - fPosition= pos; // restore - return skipToStatementStart(true, true); // set to true to match the first if - - case Symbols.TokenLBRACKET: - pos= fPosition; // store - - // special: method declaration deep indentation - if (prefArrayDimensionsDeepIndent()) { + } else if (prefParenthesisDeepIndent()) return setFirstElementAlignment(pos, bound); - } - - // normal: return the bracket as reference - fIndent= prefBracketIndent(); - return pos; // restore - - default: - Assert.isTrue(false); - return -1; // dummy + } + + // normal: return the parenthesis as reference + fIndent = prefParenthesisIndent(); + return pos; + + case Symbols.TokenLBRACE: + pos = fPosition; // store + + // special: array initializer + if (looksLikeArrayInitializerIntro()) + if (prefArrayDeepIndent()) + return setFirstElementAlignment(pos, bound); + else + fIndent = prefArrayIndent(); + else + fIndent = prefBlockIndent(); + + // normal: skip to the statement start before the scope introducer + // opening braces are often on differently ending indents than e.g. + // a method definition + fPosition = pos; // restore + return skipToStatementStart(true, true); // set to true to match + // the first if + + case Symbols.TokenLBRACKET: + pos = fPosition; // store + + // special: method declaration deep indentation + if (prefArrayDimensionsDeepIndent()) { + return setFirstElementAlignment(pos, bound); + } + + // normal: return the bracket as reference + fIndent = prefBracketIndent(); + return pos; // restore + + default: + Assert.isTrue(false); + return -1; // dummy } } /** - * Sets the deep indent offset (fAlign) to either the offset - * right after scopeIntroducerOffset or - if available - the - * first Java token after scopeIntroducerOffset, but before - * bound. + * Sets the deep indent offset (fAlign) to either the + * offset right after scopeIntroducerOffset or - if available - + * the first Java token after scopeIntroducerOffset, but + * before bound. * - * @param scopeIntroducerOffset the offset of the scope introducer - * @param bound the bound for the search for another element + * @param scopeIntroducerOffset + * the offset of the scope introducer + * @param bound + * the bound for the search for another element * @return the reference position */ private int setFirstElementAlignment(int scopeIntroducerOffset, int bound) { - int firstPossible= scopeIntroducerOffset + 1; // align with the first position after the scope intro - fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(firstPossible, bound); + int firstPossible = scopeIntroducerOffset + 1; // align with the first + // position after the + // scope intro + fAlign = fScanner.findNonWhitespaceForwardInAnyPartition(firstPossible, + bound); if (fAlign == JavaHeuristicScanner.NOT_FOUND) - fAlign= firstPossible; + fAlign = firstPossible; return fAlign; } - /** * Returns true if the next token received after calling - * nextToken is either an equal sign or an array designator ('[]'). + * nextToken is either an equal sign or an array designator + * ('[]'). * - * @return true if the next elements look like the start of an array definition + * @return true if the next elements look like the start of + * an array definition */ private boolean looksLikeArrayInitializerIntro() { nextToken(); @@ -943,51 +1057,51 @@ public class JavaIndenter { } /** - * Skips over the next if keyword. The current token when calling - * this method must be an else keyword. Returns true - * if a matching if could be found, false otherwise. - * The cursor (fPosition) is set to the offset of the if - * token. + * Skips over the next if keyword. The current token when + * calling this method must be an else keyword. Returns + * true if a matching if could be found, + * false otherwise. The cursor (fPosition) + * is set to the offset of the if token. * - * @return true if a matching if token was found, false otherwise + * @return true if a matching if token was + * found, false otherwise */ private boolean skipNextIF() { Assert.isTrue(fToken == Symbols.TokenELSE); - + while (true) { nextToken(); switch (fToken) { - // scopes: skip them - case Symbols.TokenRPAREN: - case Symbols.TokenRBRACKET: - case Symbols.TokenRBRACE: - skipScope(); - break; - - case Symbols.TokenIF: - // found it, return - return true; - case Symbols.TokenELSE: - // recursively skip else-if blocks - skipNextIF(); - break; - - // shortcut scope starts - case Symbols.TokenLPAREN: - case Symbols.TokenLBRACE: - case Symbols.TokenLBRACKET: - case Symbols.TokenEOF: - return false; - } + // scopes: skip them + case Symbols.TokenRPAREN: + case Symbols.TokenRBRACKET: + case Symbols.TokenRBRACE: + skipScope(); + break; + + case Symbols.TokenIF: + // found it, return + return true; + case Symbols.TokenELSE: + // recursively skip else-if blocks + skipNextIF(); + break; + + // shortcut scope starts + case Symbols.TokenLPAREN: + case Symbols.TokenLBRACE: + case Symbols.TokenLBRACKET: + case Symbols.TokenEOF: + return false; + } } } - /** * while(condition); is ambiguous when parsed backwardly, as it is a valid - * statement by its own, so we have to check whether there is a matching - * do. A do can either be separated from the while by a - * block, or by a single statement, which limits our search distance. + * statement by its own, so we have to check whether there is a matching do. + * A do can either be separated from the while by a block, or + * by a single statement, which limits our search distance. * * @return true if the while currently in * fToken has a matching do. @@ -996,18 +1110,19 @@ public class JavaIndenter { Assert.isTrue(fToken == Symbols.TokenWHILE); nextToken(); switch (fToken) { - case Symbols.TokenRBRACE: - skipScope(); // and fall thru - case Symbols.TokenSEMICOLON: - skipToStatementStart(false, false); - return fToken == Symbols.TokenDO; + case Symbols.TokenRBRACE: + skipScope(); // and fall thru + case Symbols.TokenSEMICOLON: + skipToStatementStart(false, false); + return fToken == Symbols.TokenDO; } return false; } - + /** * Skips brackets if the current token is a RBRACKET. There can be nothing - * but whitespace in between, this is only to be used for [] elements. + * but whitespace in between, this is only to be used for [] + * elements. * * @return true if a [] could be scanned, the * current token is left at the LBRACKET. @@ -1021,39 +1136,41 @@ public class JavaIndenter { } return false; } - + /** - * Reads the next token in backward direction from the heuristic scanner - * and sets the fields fToken, fPreviousPosition and fPosition - * accordingly. + * Reads the next token in backward direction from the heuristic scanner and + * sets the fields fToken, fPreviousPosition and + * fPosition accordingly. */ private void nextToken() { nextToken(fPosition); } - + /** * Reads the next token in backward direction of start from - * the heuristic scanner and sets the fields fToken, fPreviousPosition - * and fPosition accordingly. + * the heuristic scanner and sets the fields + * fToken, fPreviousPosition and fPosition + * accordingly. */ private void nextToken(int start) { - fToken= fScanner.previousToken(start - 1, JavaHeuristicScanner.UNBOUND); - fPreviousPos= start; - fPosition= fScanner.getPosition() + 1; + fToken = fScanner + .previousToken(start - 1, JavaHeuristicScanner.UNBOUND); + fPreviousPos = start; + fPosition = fScanner.getPosition() + 1; try { - fLine= fDocument.getLineOfOffset(fPosition); + fLine = fDocument.getLineOfOffset(fPosition); } catch (BadLocationException e) { - fLine= -1; + fLine = -1; } } - + /** * Returns true if the current tokens look like a method * declaration header (i.e. only the return type and method name). The * heuristic calls nextToken and expects an identifier - * (method name) and a type declaration (an identifier with optional + * (method name) and a type declaration (an identifier with optional * brackets) which also covers the visibility modifier of constructors; it - * does not recognize package visible constructors. + * does not recognize package visible constructors. * * @return true if the current position looks like a method * declaration header. @@ -1061,50 +1178,53 @@ public class JavaIndenter { private boolean looksLikeMethodDecl() { /* * TODO This heuristic does not recognize package private constructors - * since those do have neither type nor visibility keywords. - * One option would be to go over the parameter list, but that might - * be empty as well - hard to do without an AST... + * since those do have neither type nor visibility keywords. One option + * would be to go over the parameter list, but that might be empty as + * well - hard to do without an AST... */ - + nextToken(); if (fToken == Symbols.TokenIDENT) { // method name - do nextToken(); - while (skipBrackets()); // optional brackets for array valued return types + do + nextToken(); + while (skipBrackets()); // optional brackets for array valued return + // types return fToken == Symbols.TokenIDENT; // type name - + } return false; } - + /** - * Returns true if the current tokens look like a method - * call header (i.e. an identifier as opposed to a keyword taking parenthesized + * Returns true if the current tokens look like a method call + * header (i.e. an identifier as opposed to a keyword taking parenthesized * parameters such as if). - *

The heuristic calls nextToken and expects an identifier + *

+ * The heuristic calls nextToken and expects an identifier * (method name). * - * @return true if the current position looks like a method call - * header. + * @return true if the current position looks like a method + * call header. */ private boolean looksLikeMethodCall() { nextToken(); return fToken == Symbols.TokenIDENT; // method name } - + /** - * Scans tokens for the matching opening peer. The internal cursor - * (fPosition) is set to the offset of the opening peer if found. + * Scans tokens for the matching opening peer. The internal cursor (fPosition) + * is set to the offset of the opening peer if found. * - * @return true if a matching token was found, false - * otherwise + * @return true if a matching token was found, + * false otherwise */ private boolean skipScope(int openToken, int closeToken) { - - int depth= 1; + + int depth = 1; while (true) { nextToken(); - + if (fToken == closeToken) { depth++; } else if (fToken == openToken) { @@ -1112,40 +1232,49 @@ public class JavaIndenter { if (depth == 0) return true; } else if (fToken == Symbols.TokenEOF) { - return false; + return false; } } } // TODO adjust once there are per-project settings - + private int prefTabLength() { int tabLen; -// JavaCore core= JavaCore.getJavaCore(); - PHPeclipsePlugin plugin= PHPeclipsePlugin.getDefault(); -// if (core != null && plugin != null) - if (plugin != null) - if (JavaCore.SPACE.equals(JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR))) - // if the formatter uses chars to mark indentation, then don't substitute any chars - tabLen= -1; // results in no tabs being substituted for space runs + // JavaCore core= JavaCore.getJavaCore(); + PHPeclipsePlugin plugin = PHPeclipsePlugin.getDefault(); + // if (core != null && plugin != null) + if (plugin != null) + if (JavaCore.SPACE + .equals(JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR))) + // if the formatter uses chars to mark indentation, then don't + // substitute any chars + tabLen = -1; // results in no tabs being substituted for + // space runs else - // if the formatter uses tabs to mark indentations, use the visual setting from the editor + // if the formatter uses tabs to mark indentations, use the + // visual setting from the editor // to get nicely aligned indentations - tabLen= plugin.getPreferenceStore().getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH); + tabLen = plugin + .getPreferenceStore() + .getInt( + AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH); else - tabLen= 4; // sensible default for testing + tabLen = 4; // sensible default for testing return tabLen; } - + private boolean prefArrayDimensionsDeepIndent() { return true; // sensible default } private int prefArrayIndent() { - Plugin plugin= JavaCore.getPlugin(); + Plugin plugin = JavaCore.getPlugin(); if (plugin != null) { - String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER); + String option = JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER); try { if (DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_BY_ONE) return 1; @@ -1153,28 +1282,30 @@ public class JavaIndenter { // ignore and return default } } - + return prefContinuationIndent(); // default } private boolean prefArrayDeepIndent() { - Plugin plugin= JavaCore.getPlugin(); + Plugin plugin = JavaCore.getPlugin(); if (plugin != null) { - String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER); + String option = JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER); try { return DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_ON_COLUMN; } catch (IllegalArgumentException e) { // ignore and return default } } - + return true; } private boolean prefTernaryDeepAlign() { - Plugin plugin= JavaCore.getPlugin(); + Plugin plugin = JavaCore.getPlugin(); if (plugin != null) { - String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION); + String option = JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION); try { return DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_ON_COLUMN; } catch (IllegalArgumentException e) { @@ -1185,9 +1316,10 @@ public class JavaIndenter { } private int prefTernaryIndent() { - Plugin plugin= JavaCore.getPlugin(); + Plugin plugin = JavaCore.getPlugin(); if (plugin != null) { - String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION); + String option = JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION); try { if (DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_BY_ONE) return 1; @@ -1197,19 +1329,21 @@ public class JavaIndenter { // ignore and return default } } - + return prefContinuationIndent(); } private int prefCaseIndent() { - Plugin plugin= JavaCore.getPlugin(); + Plugin plugin = JavaCore.getPlugin(); if (plugin != null) { - if (DefaultCodeFormatterConstants.TRUE.equals(JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH))) + if (DefaultCodeFormatterConstants.TRUE + .equals(JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH))) return prefBlockIndent(); else return 0; } - + return 0; // sun standard } @@ -1220,10 +1354,12 @@ public class JavaIndenter { private int prefCaseBlockIndent() { if (true) return prefBlockIndent(); - - Plugin plugin= JavaCore.getPlugin(); + + Plugin plugin = JavaCore.getPlugin(); if (plugin != null) { - if (DefaultCodeFormatterConstants.TRUE.equals(JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES))) + if (DefaultCodeFormatterConstants.TRUE + .equals(JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES))) return prefBlockIndent(); else return 0; @@ -1240,23 +1376,25 @@ public class JavaIndenter { } private boolean prefMethodDeclDeepIndent() { - Plugin plugin= JavaCore.getPlugin(); + Plugin plugin = JavaCore.getPlugin(); if (plugin != null) { - String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION); + String option = JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION); try { return DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_ON_COLUMN; } catch (IllegalArgumentException e) { // ignore and return default } } - + return true; } private int prefMethodDeclIndent() { - Plugin plugin= JavaCore.getPlugin(); + Plugin plugin = JavaCore.getPlugin(); if (plugin != null) { - String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION); + String option = JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION); try { if (DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_BY_ONE) return 1; @@ -1270,9 +1408,10 @@ public class JavaIndenter { } private boolean prefMethodCallDeepIndent() { - Plugin plugin= JavaCore.getPlugin(); + Plugin plugin = JavaCore.getPlugin(); if (plugin != null) { - String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION); + String option = JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION); try { return DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_ON_COLUMN; } catch (IllegalArgumentException e) { @@ -1283,9 +1422,10 @@ public class JavaIndenter { } private int prefMethodCallIndent() { - Plugin plugin= JavaCore.getPlugin(); + Plugin plugin = JavaCore.getPlugin(); if (plugin != null) { - String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION); + String option = JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION); try { if (DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_BY_ONE) return 1; @@ -1295,25 +1435,26 @@ public class JavaIndenter { // ignore and return default } } - + return 1; // sensible default } private boolean prefParenthesisDeepIndent() { - + if (true) // don't do parenthesis deep indentation return false; - - Plugin plugin= JavaCore.getPlugin(); + + Plugin plugin = JavaCore.getPlugin(); if (plugin != null) { - String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION); + String option = JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION); try { return DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_ON_COLUMN; } catch (IllegalArgumentException e) { // ignore and return default } } - + return false; // sensible default } @@ -1324,48 +1465,55 @@ public class JavaIndenter { private int prefBlockIndent() { return 1; // sensible default } - - private boolean prefIndentBracesForBlocks() { - Plugin plugin= JavaCore.getPlugin(); - if (plugin != null) { - String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK); - return option.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED); - } - - return false; // sensible default - } - - private boolean prefIndentBracesForArrays() { - Plugin plugin= JavaCore.getPlugin(); - if (plugin != null) { - String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER); - return option.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED); - } - - return false; // sensible default - } - - private boolean prefIndentBracesForMethods() { - Plugin plugin= JavaCore.getPlugin(); - if (plugin != null) { - String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION); - return option.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED); - } - - return false; // sensible default - } - + +// private boolean prefIndentBracesForBlocks() { +// Plugin plugin = JavaCore.getPlugin(); +// if (plugin != null) { +// String option = JavaCore +// .getOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK); +// return option +// .equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED); +// } +// +// return false; // sensible default +// } + +// private boolean prefIndentBracesForArrays() { +// Plugin plugin = JavaCore.getPlugin(); +// if (plugin != null) { +// String option = JavaCore +// .getOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER); +// return option +// .equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED); +// } +// +// return false; // sensible default +// } + +// private boolean prefIndentBracesForMethods() { +// Plugin plugin = JavaCore.getPlugin(); +// if (plugin != null) { +// String option = JavaCore +// .getOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION); +// return option +// .equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED); +// } +// +// return false; // sensible default +// } + private int prefContinuationIndent() { - Plugin plugin= JavaCore.getPlugin(); + Plugin plugin = JavaCore.getPlugin(); if (plugin != null) { - String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION); + String option = JavaCore + .getOption(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION); try { return Integer.parseInt(option); } catch (NumberFormatException e) { // ignore and return default } } - + return 2; // sensible default }