[Pydev-cvs] org.python.pydev/src/org/python/pydev/parser package.html,NONE,1.1 PyParser.java,1.5,1.6
Brought to you by:
fabioz
From: Aleksandar T. <at...@us...> - 2004-04-10 02:01:39
|
Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/parser In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv649/src/org/python/pydev/parser Modified Files: PyParser.java Added Files: package.html Log Message: Huge code rewrite. I've implemented a Python model. Model is based in AST tree, but should be simpler to use. No more visitor pattern. OutlineView and Navigation actions have been reworked to use new model, instead of traversing AST. Added Hyperlinking capability, but goto is not implemetned yet. --- NEW FILE: package.html --- <body> Pydev interface to Python parser. <p>Every {@link org.python.pydev.editor.PyEdit PyEdit} has a PyParser associated with it. The parser continuously parses the input into AST (Abstract Syntax Tree). Listeners can register with PyParser to receive events when parse is complete. <p>PyParser is used by everyone who needs access to the underlying Python structure: {@link org.python.pydev.outline.ParsedModel outliner}, {@link org.python.pydev.editor.dictionary.PyDEditorItem dictionary}. </body> Index: PyParser.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/parser/PyParser.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** PyParser.java 30 Mar 2004 01:03:38 -0000 1.5 --- PyParser.java 10 Apr 2004 01:48:14 -0000 1.6 *************** *** 42,65 **** IDocument document; PyEdit editorView; ! SimpleNode root = null; IDocumentListener documentListener; // listens to changes in the document ArrayList parserListeners; // listeners that get notified ! ! static final boolean parseOnThread = true; // can turn of thread parsing for debugging ! ParsingThread parsingThread; // thread that reparses the document ! public PyParser(PyEdit editorView) { this.editorView = editorView; parserListeners = new ArrayList(); ! parsingThread = new ParsingThread(this); ! parsingThread.setName("Pydev parsing thread"); } public void dispose() { // remove the listeners if (document != null) document.removeDocumentListener(documentListener); ! parsingThread.diePlease(); } --- 42,79 ---- IDocument document; PyEdit editorView; ! SimpleNode root = null; // Document root IDocumentListener documentListener; // listens to changes in the document ArrayList parserListeners; // listeners that get notified ! ! final static int PARSE_LATER_INTERVAL = 20; // 20 = 2 seconds ! ! boolean parseNow = false; // synchronized access by ParsingThread ! /* counter how to parse. ! * 0 means do not parse, > 0 means wait this many loops in main thread ! */ ! int parseLater = 0; // synchronized access by ParsingThread ! public PyParser(PyEdit editorView) { this.editorView = editorView; parserListeners = new ArrayList(); ! ParsingThread.getParsingThread().register(this); ! } ! ! public void parseNow() { ! parseNow = true; } + public void parseLater() { + parseNow = false; + parseLater = PARSE_LATER_INTERVAL; // delay of 1 second + } + public void dispose() { // remove the listeners if (document != null) document.removeDocumentListener(documentListener); ! parserListeners.clear(); ! ParsingThread.getParsingThread().unregister(this); } *************** *** 80,94 **** return; } documentListener = new IDocumentListener() { public void documentChanged(DocumentEvent event) { - if (parseOnThread == true) { if (event.getText().indexOf("\n") == -1) // carriage return in changed text means parse now, anything else means parse later ! parsingThread.parseLater(); else ! parsingThread.parseNow(); ! } ! else ! reparseDocument(); } public void documentAboutToBeChanged(DocumentEvent event) {} --- 94,105 ---- return; } + final PyParser parser = this; documentListener = new IDocumentListener() { public void documentChanged(DocumentEvent event) { if (event.getText().indexOf("\n") == -1) // carriage return in changed text means parse now, anything else means parse later ! parseLater(); else ! parseNow(); } public void documentAboutToBeChanged(DocumentEvent event) {} *************** *** 96,104 **** document.addDocumentListener(documentListener); // Reparse document on the initial set ! parsingThread.start(); ! if (parseOnThread == true) ! parsingThread.parseNow(); ! else ! reparseDocument(); } --- 107,111 ---- document.addDocumentListener(documentListener); // Reparse document on the initial set ! parseNow(); } *************** *** 179,182 **** --- 186,191 ---- * Utility thread that reparses document as needed. * + * Singleton. + * * Current algorithm is: * - if parseLater is called, parse 10 main loops later *************** *** 184,248 **** */ class ParsingThread extends Thread { - PyParser parser; - boolean stayingAlive = true; - boolean parseNow = false; - /* counter how to parse. - * 0 means do not parse, > 0 means wait this many loops in main thread - */ - int parseLater = 0; - - final static int PARSE_LATER_INTERVAL = 20; // 20 = 2 seconds - - ParsingThread(PyParser parser) { - this.parser = parser; - } - - /** - * - * @throws InterruptedException - */ - public synchronized void waitForChange() throws InterruptedException { - if (!parseNow && parseLater == 0) - wait(); - } ! public synchronized void parseNow() { ! parseNow = true; ! notify(); ! } ! public synchronized void parseLater() { ! parseLater = PARSE_LATER_INTERVAL; // delay of 1 second ! notify(); ! } ! public synchronized void doNotParse() { ! parseLater = 0; ! parseNow = false; } ! public synchronized void diePlease() { ! stayingAlive = false; ! notify(); } public void run() { // wait for document change, and reparse try { ! while (stayingAlive) { ! parseLater--; ! if (parseLater == 1) ! parseNow(); ! if (parseNow) { ! doNotParse(); ! if (stayingAlive) ! parser.reparseDocument(); } sleep(100); // sleep a bit, to avoid flicker - waitForChange(); } } catch (InterruptedException e) { ! return; ! } } } --- 193,268 ---- */ class ParsingThread extends Thread { ! private static ParsingThread thread = null; ! private static ArrayList parsers = new ArrayList(); // synchronized access only ! private boolean done = false; ! private ParsingThread() { ! setName("Pydev parsing thread"); } ! static public ParsingThread getParsingThread() { ! synchronized(ParsingThread.class) { ! if (thread == null) { ! thread = new ParsingThread(); ! thread.start(); ! } ! return thread; ! } } + public void register(PyParser parser) { + synchronized(parsers) { + parsers.add(parser); + } + } + + public void unregister(PyParser parser) { + synchronized(parsers) { + parser.parseNow = false; + parser.parseLater = 0; + parsers.remove(parser); + if (parsers.size() == 0) { + done = true; + thread = null; + } + } + } + public void run() { // wait for document change, and reparse try { ! while (!done) { ! ArrayList parseUs = new ArrayList(); ! ! // Populate the list of parsers waiting to be parsed ! synchronized(parsers) { ! Iterator i = parsers.iterator(); ! while (i.hasNext()) { ! PyParser p = (PyParser)i.next(); ! p.parseLater--; ! if (p.parseLater == 1) ! p.parseNow = true; ! if (p.parseNow) ! parseUs.add(p); ! } ! } ! ! Iterator i = parseUs.iterator(); ! while (i.hasNext()) { ! PyParser p = (PyParser)i.next(); ! if (p.parseNow) { ! p.parseNow = false; ! p.reparseDocument(); ! } } sleep(100); // sleep a bit, to avoid flicker } } catch (InterruptedException e) { ! } finally { ! if (thread == this) ! thread = null; ! } } } |