[Pydev-cvs] org.python.pydev.parser/src/org/python/pydev/parser ErrorDescription.java, NONE, 1.1 Pa
Brought to you by:
fabioz
From: Fabio Z. <fa...@us...> - 2008-09-27 20:02:53
|
Update of /cvsroot/pydev/org.python.pydev.parser/src/org/python/pydev/parser In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20472/src/org/python/pydev/parser Modified Files: ParserScheduler.java PyParserManager.java ParsingThread.java ParserPlugin.java PyParser.java CompilerAPI.java Added Files: ErrorDescription.java Log Message: Synching to latest changes: Pydev <ul> <li><strong>Editor</strong>: Cursor settings no longer overridden</li> <li><strong>Code-completion</strong>: If __all__ is defined with runtime elements (and not only in a single assign statement), it's ignored for code-completion purposes</li> <li><strong>Debugger</strong>: Pythonpath the same in debug and regular modes (sys.path[0] is the same directory as the file run)</li> <li><strong>Debugger</strong>: Persist choices done in the debugger when files from the debugger are not found</li> <li><strong>Interpreter config</strong>: "email" automatically added to the "forced builtins"</li> <li><strong>Parser</strong>: Correctly recognizing absolute import with 3 or more levels</li> <li><strong>Syntax check</strong>: Option to do only on active editor</li> </ul> Also: tabs changed for spaces Index: CompilerAPI.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.parser/src/org/python/pydev/parser/CompilerAPI.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** CompilerAPI.java 20 Mar 2006 19:37:35 -0000 1.2 --- CompilerAPI.java 27 Sep 2008 19:58:43 -0000 1.3 *************** *** 13,45 **** */ public class CompilerAPI implements IParserHost { ! public Object newInteger(int i) { ! return new java.lang.Integer(i); ! } ! public Object newLong(String s) { ! return new java.lang.Long(s); ! } ! public Object newLong(java.math.BigInteger i) { ! return i; ! } ! public Object newImaginary(double v) { ! return new java.lang.Double(v); ! } ! public static Object newFloat(float v) { ! return new java.lang.Float(v); ! } ! public Object newFloat(double v) { ! return new java.lang.Float(v); ! } ! /** ! * TODO how do I implement Unicode decoding in Java? ! */ ! public String decode_UnicodeEscape(String str, int start, int end, String errors, boolean unicode) { ! return str.substring(start, end); ! } } \ No newline at end of file --- 13,45 ---- */ public class CompilerAPI implements IParserHost { ! public Object newInteger(int i) { ! return new java.lang.Integer(i); ! } ! public Object newLong(String s) { ! return new java.lang.Long(s); ! } ! public Object newLong(java.math.BigInteger i) { ! return i; ! } ! public Object newImaginary(double v) { ! return new java.lang.Double(v); ! } ! public static Object newFloat(float v) { ! return new java.lang.Float(v); ! } ! public Object newFloat(double v) { ! return new java.lang.Float(v); ! } ! /** ! * TODO how do I implement Unicode decoding in Java? ! */ ! public String decode_UnicodeEscape(String str, int start, int end, String errors, boolean unicode) { ! return str.substring(start, end); ! } } \ No newline at end of file Index: ParserScheduler.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.parser/src/org/python/pydev/parser/ParserScheduler.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ParserScheduler.java 3 Apr 2007 18:44:58 -0000 1.5 --- ParserScheduler.java 27 Sep 2008 19:58:43 -0000 1.6 *************** *** 12,16 **** * used to do parsings in a thread - is null when not doing parsings */ ! public ParsingThread parsingThread; /** --- 12,16 ---- * used to do parsings in a thread - is null when not doing parsings */ ! public volatile ParsingThread parsingThread; /** *************** *** 25,29 **** /** ! * indicates if a thread is currently waiting for an elapse cicle to end */ public static final int STATE_WAITING_FOR_ELAPSE = 2; --- 25,29 ---- /** ! * indicates if a thread is currently waiting for an elapse cycle to end */ public static final int STATE_WAITING_FOR_ELAPSE = 2; *************** *** 103,110 **** */ private boolean checkCreateAndStartParsingThread() { ! if(parsingThread == null){ ! parsingThread = new ParsingThread(this); ! parsingThread.setPriority(Thread.MIN_PRIORITY); //parsing is low priority ! parsingThread.start(); return true; } --- 103,112 ---- */ private boolean checkCreateAndStartParsingThread() { ! ParsingThread p = parsingThread; ! if(p == null){ ! p = new ParsingThread(this); ! p.setPriority(Thread.MIN_PRIORITY); //parsing is low priority ! p.start(); ! parsingThread = p; return true; } *************** *** 144,148 **** */ public void reparseDocument(Object ... argsToReparse) { ! parser.reparseDocument(argsToReparse); } --- 146,162 ---- */ public void reparseDocument(Object ... argsToReparse) { ! PyParser p = parser; ! if(p != null){ ! p.reparseDocument(argsToReparse); ! } ! } ! ! ! public void dispose() { ! ParsingThread p = this.parsingThread; ! if(p != null){ ! p.dispose(); ! } ! this.parser = null; } Index: PyParser.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.parser/src/org/python/pydev/parser/PyParser.java,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -d -r1.51 -r1.52 *** PyParser.java 31 Jul 2008 01:47:14 -0000 1.51 --- PyParser.java 27 Sep 2008 19:58:43 -0000 1.52 *************** *** 6,13 **** --- 6,16 ---- package org.python.pydev.parser; + import java.io.File; import java.io.StringReader; import java.util.ArrayList; + import java.util.HashMap; import java.util.HashSet; import java.util.List; + import java.util.Map; import java.util.Set; *************** *** 19,33 **** --- 22,41 ---- import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; + import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentListener; + import org.eclipse.jface.text.IRegion; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; + import org.eclipse.ui.texteditor.MarkerUtilities; import org.python.pydev.core.ExtensionHelper; + import org.python.pydev.core.ICallback; import org.python.pydev.core.IGrammarVersionProvider; import org.python.pydev.core.IPyEdit; import org.python.pydev.core.IPythonNature; import org.python.pydev.core.Tuple; + import org.python.pydev.core.Tuple3; import org.python.pydev.core.docutils.DocUtils; import org.python.pydev.core.docutils.PySelection; *************** *** 44,47 **** --- 52,56 ---- import org.python.pydev.parser.jython.ReaderCharStream; import org.python.pydev.parser.jython.SimpleNode; + import org.python.pydev.parser.jython.Token; import org.python.pydev.parser.jython.TokenMgrError; import org.python.pydev.parser.jython.ast.Module; *************** *** 115,118 **** --- 124,132 ---- private IGrammarVersionProvider grammarVersionProvider; + /** + * Identifies whether this parser is disposed. + */ + private volatile boolean disposed = false; + public static String getGrammarVersionStr(int grammarVersion){ *************** *** 146,172 **** public void documentChanged(DocumentEvent event) { String text = event.getText(); boolean parseNow = true; if (event == null || text == null ) { ! parseNow = false; } if(parseNow){ ! if(text.indexOf("\n") == -1 && text.indexOf("\r") == -1){ ! parseNow = false; ! ! } } ! if(!parseNow){ // carriage return in changed text means parse now, anything // else means parse later ! if(!useAnalysisOnlyOnDocSave){ ! scheduler.parseLater(); ! } } else { ! if(!useAnalysisOnlyOnDocSave){ ! scheduler.parseNow(); ! } } } --- 160,188 ---- public void documentChanged(DocumentEvent event) { + if(useAnalysisOnlyOnDocSave){ + //if we're doing analysis only on doc change, the parser will not give any changes + //to the scheduler, so, we won't have any parse events to respond to + return; + + } String text = event.getText(); boolean parseNow = true; if (event == null || text == null ) { ! parseNow = false; } if(parseNow){ ! if(text.indexOf("\n") == -1 && text.indexOf("\r") == -1){ ! parseNow = false; ! ! } } ! if(!parseNow){ // carriage return in changed text means parse now, anything // else means parse later ! scheduler.parseLater(); } else { ! scheduler.parseNow(); } } *************** *** 191,207 **** * @return a provider signaling the grammar to be used for the parser. */ ! private static IGrammarVersionProvider getGrammarProviderFromEdit(IPyEdit editorView) { ! try { ! return editorView.getPythonNature(); ! } catch (RuntimeException e) { ! //let's treat that correctly even if we do not have a default grammar (just log it) ! return new IGrammarVersionProvider(){ ! public int getGrammarVersion() { ! return IGrammarVersionProvider.LATEST_GRAMMAR_VERSION; ! } ! }; ! } ! } --- 207,223 ---- * @return a provider signaling the grammar to be used for the parser. */ ! private static IGrammarVersionProvider getGrammarProviderFromEdit(IPyEdit editorView) { ! try { ! return editorView.getPythonNature(); ! } catch (RuntimeException e) { ! //let's treat that correctly even if we do not have a default grammar (just log it) ! return new IGrammarVersionProvider(){ ! public int getGrammarVersion() { ! return IGrammarVersionProvider.LATEST_GRAMMAR_VERSION; ! } ! }; ! } ! } *************** *** 210,213 **** --- 226,232 ---- */ public void dispose() { + this.disposed = true; + this.scheduler.dispose(); + // remove the listeners if (document != null){ *************** *** 215,219 **** } synchronized(parserListeners){ ! parserListeners.clear(); } } --- 234,238 ---- } synchronized(parserListeners){ ! parserListeners.clear(); } } *************** *** 229,233 **** public void forceReparse(Object ... argsToReparse){ ! scheduler.parseNow(true, argsToReparse); } --- 248,255 ---- public void forceReparse(Object ... argsToReparse){ ! if(disposed){ ! return; ! } ! scheduler.parseNow(true, argsToReparse); } *************** *** 239,243 **** public void setDocument(IDocument document, IEditorInput input) { ! setDocument(document, true, input); } --- 261,265 ---- public void setDocument(IDocument document, IEditorInput input) { ! setDocument(document, true, input); } *************** *** 259,264 **** if(addToScheduler){ ! // Reparse document on the initial set (force it) ! scheduler.parseNow(true); } } --- 281,286 ---- if(addToScheduler){ ! // Reparse document on the initial set (force it) ! scheduler.parseNow(true); } } *************** *** 269,275 **** Assert.isNotNull(listener); synchronized(parserListeners){ ! if (!parserListeners.contains(listener)){ ! parserListeners.add(listener); ! } } } --- 291,297 ---- Assert.isNotNull(listener); synchronized(parserListeners){ ! if (!parserListeners.contains(listener)){ ! parserListeners.add(listener); ! } } } *************** *** 279,283 **** Assert.isNotNull(listener); synchronized(parserListeners){ ! parserListeners.remove(listener); } } --- 301,305 ---- Assert.isNotNull(listener); synchronized(parserListeners){ ! parserListeners.remove(listener); } } *************** *** 290,311 **** */ @SuppressWarnings("unchecked") ! protected void fireParserChanged(SimpleNode root, IAdaptable file, IDocument doc, Object ... argsToReparse) { this.root = root; synchronized(parserListeners){ ! for (IParserObserver l : new ArrayList<IParserObserver>(parserListeners)) { //work on a copy (because listeners may want to remove themselves and we cannot afford concurrent modifications here) ! if(l instanceof IParserObserver2){ ! ((IParserObserver2)l).parserChanged(root, file, doc, argsToReparse); ! }else{ ! l.parserChanged(root, file, doc); ! } ! } ! List<IParserObserver> participants = ExtensionHelper.getParticipants(ExtensionHelper.PYDEV_PARSER_OBSERVER); for (IParserObserver observer : participants) { ! if(observer instanceof IParserObserver2){ ! ((IParserObserver2)observer).parserChanged(root, file, doc, argsToReparse); ! }else{ ! observer.parserChanged(root, file, doc); ! } } } --- 312,333 ---- */ @SuppressWarnings("unchecked") ! protected void fireParserChanged(SimpleNode root, IAdaptable file, IDocument doc, Object ... argsToReparse) { this.root = root; synchronized(parserListeners){ ! for (IParserObserver l : new ArrayList<IParserObserver>(parserListeners)) { //work on a copy (because listeners may want to remove themselves and we cannot afford concurrent modifications here) ! if(l instanceof IParserObserver2){ ! ((IParserObserver2)l).parserChanged(root, file, doc, argsToReparse); ! }else{ ! l.parserChanged(root, file, doc); ! } ! } ! List<IParserObserver> participants = ExtensionHelper.getParticipants(ExtensionHelper.PYDEV_PARSER_OBSERVER); for (IParserObserver observer : participants) { ! if(observer instanceof IParserObserver2){ ! ((IParserObserver2)observer).parserChanged(root, file, doc, argsToReparse); ! }else{ ! observer.parserChanged(root, file, doc); ! } } } *************** *** 317,336 **** */ @SuppressWarnings("unchecked") ! protected void fireParserError(Throwable error, IAdaptable file, IDocument doc, Object ... argsToReparse) { synchronized(parserListeners){ ! for (IParserObserver l : new ArrayList<IParserObserver>(parserListeners)) {//work on a copy (because listeners may want to remove themselves and we cannot afford concurrent modifications here) ! if(l instanceof IParserObserver2){ ! ((IParserObserver2)l).parserError(error, file, doc, argsToReparse); ! }else{ ! l.parserError(error, file, doc); ! } } List<IParserObserver> participants = ExtensionHelper.getParticipants(ExtensionHelper.PYDEV_PARSER_OBSERVER); for (IParserObserver observer : participants) { ! if(observer instanceof IParserObserver2){ ! ((IParserObserver2)observer).parserError(error, file, doc, argsToReparse); ! }else{ ! observer.parserError(error, file, doc); ! } } } --- 339,358 ---- */ @SuppressWarnings("unchecked") ! protected void fireParserError(Throwable error, IAdaptable file, IDocument doc, Object ... argsToReparse) { synchronized(parserListeners){ ! for (IParserObserver l : new ArrayList<IParserObserver>(parserListeners)) {//work on a copy (because listeners may want to remove themselves and we cannot afford concurrent modifications here) ! if(l instanceof IParserObserver2){ ! ((IParserObserver2)l).parserError(error, file, doc, argsToReparse); ! }else{ ! l.parserError(error, file, doc); ! } } List<IParserObserver> participants = ExtensionHelper.getParticipants(ExtensionHelper.PYDEV_PARSER_OBSERVER); for (IParserObserver observer : participants) { ! if(observer instanceof IParserObserver2){ ! ((IParserObserver2)observer).parserError(error, file, doc, argsToReparse); ! }else{ ! observer.parserError(error, file, doc); ! } } } *************** *** 373,399 **** //delete the markers if (original != null){ ! try { ! IMarker[] markers = original.findMarkers(IMarker.PROBLEM, false, IResource.DEPTH_ZERO); ! if(markers.length > 0){ ! original.deleteMarkers(IMarker.PROBLEM, false, IResource.DEPTH_ZERO); ! } ! } catch (ResourceException e) { ! //ok, if it is a resource exception, it may have happened because the resource does not exist anymore ! //so, there is no need to log this failure if(original.exists()){ Log.log(e); } ! } catch (CoreException e) { ! Log.log(e); ! } ! }else if(adaptable == null){ ! //ok, we have nothing... maybe we are in tests... ! if (!PyParser.ACCEPT_NULL_INPUT_EDITOR){ ! throw new RuntimeException("Null input editor received in parser!"); ! } } //end delete the markers if(obj.o1 != null){ //ok, reparse succesful, lets erase the markers that are in the editor we just parsed --- 395,425 ---- //delete the markers if (original != null){ ! try { ! deleteErrorMarkers(original); ! } catch (ResourceException e) { ! //ok, if it is a resource exception, it may have happened because the resource does not exist anymore ! //so, there is no need to log this failure if(original.exists()){ Log.log(e); } ! } catch (CoreException e) { ! Log.log(e); ! } ! }else if(adaptable == null){ ! //ok, we have nothing... maybe we are in tests... ! if (!PyParser.ACCEPT_NULL_INPUT_EDITOR){ ! throw new RuntimeException("Null input editor received in parser!"); ! } } //end delete the markers + + if(disposed){ + //if it was disposed in this time, don't fire any notification nor return anything valid. + return new Tuple<SimpleNode, Throwable>(null, null); + } + + if(obj.o1 != null){ //ok, reparse succesful, lets erase the markers that are in the editor we just parsed *************** *** 411,414 **** --- 437,452 ---- return obj; } + + /** + * This function will remove the markers related to errors. + * @param resource the file that should have the markers removed + * @throws CoreException + */ + public static void deleteErrorMarkers(IResource resource) throws CoreException { + IMarker[] markers = resource.findMarkers(IMarker.PROBLEM, false, IResource.DEPTH_ZERO); + if(markers.length > 0){ + resource.deleteMarkers(IMarker.PROBLEM, false, IResource.DEPTH_ZERO); + } + } *************** *** 419,422 **** --- 457,461 ---- public static class ParserInfo{ public IDocument document; + public boolean stillTryToChangeCurrentLine=true; *************** *** 453,471 **** /** * @param grammarVersion: see IPythonNature.GRAMMAR_XXX constants */ ! public ParserInfo(IDocument document, boolean changedCurrentLine, int grammarVersion){ ! this.document = document; ! this.stillTryToChangeCurrentLine = changedCurrentLine; ! this.grammarVersion = grammarVersion; } ! public ParserInfo(IDocument document, boolean changedCurrentLine, IPythonNature nature){ ! this(document, changedCurrentLine, nature.getGrammarVersion()); } ! public ParserInfo(IDocument document, boolean changedCurrentLine, IPythonNature nature, int currentLine){ ! this(document, changedCurrentLine, nature); ! this.currentLine = currentLine; } } --- 492,530 ---- /** + * The module name of the contents parsed (may be null) + */ + public final String moduleName; + + /** + * The file that's been parsed (may be null) + */ + public final File file; + + /** * @param grammarVersion: see IPythonNature.GRAMMAR_XXX constants */ ! public ParserInfo(IDocument document, boolean stillTryToChangeCurrentLine, int grammarVersion){ ! this(document, stillTryToChangeCurrentLine, grammarVersion, -1, null, null); } ! public ParserInfo(IDocument document, boolean stillTryToChangeCurrentLine, IPythonNature nature){ ! this(document, stillTryToChangeCurrentLine, nature.getGrammarVersion()); } ! public ParserInfo(IDocument document, boolean stillTryToChangeCurrentLine, IPythonNature nature, int currentLine, String moduleName, File file){ ! this(document, stillTryToChangeCurrentLine, nature.getGrammarVersion(), currentLine, moduleName, file); ! } ! ! public ParserInfo(IDocument document, boolean stillTryToChangeCurrentLine, IPythonNature nature, int currentLine){ ! this(document, stillTryToChangeCurrentLine, nature.getGrammarVersion(), currentLine, null, null); ! } ! ! public ParserInfo(IDocument document, boolean stillTryToChangeCurrentLine, int grammarVersion, ! int currentLine, String name, File f) { ! this.document = document; ! this.stillTryToChangeCurrentLine = stillTryToChangeCurrentLine; ! this.grammarVersion = grammarVersion; ! this.moduleName = name; ! this.file = f; } } *************** *** 566,569 **** --- 625,635 ---- } + + /** + * This list of callbacks is mostly used for testing, so that we can check what's been parsed. + */ + public final static List<ICallback<Object, Tuple3<SimpleNode, Throwable, ParserInfo>>> successfulParseListeners = + new ArrayList<ICallback<Object, Tuple3<SimpleNode, Throwable, ParserInfo>>>(); + /** *************** *** 592,602 **** //we don't want to keep the string from being released, so, just get the char array from the string char[] cs = newDoc.get().toCharArray(); ! in = new FastCharStream(cs); }else{ ! //this should be deprecated in the future (it is still here so that we can evaluate ! //the changes done by the change of the reader). String initialDoc = newDoc.get(); ! StringReader inString = new StringReader(initialDoc); ! in = new ReaderCharStream(inString); throw new RuntimeException("This char stream reader was deprecated (was maintained only for testing purposes)."); } --- 658,668 ---- //we don't want to keep the string from being released, so, just get the char array from the string char[] cs = newDoc.get().toCharArray(); ! in = new FastCharStream(cs); }else{ ! //this should be deprecated in the future (it is still here so that we can evaluate ! //the changes done by the change of the reader). String initialDoc = newDoc.get(); ! StringReader inString = new StringReader(initialDoc); ! in = new ReaderCharStream(inString); throw new RuntimeException("This char stream reader was deprecated (was maintained only for testing purposes)."); } *************** *** 612,621 **** } try { ! ! if(ENABLE_TRACING){ ! //grammar has to be generated with debugging info for this to make a difference ! grammar.enable_tracing(); ! } SimpleNode newRoot = grammar.file_input(); // parses the file if(newRoot != null){ --- 678,688 ---- } + Tuple<SimpleNode, Throwable> returnVar = new Tuple<SimpleNode, Throwable>(null, null); try { ! ! if(ENABLE_TRACING){ ! //grammar has to be generated with debugging info for this to make a difference ! grammar.enable_tracing(); ! } SimpleNode newRoot = grammar.file_input(); // parses the file if(newRoot != null){ *************** *** 625,630 **** } } ! return new Tuple<SimpleNode, Throwable>(newRoot,null); ! } catch (Throwable e) { --- 692,706 ---- } } ! returnVar.o1 = newRoot; ! ! //only notify successful parses ! if(successfulParseListeners.size() > 0){ ! Tuple3<SimpleNode, Throwable, ParserInfo> param = new Tuple3<SimpleNode, Throwable, ParserInfo>( ! returnVar.o1, returnVar.o2, info); ! ! for(ICallback<Object, Tuple3<SimpleNode, Throwable, ParserInfo>> callback: successfulParseListeners){ ! callback.call(param); ! } ! } } catch (Throwable e) { *************** *** 655,659 **** } } ! return new Tuple<SimpleNode, Throwable>(newRoot, parseErr); }else if(e instanceof TokenMgrError){ --- 731,736 ---- } } ! ! returnVar = new Tuple<SimpleNode, Throwable>(newRoot, parseErr); }else if(e instanceof TokenMgrError){ *************** *** 667,671 **** } ! return new Tuple<SimpleNode, Throwable>(newRoot, tokenErr); }else if(e.getClass().getName().indexOf("LookaheadSuccess") != -1){ --- 744,748 ---- } ! returnVar = new Tuple<SimpleNode, Throwable>(newRoot, tokenErr); }else if(e.getClass().getName().indexOf("LookaheadSuccess") != -1){ *************** *** 674,682 **** Log.log(e); } - return new Tuple<SimpleNode, Throwable>(null, null); } } /** * @param tokenErr --- 751,761 ---- Log.log(e); } } + + return returnVar; } + /** * @param tokenErr *************** *** 715,720 **** line = tokenErr.currentToken.beginLine-2; ! }else{ ! return null; } } --- 794,799 ---- line = tokenErr.currentToken.beginLine-2; ! }else{ ! return null; } } *************** *** 775,779 **** info.document = doc; info.stillTryToChangeCurrentLine = false; ! return reparseDocument(info).o1; } return null; --- 854,858 ---- info.document = doc; info.stillTryToChangeCurrentLine = false; ! return reparseDocument(info).o1; } return null; *************** *** 788,791 **** --- 867,963 ---- } + /** + * Adds the error markers for some error that was found in the parsing process. + * + * @param error the error find while parsing the document + * @param resource the resource that should have the error added + * @param doc the document with the resource contents + * @return the error description (or null) + * + * @throws BadLocationException + * @throws CoreException + */ + public static ErrorDescription createParserErrorMarkers(Throwable error, IAdaptable resource, IDocument doc) + throws BadLocationException, CoreException { + ErrorDescription errDesc; + if(resource == null){ + return null; + } + IResource fileAdapter = (IResource) resource.getAdapter(IResource.class); + if(fileAdapter == null){ + return null; + } + + errDesc = createErrorDesc(error, doc); + + Map<String, Object> map = new HashMap<String, Object>(); + + map.put(IMarker.MESSAGE, errDesc.message); + map.put(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); + map.put(IMarker.LINE_NUMBER, errDesc.errorLine); + map.put(IMarker.CHAR_START, errDesc.errorStart); + map.put(IMarker.CHAR_END, errDesc.errorEnd); + map.put(IMarker.TRANSIENT, true); + MarkerUtilities.createMarker(fileAdapter, map, IMarker.PROBLEM); + return errDesc; + } + + + /** + * Creates the error description for a given error in the parse. + */ + private static ErrorDescription createErrorDesc(Throwable error, IDocument doc) throws BadLocationException { + int errorStart = -1; + int errorEnd = -1; + int errorLine = -1; + String message = null; + if (error instanceof ParseException) { + ParseException parseErr = (ParseException) error; + + // Figure out where the error is in the document, and create a + // marker for it + if(parseErr.currentToken == null){ + IRegion endLine = doc.getLineInformationOfOffset(doc.getLength()); + errorStart = endLine.getOffset(); + errorEnd = endLine.getOffset() + endLine.getLength(); + + }else{ + Token errorToken = parseErr.currentToken.next != null ? parseErr.currentToken.next : parseErr.currentToken; + IRegion startLine = doc.getLineInformation(errorToken.beginLine - 1); + IRegion endLine; + if (errorToken.endLine == 0){ + endLine = startLine; + }else{ + endLine = doc.getLineInformation(errorToken.endLine - 1); + } + errorStart = startLine.getOffset() + errorToken.beginColumn - 1; + errorEnd = endLine.getOffset() + errorToken.endColumn; + } + message = parseErr.getMessage(); + + } else if(error instanceof TokenMgrError){ + TokenMgrError tokenErr = (TokenMgrError) error; + IRegion startLine = doc.getLineInformation(tokenErr.errorLine - 1); + errorStart = startLine.getOffset(); + errorEnd = startLine.getOffset() + tokenErr.errorColumn; + message = tokenErr.getMessage(); + } else{ + Log.log("Error, expecting ParseException or TokenMgrError. Received: "+error); + return new ErrorDescription(null, 0, 0, 0); + } + errorLine = doc.getLineOfOffset(errorStart); + + // map.put(IMarker.LOCATION, "Whassup?"); this is the location field + // in task manager + if (message != null) { // prettyprint + message = message.replaceAll("\\r\\n", " "); + message = message.replaceAll("\\r", " "); + message = message.replaceAll("\\n", " "); + } + + + return new ErrorDescription(message, errorLine, errorStart, errorEnd); + } + Index: PyParserManager.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.parser/src/org/python/pydev/parser/PyParserManager.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PyParserManager.java 3 Apr 2007 18:44:58 -0000 1.2 --- PyParserManager.java 27 Sep 2008 19:58:43 -0000 1.3 *************** *** 88,97 **** String property = event.getProperty(); if(property.equals(USE_PYDEV_ANALYSIS_ONLY_ON_DOC_SAVE) || property.equals(PYDEV_ELAPSE_BEFORE_ANALYSIS)){ ! //reset the caches ! millisBeforeAnalysis = PyParserManager.this.prefs.getInt(PYDEV_ELAPSE_BEFORE_ANALYSIS); ! useOnlyOnSave = PyParserManager.this.prefs.getBoolean(USE_PYDEV_ANALYSIS_ONLY_ON_DOC_SAVE); ! ! ! //and set the needed parsers boolean useAnalysisOnlyOnDocSave = useAnalysisOnlyOnDocSave(); --- 88,97 ---- String property = event.getProperty(); if(property.equals(USE_PYDEV_ANALYSIS_ONLY_ON_DOC_SAVE) || property.equals(PYDEV_ELAPSE_BEFORE_ANALYSIS)){ ! //reset the caches ! millisBeforeAnalysis = PyParserManager.this.prefs.getInt(PYDEV_ELAPSE_BEFORE_ANALYSIS); ! useOnlyOnSave = PyParserManager.this.prefs.getBoolean(USE_PYDEV_ANALYSIS_ONLY_ON_DOC_SAVE); ! ! ! //and set the needed parsers boolean useAnalysisOnlyOnDocSave = useAnalysisOnlyOnDocSave(); --- NEW FILE: ErrorDescription.java --- package org.python.pydev.parser; public class ErrorDescription { public String message; public int errorLine; public int errorStart; public int errorEnd; public ErrorDescription(String message, int errorLine, int errorStart, int errorEnd) { super(); this.message = message; this.errorLine = errorLine; this.errorStart = errorStart; this.errorEnd = errorEnd; } } Index: ParsingThread.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.parser/src/org/python/pydev/parser/ParsingThread.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ParsingThread.java 3 Apr 2007 18:44:58 -0000 1.4 --- ParsingThread.java 27 Sep 2008 19:58:43 -0000 1.5 *************** *** 15,18 **** --- 15,23 ---- private ParserScheduler parser; private Object[] argsToReparse; + + /** + * Identifies whether this parsing thread is disposed. + */ + private boolean disposed; ParsingThread(ParserScheduler parser, Object ... argsToReparse) { *************** *** 24,35 **** public void run() { try { ! if(force == false){ ! makeOkAndSleepUntilIdleTimeElapses(); ! } ! ! while(!okToGo && force == false){ makeOkAndSleepUntilIdleTimeElapses(); } //ok, now we parse it... if we have not been requested to stop it try { --- 29,44 ---- public void run() { try { ! if(force == false){ ! makeOkAndSleepUntilIdleTimeElapses(); ! } ! ! while(!okToGo && force == false && !disposed){ makeOkAndSleepUntilIdleTimeElapses(); } + if(disposed){ + return; + } + //ok, now we parse it... if we have not been requested to stop it try { *************** *** 57,59 **** --- 66,72 ---- } + public void dispose() { + this.disposed = true; + } + } \ No newline at end of file Index: ParserPlugin.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.parser/src/org/python/pydev/parser/ParserPlugin.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ParserPlugin.java 25 Jun 2005 20:23:36 -0000 1.1 --- ParserPlugin.java 27 Sep 2008 19:58:43 -0000 1.2 *************** *** 9,69 **** */ public class ParserPlugin extends AbstractUIPlugin { ! //The shared instance. ! private static ParserPlugin plugin; ! //Resource bundle. ! private ResourceBundle resourceBundle; ! ! /** ! * The constructor. ! */ ! public ParserPlugin() { ! super(); ! plugin = this; ! try { ! resourceBundle = ResourceBundle.getBundle("org.python.pydev.parser.ParserPluginResources"); ! } catch (MissingResourceException x) { ! resourceBundle = null; ! } ! } ! /** ! * This method is called upon plug-in activation ! */ ! public void start(BundleContext context) throws Exception { ! super.start(context); ! } ! /** ! * This method is called when the plug-in is stopped ! */ ! public void stop(BundleContext context) throws Exception { ! super.stop(context); ! } ! /** ! * Returns the shared instance. ! */ ! public static ParserPlugin getDefault() { ! return plugin; ! } ! /** ! * Returns the string from the plugin's resource bundle, ! * or 'key' if not found. ! */ ! public static String getResourceString(String key) { ! ResourceBundle bundle = ParserPlugin.getDefault().getResourceBundle(); ! try { ! return (bundle != null) ? bundle.getString(key) : key; ! } catch (MissingResourceException e) { ! return key; ! } ! } ! /** ! * Returns the plugin's resource bundle, ! */ ! public ResourceBundle getResourceBundle() { ! return resourceBundle; ! } } --- 9,69 ---- */ public class ParserPlugin extends AbstractUIPlugin { ! //The shared instance. ! private static ParserPlugin plugin; ! //Resource bundle. ! private ResourceBundle resourceBundle; ! ! /** ! * The constructor. ! */ ! public ParserPlugin() { ! super(); ! plugin = this; ! try { ! resourceBundle = ResourceBundle.getBundle("org.python.pydev.parser.ParserPluginResources"); ! } catch (MissingResourceException x) { ! resourceBundle = null; ! } ! } ! /** ! * This method is called upon plug-in activation ! */ ! public void start(BundleContext context) throws Exception { ! super.start(context); ! } ! /** ! * This method is called when the plug-in is stopped ! */ ! public void stop(BundleContext context) throws Exception { ! super.stop(context); ! } ! /** ! * Returns the shared instance. ! */ ! public static ParserPlugin getDefault() { ! return plugin; ! } ! /** ! * Returns the string from the plugin's resource bundle, ! * or 'key' if not found. ! */ ! public static String getResourceString(String key) { ! ResourceBundle bundle = ParserPlugin.getDefault().getResourceBundle(); ! try { ! return (bundle != null) ? bundle.getString(key) : key; ! } catch (MissingResourceException e) { ! return key; ! } ! } ! /** ! * Returns the plugin's resource bundle, ! */ ! public ResourceBundle getResourceBundle() { ! return resourceBundle; ! } } |