📄 jsbeautifier.java
字号:
* beautifying a NEW source file. */ public void init() { headerStack = new Stack(); tempStacks = new Stack(); tempStacks.push(new Stack()); blockParenDepthStack = new Stack(); blockStatementStack = new Stack(); parenStatementStack = new Stack(); bracketBlockStateStack = new Stack(); bracketBlockStateStack.push(new Boolean(true)); inStatementIndentStack = new Stack(); inStatementIndentStackSizeStack = new Stack(); inStatementIndentStackSizeStack.push(new Integer(0)); parenIndentStack = new Stack(); isSpecialChar = false; isInQuote = false; isInComment = false; isInStatement = false; isInCase = false; isInQuestion = false; isInClassHeader = false; isInClassHeaderTab = false; isInHeader = false; immediatelyPreviousAssignmentOp = null; parenDepth=0; blockTabCount = 0; statementTabCount = -1; leadingWhiteSpaces = 0; prevNonSpaceCh = '{'; currentNonSpaceCh = '{'; } /** * ident using one tab per identation */ public void setTabIndentation() { indentString = "\t"; indentLength = 4; } /** * ident a number of spaces for each identation. * * @param length number of spaces per indent. */ public void setSpaceIndentation(int length) { char spaces[] = new char[length]; for (int i=0; i<length; i++) spaces[i] = ' '; indentString = new String(spaces); indentLength = length; } /** * set the maximum indentation between two lines in a multi-line statement. * * @param max maximum indentation length. */ public void setMaxInStatementIndetation(int max) { maxInStatementIndent = max; } /** * set the state of the bracket indentation option. If true, brackets will * be indented one additional indent. * * @param state state of option. */ public void setBracketIndent(boolean state) { bracketIndent = state; } /** * set the state of the switch indentation option. If true, blocks of 'switch' * statements will be indented one additional indent. * * @param state state of option. */ public void setSwitchIndent(boolean state) { switchIndent = state; } /** * beautify a line of source code. * * every line of source code in a java source code file should be sent * one after the other to the beautify method. */ public String beautify(String line) { boolean isInLineComment = false; // true when the current character is in a // comment (such as this line ...) boolean isInSwitch = false; char ch = ' '; // the current character char prevCh; // previous char StringBuffer outBuffer = new StringBuffer(); // the newly idented line is bufferd here int tabCount = 0; // number of indents before line String lastLineHeader = null; // last header found within line boolean closingBracketReached = false; int spaceTabCount = 0; boolean usePreviousTabCount = false; int previousTabCount = 0; int headerStackSize = headerStack.size(); boolean isLineInStatement = isInStatement; boolean shouldIndentBrackettedLine = true; currentHeader = null; // handle and remove white spaces around the line: // If not in comment, first find out size of white space before line, // so that possible comments starting in the line continue in // relation to the preliminary white-space. if (!isInComment) { leadingWhiteSpaces = 0; while (leadingWhiteSpaces<line.length() && (line.charAt(leadingWhiteSpaces)==' ' || line.charAt(leadingWhiteSpaces)=='\t')) leadingWhiteSpaces++; line = line.trim(); } else { int trimSize; for (trimSize=0; trimSize < line.length() && trimSize<leadingWhiteSpaces && (line.charAt(trimSize) == ' ' || line.charAt(trimSize) == '\t'); trimSize++) ; line = line.substring(trimSize); } if (line.length() == 0) return line; if (!inStatementIndentStack.isEmpty()) spaceTabCount = ((Integer) inStatementIndentStack.peek()).intValue(); // calculate preliminary indentation based on data from past lines for (int i=0; i<headerStackSize; i++) { if (!(i>0 && !"{".equals(headerStack.elementAt(i-1)) && "{".equals(headerStack.elementAt(i)))) tabCount++; // is the switchIndent option is on, indent switch statements an additional indent. if (switchIndent && i > 1 && "switch".equals(headerStack.elementAt(i-1)) && "{".equals(headerStack.elementAt(i)) ) { tabCount++; isInSwitch = true; } } if (isInSwitch && switchIndent && headerStackSize >= 2 && "switch".equals(headerStack.elementAt(headerStackSize-2)) && "{".equals(headerStack.elementAt(headerStackSize-1)) && line.charAt(0) == '}') tabCount--; if (isInClassHeader) { isInClassHeaderTab = true; tabCount += 2; } //if (isInStatement) // if (!headerStack.isEmpty() && !"{".equals(headerStack.lastElement())) // tabCount--; // parse characters in the current line. for (int i=0; i<line.length(); i++) { prevCh = ch; ch = line.charAt(i); if (ch=='\n' || ch=='\r') continue; outBuffer.append(ch); if (ch==' ' || ch=='\t') continue; // handle special characters (i.e. backslash+character such as \n, \t, ...) if (isSpecialChar) { isSpecialChar = false; continue; } if (!(isInComment || isInLineComment) && line.regionMatches(false, i, "\\\\", 0, 2)) { outBuffer.append('\\'); i++; continue; } if (!(isInComment || isInLineComment) && ch=='\\') { isSpecialChar = true; continue; } // handle quotes (such as 'x' and "Hello Dolly") if (!(isInComment || isInLineComment) && (ch=='"' || ch=='\'')) if (!isInQuote) { quoteChar = ch; isInQuote = true; } else if (quoteChar == ch) { isInQuote = false; isInStatement = true; continue; } if (isInQuote) continue; // handle comments if ( !(isInComment || isInLineComment) && line.regionMatches(false, i, "//", 0, 2) ) { isInLineComment = true; outBuffer.append("/"); i++; continue; } else if ( !(isInComment || isInLineComment) && line.regionMatches(false, i, "/*", 0, 2) ) { isInComment = true; outBuffer.append("*"); i++; continue; } else if ( (isInComment || isInLineComment) && line.regionMatches(false, i, "*/", 0, 2) ) { isInComment = false; outBuffer.append("/"); i++; continue; } if (isInComment||isInLineComment) continue; // if we have reached this far then we are NOT in a comment or string of special character... prevNonSpaceCh = currentNonSpaceCh; currentNonSpaceCh = ch; if (isInHeader) { isInHeader = false; currentHeader = (String) headerStack.peek(); } else currentHeader = null; // handle parenthesies if (ch == '(' || ch == '[' || ch == ')' || ch == ']') { if (ch == '(' || ch == '[') { if (parenDepth == 0) { parenStatementStack.push(new Boolean(isInStatement)); isInStatement = true; } parenDepth++; inStatementIndentStackSizeStack.push(new Integer(inStatementIndentStack.size())); if (currentHeader != null) { //spaceTabCount-=indentLength; inStatementIndentStack.push(new Integer(indentLength*2 + spaceTabCount)); parenIndentStack.push(new Integer(indentLength*2 + spaceTabCount)); } else registerInStatementIndent(line, i, spaceTabCount, isLineInStatement, true); } else if (ch == ')' || ch == ']') { parenDepth--; if (parenDepth == 0) { isInStatement = ((Boolean) parenStatementStack.pop()).booleanValue(); ch = ' '; } if (!inStatementIndentStackSizeStack.isEmpty()) { int previousIndentStackSize = ((Integer) inStatementIndentStackSizeStack.pop()).intValue(); while (previousIndentStackSize < inStatementIndentStack.size()) inStatementIndentStack.pop(); if (!parenIndentStack.isEmpty()) { Object poppedIndent = parenIndentStack.pop(); if (i == 0) spaceTabCount = ((Integer) poppedIndent).intValue(); } } } continue; } if (ch == '{') { boolean isBlockOpener = false; // first, check if '{' is a block-opener or an static-array opener isBlockOpener |= (prevNonSpaceCh == '{' && ((Boolean) bracketBlockStateStack.peek()).booleanValue()); isBlockOpener |= (prevNonSpaceCh == ')' || prevNonSpaceCh == ';'); isBlockOpener |= isInClassHeader; isInClassHeader = false; if (!isBlockOpener && currentHeader != null) { for (int n=0; n < nonParenHeaders.length; n++) if (currentHeader.equals(nonParenHeaders[n])) { isBlockOpener = true; break; } } bracketBlockStateStack.push(new Boolean(isBlockOpener)); if (!isBlockOpener) { if (line.length() - i == getNextProgramCharDistance(line, i) && immediatelyPreviousAssignmentOp != null) // && !inStatementIndentStack.isEmpty() - actually not needed inStatementIndentStack.pop(); inStatementIndentStackSizeStack.push(new Integer(inStatementIndentStack.size())); registerInStatementIndent(line, i, spaceTabCount, isLineInStatement, true); //parenIndentStack.push(new Integer(i+spaceTabCount)); parenDepth++; if (i == 0) shouldIndentBrackettedLine = false; continue; } if (isInClassHeader) isInClassHeader = false; if (isInClassHeaderTab) { isInClassHeaderTab = false; tabCount -= 2; } blockParenDepthStack.push(new Integer(parenDepth)); blockStatementStack.push(new Boolean(isInStatement)); inStatementIndentStackSizeStack.push(new Integer(inStatementIndentStack.size())); blockTabCount += isInStatement? 1 : 0; parenDepth = 0; isInStatement = false; tempStacks.push(new Stack()); headerStack.push("{"); lastLineHeader = "{"; continue; } //check if a header has been reached if (prevCh == ' ') { boolean isDoubleHeader = false; int h = findLegalHeader(line, i, headers); if (h > -1) { // if we reached here, then this is a header... isInHeader = true; Stack lastTempStack = (Stack) tempStacks.peek(); // if a new block is opened, push a new stack into tempStacks to hold the // future list of headers in the new block. //if ("{".equals(headers[h])) // tempStacks.push(new Stack()); // take care of the special case: 'else if (...)' if ("if".equals(headers[h]) && "else".equals(lastLineHeader)) headerStack.pop(); // take care of 'else'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -