📄 jsbeautifier.java
字号:
else if ("else".equals(headers[h])) { String header; if (lastTempStack != null) { int indexOfIf = lastTempStack.indexOf("if"); if (indexOfIf != -1) { // recreate the header list in headerStack up to the previous 'if' // from the temporary snapshot stored in lastTempStack. int restackSize = lastTempStack.size() - indexOfIf - 1; for (int r=0; r<restackSize; r++) headerStack.push(lastTempStack.pop()); if (!closingBracketReached) tabCount += restackSize; } /* * If the above if is not true, i.e. no 'if' before the 'else', * then nothing beautiful will come out of this... * I should think about inserting an Exception here to notify the caller of this... */ } } // check if 'while' closes a previous 'do' else if ("while".equals(headers[h])) { String header; if (lastTempStack != null) { int indexOfDo = lastTempStack.indexOf("do"); if (indexOfDo != -1) { // recreate the header list in headerStack up to the previous 'do' // from the temporary snapshot stored in lastTempStack. int restackSize = lastTempStack.size() - indexOfDo - 1; for (int r=0; r<restackSize; r++) headerStack.push(lastTempStack.pop()); if (!closingBracketReached) tabCount += restackSize; } } } // check if 'catch' closes a previous 'try' or 'catch' else if ("catch".equals(headers[h])) { String header; if (lastTempStack != null) { int indexOfTry = lastTempStack.indexOf("try"); if (indexOfTry == -1) indexOfTry = lastTempStack.indexOf("catch"); if (indexOfTry != -1) { // recreate the header list in headerStack up to the previous 'do' // from the temporary snapshot stored in lastTempStack. int restackSize = lastTempStack.size() - indexOfTry - 1; for (int r=0; r<restackSize; r++) headerStack.push(lastTempStack.pop()); //lastTempStack.pop(); //headerStack.push("try"); if (!closingBracketReached) tabCount += restackSize; } } } else if ("case".equals(headers[h]) || "default".equals(headers[h]) ) { isInCase = true; --tabCount; } else if (("static".equals(headers[h]) || "synchronized".equals(headers[h])) && !headerStack.isEmpty() && ("static".equals(headerStack.lastElement()) || "synchronized".equals(headerStack.lastElement()))) isDoubleHeader = true; if (!isDoubleHeader) { spaceTabCount-=indentLength; headerStack.push(headers[h]); } lastLineHeader = headers[h]; outBuffer.append(headers[h].substring(1)); i += headers[h].length() - 1; //if (parenDepth == 0) isInStatement = false; } } if (ch == '?') isInQuestion = true; // special handling of 'case' statements if (ch == ':') { if (isInQuestion) { isInQuestion = false; } else { currentNonSpaceCh = ';'; // so that brackets after the ':' will appear as block-openers if (isInCase) { isInCase = false; ch = ';'; // from here on, treat char as ';' } } } if ((ch == ';' || ch == ',') && !inStatementIndentStackSizeStack.isEmpty()) while (((Integer) inStatementIndentStackSizeStack.peek()).intValue() + (parenDepth>0 ? 1 : 0) < inStatementIndentStack.size()) inStatementIndentStack.pop(); // handle ends of statements if ( (ch == ';' && parenDepth == 0) || ch == '}' || (ch == ',' && parenDepth == 0)) { if (ch == '}') { // first check if this '}' closes a previous block, or a static array... if ( !bracketBlockStateStack.isEmpty() && !((Boolean) bracketBlockStateStack.pop()).booleanValue() ) { if (!inStatementIndentStackSizeStack.isEmpty()) { int previousIndentStackSize = ((Integer) inStatementIndentStackSizeStack.pop()).intValue(); while (previousIndentStackSize < inStatementIndentStack.size()) inStatementIndentStack.pop(); parenDepth--; if (i == 0) shouldIndentBrackettedLine = false; if (!parenIndentStack.isEmpty()) { Object poppedIndent = parenIndentStack.pop(); if (i == 0) spaceTabCount = ((Integer) poppedIndent).intValue(); } } continue; } if(!inStatementIndentStackSizeStack.isEmpty()) inStatementIndentStackSizeStack.pop(); if (!blockParenDepthStack.isEmpty()) { parenDepth = ((Integer) blockParenDepthStack.pop()).intValue(); isInStatement = ((Boolean) blockStatementStack.pop()).booleanValue(); if (isInStatement) blockTabCount--; } closingBracketReached = true; int headerPlace = headerStack.search("{"); if (headerPlace != -1) { while (!"{".equals(headerStack.pop())) ; if (!tempStacks.isEmpty()) tempStacks.pop(); } ch = ' '; // needed due to cases such as '}else{', so that headers ('else' tn tih case) will be identified... } //else if (ch == ';' /* parenDepth == 0*/) // while (((Integer) inStatementIndentStackSizeStack.peek()).intValue() < inStatementIndentStack.size()) // inStatementIndentStack.pop(); /* * Create a temporary snapshot of the current block's header-list in the * uppermost inner stack in tempStacks, and clear the headerStack up to * the begining of the block. * Thus, the next future statement will think it comes one indent past * the block's '{' unless it specifically checks for a companion-header * (such as a previous 'if' for an 'else' header) within the tempStacks, * and recreates the temporary snapshot by manipulating the tempStacks. */ if (!((Stack) tempStacks.peek()).isEmpty()) ((Stack) tempStacks.peek()).removeAllElements(); while (!headerStack.isEmpty() && !"{".equals(headerStack.peek())) ((Stack) tempStacks.peek()).push(headerStack.pop()); if (parenDepth == 0 && ch == ';') isInStatement=false; continue; } if (prevCh == ' ') { int headerNum = findLegalHeader(line, i, preBlockStatements); if (headerNum > -1) { isInClassHeader = true; outBuffer.append(preBlockStatements[headerNum].substring(1)); i += preBlockStatements[headerNum].length() - 1; } } // PRECHECK if a '==' or '--' or '++' operator was reached. // If not, then register an indent IF an assignment operator was reached. // The precheck is important, so that statements such as 'i--==2' are not recognized // to have assignment operators (here, '-=') in them . . . immediatelyPreviousAssignmentOp = null; boolean isNonAssingmentOperator = false; for (int n = 0; n < nonAssignmentOperators.length; n++) if (line.regionMatches(false, i, nonAssignmentOperators[n], 0, nonAssignmentOperators[n].length())) { outBuffer.append(nonAssignmentOperators[n].substring(1)); i++; /* the above two lines do the same as the next since all listed non Assignment operators are 2 chars long... if (nonAssignmentOperators[n].length() > 1) { outBuffer.append(nonAssignmentOperators[n].substring(1)); i += nonAssignmentOperators[n].length() - 1; } */ isNonAssingmentOperator = true; break; } if (!isNonAssingmentOperator) { for (int a = 0; a < assignmentOperators.length; a++) if (line.regionMatches(false, i, assignmentOperators[a], 0, assignmentOperators[a].length())) { if (assignmentOperators[a].length() > 1) { outBuffer.append(assignmentOperators[a].substring(1)); i += assignmentOperators[a].length() - 1; } registerInStatementIndent(line, i, spaceTabCount, isLineInStatement, false); immediatelyPreviousAssignmentOp = assignmentOperators[a]; break; } } if ( parenDepth > 0 || !(isLegalNameChar(ch) || ch == ':')) isInStatement = true; } // handle special cases of unindentation: /* * if '{' doesn't follow an immediately previous '{' in the headerStack * (but rather another header such as "for" or "if", then unindent it * by one indentation relative to its block. */ if (outBuffer.length()>0 && outBuffer.charAt(0)=='{' && !(headerStack.size()>1 && "{".equals(headerStack.elementAt(headerStack.size()-2))) && shouldIndentBrackettedLine) tabCount--; else if (outBuffer.length()>0 && outBuffer.charAt(0)=='}' && shouldIndentBrackettedLine ) tabCount--; if (tabCount < 0) tabCount = 0; // take care of extra bracket indentatation option... if (bracketIndent && outBuffer.length()>0 && shouldIndentBrackettedLine) if (outBuffer.charAt(0)=='{' || outBuffer.charAt(0)=='}') tabCount++; // finally, insert indentations into begining of line for (int i=0; i<tabCount; i++) outBuffer.insert(0, indentString); while ((spaceTabCount--) > 0) outBuffer.insert(0, ' '); if (!inStatementIndentStack.isEmpty()) { if (statementTabCount < 0) statementTabCount = tabCount; } else statementTabCount = -1; return outBuffer.toString(); } private void registerInStatementIndent(String line, int i, int spaceTabCount, boolean isLineInStatement, boolean updateParenStack) { int inStatementIndent; int remainingCharNum = line.length() - i; int nextNonWSChar = 1; /* while (nextNonWSChar < remainingCharNum && (line.charAt(i+nextNonWSChar) == ' ' || line.charAt(i+nextNonWSChar) == '\t') ) nextNonWSChar++; */ nextNonWSChar = getNextProgramCharDistance(line, i); // if indent is around the last char in the line, indent instead 2 spaces from the previous indent if (nextNonWSChar == remainingCharNum) { int previousIndent = spaceTabCount; if (!inStatementIndentStack.isEmpty()) previousIndent = ((Integer) inStatementIndentStack.peek()).intValue(); inStatementIndentStack.push(new Integer(2 /*indentLength*/ + previousIndent) ); //2 if (updateParenStack) parenIndentStack.push( new Integer(previousIndent) ); return; } if (updateParenStack) parenIndentStack.push(new Integer(i+spaceTabCount)); inStatementIndent = i + nextNonWSChar + spaceTabCount; if (i + nextNonWSChar > maxInStatementIndent) inStatementIndent = indentLength*2 + spaceTabCount; if (!inStatementIndentStack.isEmpty() && inStatementIndent < ((Integer) inStatementIndentStack.peek()).intValue()) inStatementIndent = ((Integer) inStatementIndentStack.peek()).intValue(); //else if (!isLineInStatement && i + nextNonWSChar < 8) // inStatementIndent = 8 + spaceTabCount; inStatementIndentStack.push(new Integer(inStatementIndent)); } // get distance to the next non-white sspace, non-comment character in the line. // if no such character exists, return the length remaining to the end of the line. private int getNextProgramCharDistance(String line, int i) { int inStatementIndent; boolean inComment = false; int remainingCharNum = line.length() - i; int charDistance = 1; int ch; for (charDistance = 1; charDistance < remainingCharNum; charDistance++) { ch = line.charAt(i + charDistance); if (inComment) { if (line.regionMatches(false, i + charDistance, "*/", 0, 2)) { charDistance++; inComment = false; } continue; } else if (ch == ' ' || ch == '\t') continue; else if (ch == '/') { if ((line.regionMatches(false, i + charDistance, "//", 0, 2))) return remainingCharNum; else if ((line.regionMatches(false, i + charDistance, "/*", 0, 2))) { charDistance++; inComment = true; } } else return charDistance; } return charDistance; } private boolean isLegalNameChar(char ch) { return ((ch>='a' && ch<='z') || (ch>='A' && ch<='Z') || (ch>='0' && ch<='9') || ch=='.' || ch=='_' || ch=='$'); } private int findLegalHeader(String line, int i, String possibleHeaders[]) { int maxHeaders = possibleHeaders.length; int p; for (p=0; p < maxHeaders; p++) if (line.regionMatches(false, i, possibleHeaders[p], 0, possibleHeaders[p].length())) { // first check that this is a header and not the begining of a longer word... int lineLength = line.length(); int headerEnd = i + possibleHeaders[p].length(); char endCh = 0; if ( headerEnd < lineLength ) endCh = line.charAt(headerEnd); if (headerEnd >= lineLength || !isLegalNameChar(endCh)) return p; else return -1; } return -1; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -