📄 jbrowselineparser.java
字号:
/* * JBrowseLineParser.java - a JBrowseParser for Java Source Code via LineSource * * Copyright (c) 1999 George Latkiewicz (georgel@arvotek.net) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */import java.util.Stack; // will be required for inner-class support//=============================================================================/** * The class that implemnts a JBrowseParser for Java Source Code via a * JBrowseParser.LineSource. * * @author George Latkiewicz * @version 1.0.1 - Nov. 16, 1999 */public class JBrowseLineParser implements JBrowseParser{ /* public class attributes */ public static final String VER_NUM = "1.0.1"; /* public instance attributes */ public JBrowseParser.Results results; /* private instance attributes */ private JBrowseParser.LineSource ls; private String fileName; // set on JBrowse.TreePane.init(), private String expectedTopLevelName; // set on JBrowse.TreePane.init(), Stack nodeStack = new Stack(); private UMLTree.Node root; private Options options; private Options.Filter filterOpt; private Options.Display displayOpt; // Parse State ParseState parseState = null; ParseSubState parseSubState = null; // Counters int tokenCount = 0; // only count tokens returned by TokenSource int curTokenLine = -1; int curTokenPos = -1; //------------------------------------------------------------------------- /** * This method creates a new instance of JBrowse GUI and Parsing engine. * @param ls JBrowseParser.LineSource that will provide the source to be parsed. */ public JBrowseLineParser(JBrowseParser.LineSource ls) { this.ls = ls; results = new JBrowseParser.Results(); } // JBrowseLineParser(View): <init> /** * Returns the String that represents the name associated with the current * JBrowseParser.LineSource (e.g. the fileName associated with the current * buffer), or null if the JBrowseParser.LineSource is not currently associated * with a source. */ public String getSourceName() { if (ls != null) { return ls.getName(); } else { return null; } } /** * Returns <CODE>true</CODE> if the <CODE>JEditTextArea</CODE> to which this * <CODE>JBrowseLineParser</CODE> is tied uses a <CODE>JavaTokenMarker</CODE>. */ public boolean usesJavaTokenMarker() { return (ls instanceof JEditLineSource) ? (((JEditLineSource)ls).getTextArea().getTokenMarker() instanceof org.gjt.sp.jedit.syntax.JavaTokenMarker) : false; }//end usesJavaTokenMarker public final void setOptions(Options options) { this.options = options; filterOpt = options.getFilterOptions(); displayOpt = options.getDisplayOptions(); } public final void setRootNode(UMLTree.Node root) { this.root = root; } public boolean isReady() { boolean rVal = false; if ( options != null && ls != null && root != null ) { rVal = true; } return rVal; } // isReady(): boolean //------------------------------------------------------------------------- /** * The method that preforms the actual parsing. This is the method which builds * the tree model that reflects the heirarchical structure of the Java code in * the current LineSource. */ public JBrowseParser.Results parse() { results.reset(); // reset result counters to 0 ls.reset(); // reset the LineSource to the beginning of the buffer if (!isReady()) { return results; } // Set initial Parse State parseState = ParseState.HEADER; parseSubState = null; // Set initial counts tokenCount = 0; // only count tokens returned by TokenSource curTokenLine = -1; curTokenPos = -1; UML.Element currentElement = null; UML.Message messageElement = null; UML.Type eType; nodeStack.push(root); UMLTree.Node parentNode = root; int methodBraceCount = 0; int lastTokenLine = -1; int packageMemberStartPos = -1; int packageMemberLine = -1; // Parsing Attributes int curElementStartPos = -1; String msgStr = null; boolean badFlag = false; boolean resetFlag = false; String lastToken = null; String token = null; char tokenStartChar; boolean exceptionThrown = false; // Get fileName and TokenSource fileName = ls.getName();// TokenSource ts = new TokenSource(ls, JBrowse.debugLevel ); TokenSource ts = new TokenSource(ls); if (!fileName.toUpperCase().endsWith(".JAVA") ) { expectedTopLevelName = fileName; fileName += " (NON-java file?)"; } else { expectedTopLevelName = fileName.substring(0, fileName.indexOf('.')); } root.setName(fileName); try { root.setPosition( ls.createPosition(0) ); if (root.getChildCount() > 0 ) { root.removeAllChildren(); } // parsing attributes int mod = 0; String className = null; String memberType = null; // method return type or attribute type String memberName = null; String parmType = ""; String parmName = ""; int methodParmsCount = 0; boolean extendsFound = false; // set when extends keyword found boolean implementsFound = false; // set when implements keyword found boolean extendsOK = true; // set when extends class/interface name found (but no comma) boolean implementsOK = true; // set when implements interface name found (but no comma) boolean throwsFound = false; // set when throws keyword found boolean throwsOK = true; // set when throws class/interface name found (but no comma) boolean isBodyRequired = false; do { tokenCount++; lastTokenLine = curTokenLine; token = ts.getNextToken(); curTokenLine = ts.getCurrentLineNum(); curTokenPos = ts.getCurrentPos(); if (token == null) break; // may be necessary if we end in a comment tokenStartChar = token.charAt(0); // ----------------------- // HEADER - <any substate> // ----------------------- if ( parseState == ParseState.HEADER) { if (parseSubState == null) { if (token.equals("package") ) { parseSubState = ParseSubState.PACKAGE; continue; } else if (token.equals("import") ) { parseSubState = ParseSubState.IMPORT; continue; } else if (Character.isJavaIdentifierStart(tokenStartChar) ) { parseState = ParseState.POST_HEADER; parseSubState = ParseSubState.SCANNING; // fall into ParseState.POST_HEADER processing } else { String lastMsgStr = "Expecting package/import or package member definition."; if (!lastMsgStr.equals(msgStr) || lastTokenLine != curTokenLine ) { // i.e. log only if not already logged for this line. msgStr = lastMsgStr; // Create error node and increment count results.incErrorCount(); messageElement = new UML.Message(msgStr, UML.Type.ERROR, parentNode.getElement(), curTokenLine); insertAsNode(messageElement, curElementStartPos, parentNode); } // suppress repeats continue; } } else if (parseSubState == ParseSubState.PACKAGE) { if (token.equals(";") ) { parseSubState = ParseSubState.POST_PACKAGE; } continue; } else if (parseSubState == ParseSubState.POST_PACKAGE) { if (token.equals("import") ) { parseSubState = ParseSubState.IMPORT; continue; } else if (Character.isJavaIdentifierStart(tokenStartChar) ) { parseState = ParseState.POST_HEADER; parseSubState = ParseSubState.SCANNING; // fall into ParseState.POST_HEADER processing } else { String lastMsgStr = "Expecting import or package member definition."; if (!lastMsgStr.equals(msgStr) || lastTokenLine != curTokenLine ) { // i.e. log only if not already logged for this line. msgStr = lastMsgStr; // Create error node and increment count results.incErrorCount(); messageElement = new UML.Message(msgStr, UML.Type.ERROR, parentNode.getElement(), curTokenLine); insertAsNode(messageElement, curElementStartPos, parentNode); } // suppress repeats continue; } } else if (parseSubState == ParseSubState.IMPORT) { if (token.equals(";") ) { parseSubState = ParseSubState.POST_PACKAGE; } continue; } // if - else if for HEADER - <any substate> } // if (ParseState == ParseState.HEADER) // ---------------------------- // POST_HEADER - <any substate> // ---------------------------- if (parseState == ParseState.POST_HEADER) { // these tokens should put me in a class/interface and lead me to its body if (curElementStartPos == -1) { curElementStartPos = ls.getStartOffset() + curTokenPos; className = null; mod = 0; badFlag = false; } if ( Character.isJavaIdentifierStart(tokenStartChar) ) { if (className == null) { if (token.equals("abstract") ) { mod = RWModifier.setAbstract(mod); } else if (token.equals("final") ) { mod = RWModifier.setFinal(mod); } else if (token.equals("interface") ) { mod = RWModifier.setInterface(mod);// } else if (token.equals("native") ) { // n/a for class/interface// mod = RWModifier.setNative(mod);// } else if (token.equals("private") ) { // n/a for class/interface// mod = RWModifier.setPrivate(mod);// } else if (token.equals("protected") ) { // n/a for class/interface// mod = RWModifier.setProtected(mod); } else if (token.equals("public") ) { mod = RWModifier.setPublic(mod);// } else if (token.equals("static") ) { // n/a for class/interface// mod = RWModifier.setStatic(mod); } else if (token.equals("strictfp") ) { mod = RWModifier.setStrict(mod); } else if (token.equals("synchronized") ) { // n/a for class/interface mod = RWModifier.setSynchronized(mod);// } else if (token.equals("transient") ) { // n/a for class/interface// mod = RWModifier.setTransient(mod);// } else if (token.equals("volatile") ) { // n/a for class/interface// mod = RWModifier.setVolatile(mod); } else if (token.equals("class") ) { mod = RWModifier.setClass(mod); } else if ( RWModifier.isClassOrInterface(mod) ) { className = token; } else { // identifier found (not modifier) // where "class"/"interface" not yet specified badFlag = true; } } // if (className == null) } else if (token.equals("{") ) { // non-identifier token where name not yet found if ( RWModifier.isClassOrInterface(mod) ) { className = MISSING_LABEL; } else { badFlag = true; } } else { // non-identifier token where name not yet found badFlag = true; } // i.e. isJavaIdentifierStart() if (className != null) { packageMemberStartPos = curElementStartPos; packageMemberLine = curTokenLine; // Determine node type and insert if ( RWModifier.isInterface(mod) ) { eType = UML.Type.INTERFACE; results.incInterfaceCount(); } else if (parentNode != root && !(RWModifier.isStatic(mod))) { eType = UML.Type.INNER_CLASS; results.incClassCount(); } else { eType = UML.Type.CLASS; results.incClassCount(); } // Create and insert class/interface node if (parentNode == root) { currentElement = new UML.PackageMember(className, eType, mod,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -