pydev-cvs Mailing List for PyDev for Eclipse (Page 315)
Brought to you by:
fabioz
You can subscribe to this list here.
2004 |
Jan
|
Feb
(4) |
Mar
(48) |
Apr
(56) |
May
(64) |
Jun
(27) |
Jul
(66) |
Aug
(81) |
Sep
(148) |
Oct
(194) |
Nov
(78) |
Dec
(46) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(125) |
Feb
(126) |
Mar
(163) |
Apr
(133) |
May
(115) |
Jun
(307) |
Jul
(387) |
Aug
(417) |
Sep
(283) |
Oct
(148) |
Nov
(45) |
Dec
(53) |
2006 |
Jan
(240) |
Feb
(200) |
Mar
(267) |
Apr
(231) |
May
(245) |
Jun
(361) |
Jul
(142) |
Aug
(12) |
Sep
(210) |
Oct
(99) |
Nov
(7) |
Dec
(30) |
2007 |
Jan
(161) |
Feb
(511) |
Mar
(265) |
Apr
(74) |
May
(147) |
Jun
(151) |
Jul
(94) |
Aug
(68) |
Sep
(98) |
Oct
(144) |
Nov
(26) |
Dec
(36) |
2008 |
Jan
(98) |
Feb
(107) |
Mar
(199) |
Apr
(113) |
May
(119) |
Jun
(112) |
Jul
(92) |
Aug
(71) |
Sep
(101) |
Oct
(16) |
Nov
|
Dec
|
From: Aleksandar T. <at...@us...> - 2004-04-28 02:49:57
|
Update of /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/model In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6529/src/org/python/pydev/debug/model Modified Files: PyThread.java PySourceLocator.java PyDebugTarget.java PyStackFrame.java Log Message: Stepping is done Index: PyThread.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/model/PyThread.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PyThread.java 27 Apr 2004 19:12:59 -0000 1.2 --- PyThread.java 28 Apr 2004 02:49:48 -0000 1.3 *************** *** 7,10 **** --- 7,11 ---- import org.eclipse.core.resources.IResource; + import org.eclipse.core.runtime.Platform; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; *************** *** 13,16 **** --- 14,18 ---- import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; + import org.eclipse.ui.views.tasklist.ITaskListResourceAdapter; /** *************** *** 163,167 **** public IStackFrame getTopStackFrame() throws DebugException { ! return stack == null ? stack[0] : null; } --- 165,169 ---- public IStackFrame getTopStackFrame() throws DebugException { ! return stack == null ? null : stack[0]; } *************** *** 175,180 **** adapter.equals(IResource.class)) return target.getAdapter(adapter); // ongoing, I do not fully understand all the interfaces they'd like me to support - System.err.println("PythonThread Need adapter " + adapter.toString()); return null; } --- 177,187 ---- adapter.equals(IResource.class)) return target.getAdapter(adapter); + else if (adapter.equals(ITaskListResourceAdapter.class)) + return null; + else { + System.err.println("PythonThread Need adapter " + adapter.toString()); + Platform.getAdapterManager().getAdapter(this, adapter); + } // ongoing, I do not fully understand all the interfaces they'd like me to support return null; } Index: PyStackFrame.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/model/PyStackFrame.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyStackFrame.java 27 Apr 2004 19:12:59 -0000 1.1 --- PyStackFrame.java 28 Apr 2004 02:49:48 -0000 1.2 *************** *** 8,11 **** --- 8,12 ---- import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; + import org.eclipse.core.runtime.IStatus; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; *************** *** 16,19 **** --- 17,21 ---- import org.eclipse.debug.core.model.IVariable; import org.eclipse.ui.views.tasklist.ITaskListResourceAdapter; + import org.python.pydev.debug.core.PydevDebugPlugin; /** *************** *** 37,40 **** --- 39,43 ---- } + public IPath getPath() { return path; *************** *** 64,74 **** public int getCharStart() throws DebugException { ! // TODO Auto-generated method stub ! return 0; } public int getCharEnd() throws DebugException { ! // TODO Auto-generated method stub ! return 0; } --- 67,75 ---- public int getCharStart() throws DebugException { ! return -1; } public int getCharEnd() throws DebugException { ! return -1; } *************** *** 168,170 **** --- 169,199 ---- } + /** + * HACK + * Here to work around eclipse2 annotation marker removal code. + * This makes sure that old stack markers get removed. + * E3 remove me in Eclipse 3 + */ + public int hashCode() { + return 5; + } + /** + * HACK + * Here to work around eclipse2 annotation marker removal code + * E3 remove me in Eclipse 3 + * LaunchView wants to know, + */ + public boolean equals(Object obj) { + if (obj instanceof PyStackFrame) + try { + return path.equals(((PyStackFrame)obj).getPath()) && + (line == ((PyStackFrame)obj).getLineNumber()); + } catch (DebugException e) { + PydevDebugPlugin.log(IStatus.ERROR, "PyStackFrame.equals", null); + return false; + } + else + return super.equals(obj); + } + } Index: PySourceLocator.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/model/PySourceLocator.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PySourceLocator.java 27 Apr 2004 19:12:59 -0000 1.1 --- PySourceLocator.java 28 Apr 2004 02:49:48 -0000 1.2 *************** *** 31,36 **** if (path != null) { IEditorPart part = PydevPlugin.getDefault().doOpenEditor(path, false); ! if (part != null) return part.getEditorInput(); } } --- 31,37 ---- if (path != null) { IEditorPart part = PydevPlugin.getDefault().doOpenEditor(path, false); ! if (part != null) { return part.getEditorInput(); + } } } Index: PyDebugTarget.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/model/PyDebugTarget.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PyDebugTarget.java 27 Apr 2004 19:12:59 -0000 1.2 --- PyDebugTarget.java 28 Apr 2004 02:49:48 -0000 1.3 *************** *** 26,29 **** --- 26,30 ---- import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; + import org.eclipse.ui.views.properties.IPropertySource; import org.python.pydev.debug.core.PydevDebugPlugin; *************** *** 32,35 **** --- 33,37 ---- * TODO Comment this class * Make sure we fire the right org.eclipse.debug.core.DebugEvents + * What happens with debug events? LaunchViewEventHandlerL:: */ public class PyDebugTarget implements IDebugTarget, ILaunchListener { *************** *** 215,218 **** --- 217,221 ---- return launch; else if (adapter.equals(IResource.class)) { + // used by Variable ContextManager, and Project:Properties menu item IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(file); if (files != null && files.length > 0) *************** *** 220,224 **** else return null; ! } else System.err.println("Need adapter " + adapter.toString()); --- 223,228 ---- else return null; ! } else if (adapter.equals(IPropertySource.class)) ! return launch.getAdapter(adapter); else System.err.println("Need adapter " + adapter.toString()); *************** *** 324,327 **** --- 328,333 ---- if (t != null) { t.setSuspended(true, (IStackFrame[])threadNstack[2]); + if (reason == DebugEvent.STEP_END) + System.out.println("need love"); fireEvent(new DebugEvent(t, DebugEvent.SUSPEND, reason)); } |
From: Aleksandar T. <at...@us...> - 2004-04-28 02:49:57
|
Update of /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6529/src/org/python/pydev/debug/core Modified Files: PydevDebugPlugin.java Log Message: Stepping is done Index: PydevDebugPlugin.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/core/PydevDebugPlugin.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PydevDebugPlugin.java 15 Apr 2004 23:24:50 -0000 1.2 --- PydevDebugPlugin.java 28 Apr 2004 02:49:48 -0000 1.3 *************** *** 38,46 **** } /** * @param errorLevel IStatus.[OK|INFO|WARNING|ERROR] */ public static void log(int errorLevel, String message, Throwable e) { ! Status s = new Status(errorLevel, getPluginID(), errorLevel, message, e); getDefault().getLog().log(s); } --- 38,49 ---- } + public static Status makeStatus(int errorLevel, String message, Throwable e) { + return new Status(errorLevel, getPluginID(), errorLevel, message, e); + } /** * @param errorLevel IStatus.[OK|INFO|WARNING|ERROR] */ public static void log(int errorLevel, String message, Throwable e) { ! Status s = makeStatus(errorLevel, message, e); getDefault().getLog().log(s); } |
From: Aleksandar T. <at...@us...> - 2004-04-27 19:13:29
|
Update of /cvsroot/pydev/org.python.pydev.debug/pysrc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10562/pysrc Modified Files: pydevd.py Removed Files: jpydaemon.py Log Message: Stepping works. --- jpydaemon.py DELETED --- Index: pydevd.py =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/pysrc/pydevd.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pydevd.py 22 Apr 2004 10:54:53 -0000 1.1 --- pydevd.py 27 Apr 2004 19:13:20 -0000 1.2 *************** *** 10,14 **** at the daemon are even. Every response uses the same sequence number as the request. ! Commands: --- 10,17 ---- at the daemon are even. Every response uses the same sequence number as the request. ! payload: it is protocol dependent. When response is a complex structure, it ! is returned as XML. Each attribute value is urlencoded, and then the whole ! payload is urlencoded again to prevent stray characters corrupting protocol/xml encodings ! Commands: *************** *** 17,26 **** 101 RUN RDB - - 102 LIST_THREADS RDB RETURN with XML listing of all threads ! 103 THREAD_CREATED PYDB - XML with thread information ! 500 series: errors ! 501 ERROR either - This is reserved for unexpected errors. ! 900 series diagnostics/ok ! 901 VERSION either Version string (1.0) 902 RETURN either Depends on caller - * RDB - remote debugger, the java end --- 20,40 ---- 101 RUN RDB - - 102 LIST_THREADS RDB RETURN with XML listing of all threads ! 103 THREAD_CREATE PYDB - XML with thread information ! 104 THREAD_KILL RDB id kills the thread ! PYDB id nofies RDB that thread was killed ! 105 THREAD_SUSPEND RDB XML of the stack, suspends the thread ! reason for suspension ! PYDB id notifies RDB that thread was suspended ! 106 THREAD_RUN RDB id resume the thread ! PYDB id \t reason notifies RDB that thread was resumed ! 107 STEP_INTO RDB thread_id ! 108 STEP_OVER RDB thread_id ! 109 STEP_RETURN RDB thread_id ! ! 500 series diagnostics/ok ! 901 VERSION either Version string (1.0) Currently just used at startup 902 RETURN either Depends on caller - + 900 series: errors + 501 ERROR either - This is reserved for unexpected errors. * RDB - remote debugger, the java end *************** *** 32,35 **** --- 46,52 ---- from Queue import * from socket import * + import urllib + import time + import inspect VERSION_STRING = "1.0" *************** *** 37,44 **** CMD_RUN = 101 CMD_LIST_THREADS = 102 ! CMD_THREAD_CREATED = 103 ! CMD_ERROR = 501 ! CMD_VERSION = 901 ! CMD_RETURN = 902 Debugger = None --- 54,67 ---- CMD_RUN = 101 CMD_LIST_THREADS = 102 ! CMD_THREAD_CREATE = 103 ! CMD_THREAD_KILL = 104 ! CMD_THREAD_SUSPEND = 105 ! CMD_THREAD_RUN = 106 ! CMD_STEP_INTO = 107 ! CMD_STEP_OVER = 108 ! CMD_STEP_RETURN = 109 ! CMD_VERSION = 501 ! CMD_RETURN = 502 ! CMD_ERROR = 901 Debugger = None *************** *** 68,79 **** def run(self): buffer = "" ! while(True): ! buffer += self.sock.recv(1024) ! while (buffer.find('\n') != -1): ! [command, buffer] = buffer.split('\n', 1) ! log(2, "received command " + command) ! args = command.split('\t', 2) ! PyDB.instance.processNetCommand(int(args[0]), int(args[1]), args[2]) class WriterThread(threading.Thread): --- 91,111 ---- def run(self): + sys.settrace(None) # no debugging on this thread buffer = "" ! try: ! while(True): ! # print >>sys.stderr, "waiting for input" ! buffer += self.sock.recv(1024) ! # print >>sys.stderr, "received input" ! while (buffer.find('\n') != -1): ! [command, buffer] = buffer.split('\n', 1) ! log(2, "received command " + command) ! args = command.split('\t', 2) ! print "the args are", args[0], " 2 ", args[1], " 3 ", args[2] ! PyDB.instance.processNetCommand(int(args[0]), int(args[1]), args[2]) ! # print >>sys.stderr, "processed input" ! except: ! print >>sys.stderr, "Exception in reader thread" ! raise class WriterThread(threading.Thread): *************** *** 92,100 **** def run(self): """ just loop and write responses """ ! while(True): ! cmd = self.cmdQueue.get(1) ! log(2, "sending cmd " + cmd.getOutgoing()) ! self.sock.sendall(cmd.getOutgoing()) ! class NetCommand: """ Commands received/sent over the network. --- 124,137 ---- def run(self): """ just loop and write responses """ ! sys.settrace(None) # no debugging on this thread ! try: ! while(True): ! cmd = self.cmdQueue.get(1) ! log(2, "sending cmd " + cmd.getOutgoing()) ! self.sock.sendall(cmd.getOutgoing()) ! except: ! print >>sys.stderr, "Exception in writer thread" ! raise ! class NetCommand: """ Commands received/sent over the network. *************** *** 111,115 **** self.id = id if (seq == 0): seq = self.getNextSeq() - if text: text.replace("\n","\\n") # make sure we have no carriage returns self.seq = seq self.text = text --- 148,151 ---- *************** *** 126,130 **** def makeMessage(self, cmd, seq, payload): ! return str(cmd) + '\t' + str(seq) + '\t' + str(payload)+ "\n" class NetCommandFactory: --- 162,167 ---- def makeMessage(self, cmd, seq, payload): ! encoded = urllib.quote(str(payload), '/<>_=" ') ! return str(cmd) + '\t' + str(seq) + '\t' + encoded + "\n" class NetCommandFactory: *************** *** 135,145 **** def threadToXML(self, thread): """ thread information as XML """ ! cmdText = '<thread name="' + thread.getName() + '"' cmdText += ' id="' + str(id(thread)) + '" />' return cmdText def makeErrorMessage(self, seq, text): - if (seq == 0): - seq = getNextSeq() cmd = NetCommand(CMD_ERROR, seq, text) return cmd; --- 172,180 ---- def threadToXML(self, thread): """ thread information as XML """ ! cmdText = '<thread name="' + urllib.quote(thread.getName()) + '"' cmdText += ' id="' + str(id(thread)) + '" />' return cmdText def makeErrorMessage(self, seq, text): cmd = NetCommand(CMD_ERROR, seq, text) return cmd; *************** *** 147,151 **** def makeThreadCreatedMessage(self,thread): cmdText = "<xml>" + self.threadToXML(thread) + "</xml>" ! return NetCommand(CMD_THREAD_CREATED, 0, cmdText) def makeListThreadsMessage(self, seq): --- 182,186 ---- def makeThreadCreatedMessage(self,thread): cmdText = "<xml>" + self.threadToXML(thread) + "</xml>" ! return NetCommand(CMD_THREAD_CREATE, 0, cmdText) def makeListThreadsMessage(self, seq): *************** *** 159,163 **** return NetCommand(CMD_RETURN, seq, cmdText) except: ! return self.makeErrorMessage(self, seq, sys.exc_info()[0]) def makeVersionMessage(self, seq): --- 194,198 ---- return NetCommand(CMD_RETURN, seq, cmdText) except: ! return self.makeErrorMessage(seq, sys.exc_info()[0]) def makeVersionMessage(self, seq): *************** *** 165,169 **** return NetCommand(CMD_VERSION, seq, VERSION_STRING) except: ! return self.makeErrorMessage(self, seq, sys.exc_info()[0]) class PyDB: --- 200,285 ---- return NetCommand(CMD_VERSION, seq, VERSION_STRING) except: ! return self.makeErrorMessage(seq, sys.exc_info()[0]) ! ! def makeThreadKilledMessage(self, id): ! try: ! return NetCommand(CMD_THREAD_KILL, 0, str(id)) ! except: ! return self.makeErrorMessage(0, sys.exc_info()[0]) ! ! def makeThreadSuspendMessage(self, thread_id, frame, stop_reason): ! ! """ <xml> ! <thread id="id"/> ! <frame id="id" name="functionName " file="file" line="line"> ! """ ! try: ! cmdText = "<xml>" ! cmdText += '<thread id="' + str(thread_id) + '" ' + 'stop_reason="' + str(stop_reason) + '"/>' ! curFrame = frame ! while (curFrame): ! # print cmdText ! myId = str(id(curFrame)) ! # print "id is ", myId ! myName = curFrame.f_code.co_name ! # print "name is ", myName ! myFile = inspect.getsourcefile(curFrame) or inspect.getfile(frame) ! # print "file is ", myFile ! myLine = str(curFrame.f_lineno) ! # print "line is ", myLine ! cmdText += '<frame id="' + myId +'" name="' + myName + '" ' ! cmdText += 'file="' + myFile + '" line="' + myLine + '"/>"' ! curFrame = curFrame.f_back ! cmdText += "</xml>" ! return NetCommand(CMD_THREAD_SUSPEND, 0, cmdText) ! except: ! return self.makeErrorMessage(0, str(sys.exc_info()[0])) ! ! def makeThreadRunMessage(self, id, reason): ! try: ! return NetCommand(CMD_THREAD_RUN, 0, str(id) + "\t" + str(reason)) ! except: ! return self.makeErrorMessage(0, sys.exc_info()[0]) ! ! INTERNAL_TERMINATE_THREAD = 1 ! INTERNAL_SUSPEND_THREAD = 2 ! ! class InternalThreadCommand: ! """ internal commands are generated/executed by the debugger. ! ! The reason for their existence is that some commands have to be executed ! on specific threads. These are the InternalThreadCommands that get ! get posted to PyDB.cmdQueue. ! """ ! def __init__(self, id, payload): ! self.id = id ! ! def doIt(self, dbg): ! print "you have to override doIt" ! ! class InternalTerminateThread: ! def __init__(self, thread_id): ! self.thread_id = thread_id ! ! def doIt(self, dbg): ! print "killing " + str(self.thread_id) ! cmd = dbg.cmdFactory.makeThreadKilledMessage(self.thread_id) ! dbg.writer.addCommand(cmd) ! time.sleep(0.1) ! sys.exit() ! ! def findThreadById(thread_id): ! try: ! int_id = int(thread_id) ! print >>sys.stderr, "enumerating" ! threads = threading.enumerate() ! print >>sys.stderr, "done enumerating" ! for i in threads: ! if int_id == id(i): return i ! print >>sys.stderr, "could not find thread" ! except: ! print >>sys.stderr, "unexpected exceiton if findThreadById" ! return None ! class PyDB: *************** *** 182,185 **** --- 298,303 ---- instance = None + STATE_RUN = 1 + STATE_SUSPEND = 2 # thread states def __init__(self): *************** *** 189,193 **** self.quitting = None self.cmdFactory = NetCommandFactory() ! self.cmdQueue = {} def initializeNetwork(self, sock): --- 307,311 ---- self.quitting = None self.cmdFactory = NetCommandFactory() ! self.cmdQueue = {} # the hash of Queues. Key is thread id, value is thread def initializeNetwork(self, sock): *************** *** 197,200 **** --- 315,320 ---- self.writer = WriterThread(sock) self.writer.start() + time.sleep(0.1) # give threads time to start + def startServer(self, port): *************** *** 226,288 **** else: self.startServer(port) - - def processNetCommand(self, id, seq, text): - cmd = None - if (id == CMD_VERSION): # response is version number - cmd = self.cmdFactory.makeVersionMessage(seq) - elif (id == CMD_LIST_THREADS): # response is a list of threads - cmd = self.cmdFactory.makeListThreadsMessage(seq) - else: - cmd = self.cmdFactory.makeErrorCommand(seq, "unexpected command " + str(id)) - - if cmd: - self.writer.addCommand(cmd) ! def getQueueForThread(self, thread): """ returns intenal command queue for a given thread. if new queue is created, notify the RDB about it """ ! myID = id(thread) queue = None try: ! return self.cmdQueue[myID] except KeyError: ! self.cmdQueue[myID] = Queue() ! cmd = self.cmdFactory.makeThreadCreatedMessage(thread) ! print "found a new thread" self.writer.addCommand(cmd) ! return self.cmdQueue[myID] ! def processQueuedEvents(self, frame, event, arg): ! queue = self.getQueueForThread(threading.currentThread()) ! def trace_dispatch(self, frame, event, arg): ! self.processQueuedEvents(frame, event, arg) if self.quitting: ! return # None ! if event == 'line': ! return self.dispatch_line(frame) ! if event == 'call': ! return self.dispatch_call(frame, arg) ! if event == 'return': ! return self.dispatch_return(frame, arg) ! if event == 'exception': ! return self.dispatch_exception(frame, arg) ! print 'bdb.Bdb.dispatch: unknown debugging event:', `event` ! return self.trace_dispatch def dispatch_line(self, frame): ! print "L " + str(frame) return self.trace_dispatch def dispatch_call(self, frame, arg): ! print "C " + str(frame) + " " + str(arg) return self.trace_dispatch def dispatch_return(self, frame, arg): ! print "R " + str(frame) + " " + str(arg) return self.trace_dispatch def dispatch_exception(self, frame, arg): ! print "E " + str(frame) + " " + str(arg) return self.trace_dispatch --- 346,547 ---- else: self.startServer(port) ! def getInternalQueue(self, thread_id): """ returns intenal command queue for a given thread. if new queue is created, notify the RDB about it """ ! thread_id = int(thread_id) queue = None try: ! return self.cmdQueue[thread_id] except KeyError: ! self.cmdQueue[thread_id] = Queue() ! all_threads = threading.enumerate() ! cmd = None ! for t in all_threads: ! if id(t) == thread_id: ! cmd = self.cmdFactory.makeThreadCreatedMessage(t) ! if (cmd): ! log(2, "found a new thread " + str(thread_id)) ! self.writer.addCommand(cmd) ! else: ! log(0, "could not find thread by id to register") ! return self.cmdQueue[thread_id] ! ! def postInternalCommand(self, int_cmd, thread_id): ! """ if thread_id is *, post to all """ ! print "Posting internal command for ", str(thread_id) ! if (thread_id == "*"): ! for k in self.cmdQueue.keys(): self.cmdQueue[k].put(int_cmd) ! else: ! queue = self.getInternalQueue(thread_id) ! queue.put(int_cmd) ! ! def processInternalCommands(self): ! queue = self.getInternalQueue(id(threading.currentThread())) ! try: ! while (True): ! int_cmd = queue.get(False) ! log(2, "processign internal command " + str(int_cmd)) ! int_cmd.doIt(self) ! except Empty: ! pass # this is how we exit ! ! def processNetCommand(self, id, seq, text): ! try: ! cmd = None ! print >>sys.stderr, "processing command", id ! if (id == CMD_VERSION): # response is version number ! cmd = self.cmdFactory.makeVersionMessage(seq) ! elif (id == CMD_LIST_THREADS): # response is a list of threads ! cmd = self.cmdFactory.makeListThreadsMessage(seq) ! elif (id == CMD_THREAD_KILL): ! int_cmd = InternalTerminateThread(text) ! self.postInternalCommand(int_cmd, text) ! elif (id == CMD_THREAD_SUSPEND): ! print >>sys.stderr, "About to suspend ", text ! t = findThreadById(text) ! if t: self.setSuspend(t, CMD_THREAD_SUSPEND) ! else: print >>sys.stderr, "Could not find thread ", t ! elif (id == CMD_THREAD_RUN): ! t = findThreadById(text) ! if t: t.pydev_state = PyDB.STATE_RUN ! elif (id == CMD_STEP_INTO or id == CMD_STEP_OVER or id == CMD_STEP_RETURN): ! t = findThreadById(text) ! if t: ! t.pydev_state = PyDB.STATE_RUN ! t.pydev_step_cmd = id ! else: ! cmd = self.cmdFactory.makeErrorMessage(seq, "unexpected command " + str(id)) ! print >>sys.stderr, "processed command", id ! if cmd: ! self.writer.addCommand(cmd) ! except: ! print >>sys.stderr, "Unexpected exception in processNetCommand" ! print >>sys.stderr, sys.exc_info()[0] ! ! def processThreadNotAlive(self, thread): ! """ if thread is not alive, cancel trace_dispatch processing """ ! wasNotified = False ! try: ! wasNotified = thread.pydev_notify_kill ! except AttributeError: ! thread.pydev_notify_kill = False ! if not wasNotified: ! log(0, "leaving stopped thread " + str(id(thread))) ! cmd = self.cmdFactory.makeThreadKilledMessage(id(thread)) self.writer.addCommand(cmd) ! thread.pydev_notify_kill = True ! ! def setSuspend(self, thread, stop_reason): ! thread.pydev_state = PyDB.STATE_SUSPEND ! thread.stop_reason = stop_reason ! ! def doWaitSuspend(self, thread): ! """ busy waits until the thread state changes to RUN ! it expects thread's state as attributes of the thread. ! Upon running, processes any outstanding Stepping commands. ! """ ! # print >>sys.stderr, "thread suspended", thread.getName() ! ! cmd = self.cmdFactory.makeThreadSuspendMessage(id(thread), thread.pydev_frame, thread.stop_reason) ! self.writer.addCommand(cmd) ! while (thread.pydev_state == PyDB.STATE_SUSPEND): ! # print "waiting on thread" ! self.processInternalCommands() ! time.sleep(0.1) ! try: ! """ process any stepping instructions """ ! if (thread.pydev_step_cmd == CMD_STEP_INTO): ! thread.pydev_step_return = None ! pass ! elif (thread.pydev_step_cmd == CMD_STEP_OVER): ! thread.pydev_step_stop = thread.pydev_frame ! elif (thread.pydev_step_cmd == CMD_STEP_RETURN): ! thread.pydev_step_stop = thread.pydev_frame.f_back ! except AttributeError: ! thread.pydev_step_cmd = None # so we do ont thro ! pass ! del thread.pydev_frame ! del thread.pydev_event ! del thread.pydev_arg ! ! print >>sys.stderr, "thread resumed", thread.getName() ! cmd = self.cmdFactory.makeThreadRunMessage(id(thread), thread.pydev_step_cmd) ! self.writer.addCommand(cmd) ! ! def trace_dispatch(self, frame, event, arg): ! """ the main callback from the debugger """ ! self.processInternalCommands() ! t = threading.currentThread() ! """ if thread is not alive, cancel trace_dispatch processing """ ! if not t.isAlive(): ! self.processThreadNotAlive(t) ! return None # suspend tracing ! wasSuspended = False ! try: ! """ if thread has a suspend flag, we suspend with a busy wait """ ! if (t.pydev_state == PyDB.STATE_SUSPEND): ! t.pydev_frame = frame ! t.pydev_event = event ! t.pydev_arg = arg ! wasSuspended = True ! self.doWaitSuspend(t) ! return self.trace_dispatch ! except AttributeError: ! t.pydev_state = PyDB.STATE_RUN # assign it to avoid future exceptions ! except: ! print sys.stderr, "Exception in trace_dispatch" ! print sys.exc_info()[0] ! raise ! ! if ( not wasSuspended and event == 'line'): ! """ step handling """ ! try: ! if (t.pydev_step_cmd == CMD_STEP_INTO): ! self.setSuspend(t, CMD_STEP_INTO) ! self.doWaitSuspend(t) ! elif (t.pydev_step_cmd == CMD_STEP_OVER or t.pydev_step_cmd == CMD_STEP_RETURN): ! if (t.pydev_step_stop == frame): ! self.setSuspend(t, t.pydev_step_cmd) ! self.doWaitSuspend(t) ! except: ! t.pydev_step_cmd = None ! ! retVal = None ! # print "t3 ", str(id(t)) if self.quitting: ! pass ! elif event == 'line': ! retVal = self.dispatch_line(frame) ! elif event == 'call': ! retVal = self.dispatch_call(frame, arg) ! elif event == 'return': ! retVal = self.dispatch_return(frame, arg) ! elif event == 'exception': ! retVal = self.dispatch_exception(frame, arg) ! else: ! retVal = self.trace_dispatch ! print 'bdb.Bdb.dispatch: unknown debugging event:', `event` ! # print "b", str(id(t)) ! return retVal def dispatch_line(self, frame): ! # myFile = inspect.getsourcefile(frame) or inspect.getfile(frame) ! # myLine = str(frame.f_lineno) ! # print ' File "'+ myFile + '", line '+ myLine return self.trace_dispatch def dispatch_call(self, frame, arg): ! # print "C " + str(frame) + " " + str(arg) return self.trace_dispatch def dispatch_return(self, frame, arg): ! # print "R " + str(frame) + " " + str(arg) return self.trace_dispatch def dispatch_exception(self, frame, arg): ! # print "E " + str(frame) + " " + str(arg) return self.trace_dispatch *************** *** 297,307 **** cmd = cmd+'\n' ! threading.settrace(self.trace_dispatch) # for all threads sys.settrace(self.trace_dispatch) # for this thread try: try: exec cmd in globals, locals except: ! print sys.stderr, "Debugger exiting with exception" raise finally: --- 556,574 ---- cmd = cmd+'\n' ! # for completness, we'll register the pydevd.reader & pydevd.writer threads ! net = NetCommand(str(CMD_THREAD_CREATE), 0, '<xml><thread name="pydevd.reader" id="-1"/></xml>') ! self.writer.addCommand(net) ! net = NetCommand(str(CMD_THREAD_CREATE), 0, '<xml><thread name="pydevd.writer" id="-1"/></xml>') ! self.writer.addCommand(net) ! ! threading.settrace(self.trace_dispatch) # for all future threads sys.settrace(self.trace_dispatch) # for this thread try: try: + print "exec start" exec cmd in globals, locals + print >>sys.stderr, "Debugger done" except: ! print >>sys.stderr, "Debugger exiting with exception" raise finally: |
Update of /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/model In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10447/src/org/python/pydev/debug/model Modified Files: PyThread.java VersionCommand.java PyDebugTarget.java RemoteDebugger.java Added Files: ThreadListCommand.java XMLUtils.java StepCommand.java ThreadSuspendCommand.java AbstractDebuggerCommand.java ThreadRunCommand.java PySourceLocator.java ThreadKillCommand.java PyStackFrame.java Removed Files: ModelUtils.java ListThreadsCommand.java RemoteDebuggerCommand.java Log Message: Stepping works. Index: RemoteDebugger.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/model/RemoteDebugger.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** RemoteDebugger.java 22 Apr 2004 10:56:18 -0000 1.2 --- RemoteDebugger.java 27 Apr 2004 19:12:59 -0000 1.3 *************** *** 84,88 **** protected class Writer implements Runnable { ArrayList cmdQueue; // a list of RemoteDebuggerCommands ! PrintWriter out; boolean done; --- 84,88 ---- protected class Writer implements Runnable { ArrayList cmdQueue; // a list of RemoteDebuggerCommands ! OutputStreamWriter out; boolean done; *************** *** 92,96 **** OutputStream sout; sout = s.getOutputStream(); ! out = new PrintWriter(new OutputStreamWriter(sout)); } --- 92,96 ---- OutputStream sout; sout = s.getOutputStream(); ! out = new OutputStreamWriter(sout); } *************** *** 98,102 **** * Add command for processing */ ! public void postCommand(RemoteDebuggerCommand cmd) { synchronized(cmdQueue) { cmdQueue.add(cmd); --- 98,102 ---- * Add command for processing */ ! public void postCommand(AbstractDebuggerCommand cmd) { synchronized(cmdQueue) { cmdQueue.add(cmd); *************** *** 113,133 **** public void run() { while (!done) { ! RemoteDebuggerCommand cmd = null; synchronized (cmdQueue) { if (cmdQueue.size() > 0) ! cmd = (RemoteDebuggerCommand) cmdQueue.remove(0); ! } ! if (cmd != null) { ! cmd.aboutToSend(); ! out.write(cmd.getOutgoing()); ! out.write("\n"); ! out.flush(); } try { Thread.sleep(100); } catch (InterruptedException e) { ! // TODO Auto-generated catch block ! e.printStackTrace(); ! } } } --- 113,134 ---- public void run() { while (!done) { ! AbstractDebuggerCommand cmd = null; synchronized (cmdQueue) { if (cmdQueue.size() > 0) ! cmd = (AbstractDebuggerCommand) cmdQueue.remove(0); } try { + if (cmd != null) { + cmd.aboutToSend(); + out.write(cmd.getOutgoing()); + out.write("\n"); + out.flush(); + } Thread.sleep(100); } catch (InterruptedException e) { ! done = true; ! } catch (IOException e1) { ! done = true; ! } } } *************** *** 153,160 **** } ! public void addToResponseQueue(RemoteDebuggerCommand cmd) { responseQueue.put(new Integer(cmd.getSequence()), cmd); Object o = responseQueue.remove(new Integer(cmd.getSequence())); - System.out.println(o.toString()); responseQueue.put(new Integer(cmd.getSequence()), cmd); } --- 154,160 ---- } ! public void addToResponseQueue(AbstractDebuggerCommand cmd) { responseQueue.put(new Integer(cmd.getSequence()), cmd); Object o = responseQueue.remove(new Integer(cmd.getSequence())); responseQueue.put(new Integer(cmd.getSequence()), cmd); } *************** *** 170,179 **** cmdCode = Integer.parseInt(cmdParsed[0]); seqCode = Integer.parseInt(cmdParsed[1]); ! payload = cmdParsed[2]; // is there a response waiting ! RemoteDebuggerCommand cmd = (RemoteDebuggerCommand)responseQueue.remove(new Integer(seqCode)); if (cmd == null) if (target != null) ! target.processCommand(cmdParsed[0], cmdParsed[1], cmdParsed[2]); else PydevDebugPlugin.log(IStatus.ERROR, "internal error, command received no target", null); --- 170,179 ---- cmdCode = Integer.parseInt(cmdParsed[0]); seqCode = Integer.parseInt(cmdParsed[1]); ! payload = URLDecoder.decode(cmdParsed[2]); // is there a response waiting ! AbstractDebuggerCommand cmd = (AbstractDebuggerCommand)responseQueue.remove(new Integer(seqCode)); if (cmd == null) if (target != null) ! target.processCommand(cmdParsed[0], cmdParsed[1], payload); else PydevDebugPlugin.log(IStatus.ERROR, "internal error, command received no target", null); *************** *** 195,204 **** Thread.sleep(100); } catch (IOException e) { ! PydevDebugPlugin.log(IStatus.WARNING, "Unexpected termination of remote dbg input stream", e); } catch (InterruptedException e1) { e1.printStackTrace(); } ! if (socket.isConnected() == false) ! System.err.println("no longer connected"); } } --- 195,208 ---- Thread.sleep(100); } catch (IOException e) { ! done = true; } catch (InterruptedException e1) { e1.printStackTrace(); } ! if ((socket == null) || !socket.isConnected()) { ! if (target != null) { ! target.debuggerDisconnected(); ! } ! done = true; ! } } } *************** *** 212,215 **** --- 216,230 ---- this.target = target; } + + public void startTransmission() throws IOException { + this.reader = new Reader(socket); + this.writer = new Writer(socket); + Thread t = new Thread(reader, "pydevd.reader"); + t.start(); + t = new Thread(writer, "pydevd.writer"); + t.start(); + writer.postCommand(new VersionCommand(this)); + + } /** *************** *** 269,304 **** public void connected(Socket socket) throws IOException { this.socket = socket; - this.reader = new Reader(socket); - this.writer = new Writer(socket); - Thread t = new Thread(reader, "pydevd.reader"); - t.start(); - t = new Thread(writer, "pydevd.writer"); - t.start(); - writer.postCommand(new VersionCommand(this)); } /** * Dispose must be called to clean up. */ public void dispose() { ! if (connector != null) connector.stopListening(); ! if (reader != null) ! reader.done(); ! if (writer != null) writer.done(); ! if (socket != null && socket.isConnected()) ! try { ! socket.close(); ! } catch (IOException e) { ! // other end might have closed first ! } target = null; } ! public void addToResponseQueue(RemoteDebuggerCommand cmd) { reader.addToResponseQueue(cmd); } ! public void postCommand(RemoteDebuggerCommand cmd) { writer.postCommand(cmd); } --- 284,332 ---- public void connected(Socket socket) throws IOException { this.socket = socket; } + + public void disconnect() { + try { + if (socket != null) { + socket.shutdownInput(); // trying to make my pydevd notice that the socket is gone + socket.shutdownOutput(); + socket.close(); + } + } catch (IOException e) { + e.printStackTrace(); + // it is going away + } + socket = null; + if (target != null) + target.debuggerDisconnected(); + } + /** * Dispose must be called to clean up. + * Because we call this from PyDebugTarget.terminate, we can be called multiple times + * But, once dispose() is called, no other calls will be made. */ public void dispose() { ! if (connector != null) { connector.stopListening(); ! connector = null; ! } ! if (writer != null) { writer.done(); ! writer = null; ! } ! if (reader != null) { ! reader.done(); ! reader = null; ! } ! disconnect(); target = null; } ! public void addToResponseQueue(AbstractDebuggerCommand cmd) { reader.addToResponseQueue(cmd); } ! public void postCommand(AbstractDebuggerCommand cmd) { writer.postCommand(cmd); } --- NEW FILE: PyStackFrame.java --- /* * Author: atotic * Created on Apr 22, 2004 * License: Common Public License v1.0 */ package org.python.pydev.debug.model; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IRegisterGroup; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; import org.eclipse.debug.core.model.IVariable; import org.eclipse.ui.views.tasklist.ITaskListResourceAdapter; /** * Represents a stack entry. * * Needs to integrate with the source locator */ public class PyStackFrame implements IStackFrame { private String name; private PyThread thread; private String id; private IPath path; private int line; public PyStackFrame(String id, String name, IPath file, int line) { this.id = id; this.name = name; this.path = file; this.line = line; } public IPath getPath() { return path; } public IThread getThread() { return thread; } public void setThread(PyThread thread) { this.thread = thread; } public IVariable[] getVariables() throws DebugException { // TODO Auto-generated method stub return null; } public boolean hasVariables() throws DebugException { // TODO Auto-generated method stub return false; } public int getLineNumber() throws DebugException { return line; } public int getCharStart() throws DebugException { // TODO Auto-generated method stub return 0; } public int getCharEnd() throws DebugException { // TODO Auto-generated method stub return 0; } public String getName() throws DebugException { return name + " [" + path.lastSegment() + ":" + Integer.toString(line) + "]"; } public IRegisterGroup[] getRegisterGroups() throws DebugException { return null; } public boolean hasRegisterGroups() throws DebugException { return false; } public String getModelIdentifier() { return thread.getModelIdentifier(); } public IDebugTarget getDebugTarget() { return thread.getDebugTarget(); } public ILaunch getLaunch() { return thread.getLaunch(); } public boolean canStepInto() { return thread.canStepInto(); } public boolean canStepOver() { return thread.canStepOver(); } public boolean canStepReturn() { return thread.canStepReturn(); } public boolean isStepping() { return thread.isStepping(); } public void stepInto() throws DebugException { thread.stepInto(); } public void stepOver() throws DebugException { thread.stepOver(); } public void stepReturn() throws DebugException { thread.stepReturn(); } public boolean canResume() { return thread.canResume(); } public boolean canSuspend() { return thread.canSuspend(); } public boolean isSuspended() { return thread.isSuspended(); } public void resume() throws DebugException { thread.resume(); } public void suspend() throws DebugException { thread.suspend(); } public boolean canTerminate() { return thread.canTerminate(); } public boolean isTerminated() { return thread.isTerminated(); } public void terminate() throws DebugException { thread.terminate(); } public Object getAdapter(Class adapter) { if (adapter.equals(ILaunch.class) || adapter.equals(IResource.class)) return thread.getAdapter(adapter); else if (adapter.equals(ITaskListResourceAdapter.class)) return null; // ongoing, I do not fully understand all the interfaces they'd like me to support System.err.println("PyStackFrame Need adapter " + adapter.toString()); return null; } } --- ListThreadsCommand.java DELETED --- --- NEW FILE: ThreadRunCommand.java --- /* * Author: atotic * Created on Apr 22, 2004 * License: Common Public License v1.0 */ package org.python.pydev.debug.model; /** * Run thread network command */ public class ThreadRunCommand extends AbstractDebuggerCommand { String thread; public ThreadRunCommand(RemoteDebugger debugger, String thread) { super(debugger); this.thread = thread; } public String getOutgoing() { return makeCommand(Integer.toString(CMD_THREAD_RUN), sequence, thread); } } --- NEW FILE: ThreadListCommand.java --- /* * Author: atotic * Created on Apr 21, 2004 * License: Common Public License v1.0 */ package org.python.pydev.debug.model; import org.eclipse.core.runtime.IStatus; import org.eclipse.debug.core.model.IThread; import org.python.pydev.debug.core.PydevDebugPlugin; /** * ListThreads command. * * See protocol for more info */ public class ThreadListCommand extends AbstractDebuggerCommand { boolean done; PyDebugTarget target; IThread[] threads; public ThreadListCommand(RemoteDebugger debugger, PyDebugTarget target) { super(debugger); this.target = target; done = false; } public void waitUntilDone(int timeout) throws InterruptedException { while (!done && timeout > 0) { timeout -= 100; Thread.sleep(100); } if (timeout < 0) throw new InterruptedException(); } public IThread[] getThreads() { return threads; } public String getOutgoing() { return makeCommand(Integer.toString(CMD_LIST_THREADS), sequence, ""); } public boolean needResponse() { return true; } /** * The response is a list of threads */ public void processResponse(int cmdCode, String payload) { if (cmdCode != 102) { PydevDebugPlugin.log(IStatus.ERROR, "Unexpected response to LIST THREADS" + payload, null); return; } threads = XMLUtils.ThreadsFromXML(target, payload); done = true; } public void processErrorResponse(int cmdCode, String payload) { PydevDebugPlugin.log(IStatus.ERROR, "LIST THREADS got an error " + payload, null); } } --- NEW FILE: ThreadSuspendCommand.java --- /* * Author: atotic * Created on Apr 22, 2004 * License: Common Public License v1.0 */ package org.python.pydev.debug.model; /** * Suspend thread network command. * * See protocol docs for more info. */ public class ThreadSuspendCommand extends AbstractDebuggerCommand { String thread; public ThreadSuspendCommand(RemoteDebugger debugger, String thread) { super(debugger); this.thread = thread; } public String getOutgoing() { return makeCommand(Integer.toString(CMD_THREAD_SUSPEND), sequence, thread); } } --- ModelUtils.java DELETED --- Index: PyThread.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/model/PyThread.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyThread.java 22 Apr 2004 10:56:17 -0000 1.1 --- PyThread.java 27 Apr 2004 19:12:59 -0000 1.2 *************** *** 24,40 **** private String name; private String id; public PyThread(PyDebugTarget target, String name, String id) { this.target = target; this.name = name; ! this.id = id; } public String getName() throws DebugException { return name; } public int getPriority() throws DebugException { - // TODO maybe daemon status of the threads? return 0; } --- 24,60 ---- private String name; private String id; + boolean isPydevThread; // true if this is a debugger thread, that can't be killed/suspended + + boolean isSuspended = false; + boolean isStepping = false; + IStackFrame[] stack; public PyThread(PyDebugTarget target, String name, String id) { this.target = target; this.name = name; ! this.id = id; ! isPydevThread = id.equals("-1"); // use a special id for pydev threads } + /** + * If a thread is entering a suspended state, pass in the stack + */ + public void setSuspended(boolean state, IStackFrame[] stack) { + isSuspended = state; + this.stack = stack; + if (stack != null) + for (int i=0; i<stack.length; i++) + ((PyStackFrame)stack[i]).setThread(this); + } + public String getName() throws DebugException { return name; } + + public String getId() { + return id; + } public int getPriority() throws DebugException { return 0; } *************** *** 53,57 **** public boolean canTerminate() { ! return true; } --- 73,77 ---- public boolean canTerminate() { ! return !isPydevThread; } *************** *** 61,139 **** public void terminate() throws DebugException { ! System.out.print("Terminating thread"); } public boolean canResume() { ! // TODO Auto-generated method stub ! return false; } public boolean canSuspend() { ! // TODO Auto-generated method stub ! return true; } public boolean isSuspended() { ! // TODO Auto-generated method stub ! return false; } public void resume() throws DebugException { ! // TODO Auto-generated method stub } public void suspend() throws DebugException { ! // TODO Auto-generated method stub ! } public boolean canStepInto() { ! // TODO Auto-generated method stub ! return false; } public boolean canStepOver() { ! // TODO Auto-generated method stub ! return false; } public boolean canStepReturn() { ! // TODO Auto-generated method stub ! return false; } public boolean isStepping() { ! // TODO Auto-generated method stub ! return false; } public void stepInto() throws DebugException { ! // TODO Auto-generated method stub } public void stepOver() throws DebugException { ! // TODO Auto-generated method stub ! } public void stepReturn() throws DebugException { ! // TODO Auto-generated method stub ! } public IStackFrame[] getStackFrames() throws DebugException { ! // TODO Auto-generated method stub ! return null; } public boolean hasStackFrames() throws DebugException { ! // TODO Auto-generated method stub ! return false; } public IStackFrame getTopStackFrame() throws DebugException { ! // TODO Auto-generated method stub ! return null; } public IBreakpoint[] getBreakpoints() { // TODO Auto-generated method stub --- 81,169 ---- public void terminate() throws DebugException { ! if (!isPydevThread) { ! RemoteDebugger d = target.getDebugger(); ! d.postCommand(new ThreadKillCommand(d, id)); ! } } public boolean canResume() { ! return !isPydevThread && isSuspended; } public boolean canSuspend() { ! return !isPydevThread && !isSuspended; } public boolean isSuspended() { ! return isSuspended; } public void resume() throws DebugException { ! if (!isPydevThread) { ! isStepping = false; ! RemoteDebugger d = target.getDebugger(); ! d.postCommand(new ThreadRunCommand(d, id)); ! } } public void suspend() throws DebugException { ! if (!isPydevThread) { ! RemoteDebugger d = target.getDebugger(); ! d.postCommand(new ThreadSuspendCommand(d, id)); ! } } public boolean canStepInto() { ! return !isPydevThread && isSuspended; } public boolean canStepOver() { ! return !isPydevThread && isSuspended; } public boolean canStepReturn() { ! return !isPydevThread && isSuspended; } public boolean isStepping() { ! return isStepping; } public void stepInto() throws DebugException { ! if (!isPydevThread) { ! isStepping = true; ! RemoteDebugger d = target.getDebugger(); ! d.postCommand(new StepCommand(d, AbstractDebuggerCommand.CMD_STEP_INTO, id)); ! } } public void stepOver() throws DebugException { ! if (!isPydevThread) { ! isStepping = true; ! RemoteDebugger d = target.getDebugger(); ! d.postCommand(new StepCommand(d, AbstractDebuggerCommand.CMD_STEP_OVER, id)); ! } } public void stepReturn() throws DebugException { ! if (!isPydevThread) { ! isStepping = true; ! RemoteDebugger d = target.getDebugger(); ! d.postCommand(new StepCommand(d, AbstractDebuggerCommand.CMD_STEP_RETURN, id)); ! } } public IStackFrame[] getStackFrames() throws DebugException { ! return stack; } public boolean hasStackFrames() throws DebugException { ! return (stack != null && stack.length > 0); } public IStackFrame getTopStackFrame() throws DebugException { ! return stack == null ? stack[0] : null; } + public IBreakpoint[] getBreakpoints() { // TODO Auto-generated method stub --- NEW FILE: StepCommand.java --- /* * Author: atotic * Created on Apr 27, 2004 * License: Common Public License v1.0 */ package org.python.pydev.debug.model; /** * Debugger step command. */ public class StepCommand extends AbstractDebuggerCommand { int command_id; String thread_id; /** * * @param command_id CMD_STEP_INTO CMD_STEP_OVER CMD_STEP_RETURN */ public StepCommand(RemoteDebugger debugger, int command_id, String thread_id) { super(debugger); this.command_id = command_id; this.thread_id = thread_id; } public String getOutgoing() { return makeCommand(Integer.toString(command_id), sequence, thread_id); } } Index: PyDebugTarget.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/model/PyDebugTarget.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyDebugTarget.java 22 Apr 2004 10:56:18 -0000 1.1 --- PyDebugTarget.java 27 Apr 2004 19:12:59 -0000 1.2 *************** *** 6,9 **** --- 6,12 ---- package org.python.pydev.debug.model; + import java.util.regex.Matcher; + import java.util.regex.Pattern; + import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarkerDelta; *************** *** 21,24 **** --- 24,28 ---- import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IProcess; + import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; import org.python.pydev.debug.core.PydevDebugPlugin; *************** *** 36,39 **** --- 40,44 ---- IPath file; IThread[] threads; + boolean disconnected = false; public PyDebugTarget(ILaunch launch, *************** *** 51,54 **** --- 56,68 ---- DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this); } + + public RemoteDebugger getDebugger() { + return debugger; + } + + public void debuggerDisconnected() { + disconnected = true; + fireEvent(new DebugEvent(this, DebugEvent.CHANGE)); + } public void launchRemoved(ILaunch launch) { *************** *** 93,97 **** public boolean canTerminate() { ! // We can always terminate, it makes no harm return true; } --- 107,111 ---- public boolean canTerminate() { ! // We can always terminate, it does no harm return true; } *************** *** 102,152 **** public void terminate() throws DebugException { process.terminate(); } public boolean canDisconnect() { ! // TODO NOW Auto-generated method stub ! return true; } public void disconnect() throws DebugException { ! // TODO Auto-generated method stub ! } public boolean isDisconnected() { ! // TODO NOW Auto-generated method stub ! return false; } public boolean canResume() { ! // TODO NOW Auto-generated method stub return false; } public boolean canSuspend() { ! // TODO NOW Auto-generated method stub ! return true; } public boolean isSuspended() { - // TODO Auto-generated method stub return false; } public void resume() throws DebugException { ! // TODO Auto-generated method stub ! } public void suspend() throws DebugException { ! // TODO Auto-generated method stub ! } public IThread[] getThreads() throws DebugException { if (threads == null) { ! ListThreadsCommand cmd = new ListThreadsCommand(debugger, this); debugger.postCommand(cmd); try { --- 116,170 ---- public void terminate() throws DebugException { + if (debugger != null) + debugger.disconnect(); process.terminate(); } public boolean canDisconnect() { ! return !disconnected; } public void disconnect() throws DebugException { ! if (debugger != null) { ! debugger.disconnect(); ! } } public boolean isDisconnected() { ! return disconnected; } public boolean canResume() { ! for (int i=0; i< threads.length; i++) ! if (threads[i].canResume()) ! return true; return false; } public boolean canSuspend() { ! for (int i=0; i< threads.length; i++) ! if (threads[i].canSuspend()) ! return true; ! return false; } public boolean isSuspended() { return false; } public void resume() throws DebugException { ! for (int i=0; i< threads.length; i++) ! threads[i].resume(); } public void suspend() throws DebugException { ! for (int i=0; i< threads.length; i++) ! threads[i].suspend(); } public IThread[] getThreads() throws DebugException { if (threads == null) { ! ThreadListCommand cmd = new ThreadListCommand(debugger, this); debugger.postCommand(cmd); try { *************** *** 184,188 **** public boolean supportsStorageRetrieval() { - // TODO Auto-generated method stub return false; } --- 202,205 ---- *************** *** 190,199 **** public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException { - // TODO Auto-generated method stub return null; } public Object getAdapter(Class adapter) { ! // TODO Auto-generated method stub if (adapter.equals(ILaunch.class)) return launch; --- 207,215 ---- public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException { return null; } public Object getAdapter(Class adapter) { ! // Not really sure what to do here, but I am trying if (adapter.equals(ILaunch.class)) return launch; *************** *** 219,224 **** int cmdCode = Integer.parseInt(sCmdCode); int seqCode = Integer.parseInt(sSeqCode); ! if (cmdCode == RemoteDebuggerCommand.CMD_THREAD_CREATED) processThreadCreated(payload); else PydevDebugPlugin.log(IStatus.WARNING, "Unexpected debugger command" + sCmdCode, null); --- 235,246 ---- int cmdCode = Integer.parseInt(sCmdCode); int seqCode = Integer.parseInt(sSeqCode); ! if (cmdCode == AbstractDebuggerCommand.CMD_THREAD_CREATED) processThreadCreated(payload); + else if (cmdCode == AbstractDebuggerCommand.CMD_THREAD_KILL) + processThreadKilled(payload); + else if (cmdCode == AbstractDebuggerCommand.CMD_THREAD_SUSPEND) + processThreadSuspended(payload); + else if (cmdCode == AbstractDebuggerCommand.CMD_THREAD_RUN) + processThreadRun(payload); else PydevDebugPlugin.log(IStatus.WARNING, "Unexpected debugger command" + sCmdCode, null); *************** *** 232,237 **** } private void processThreadCreated(String payload) { ! IThread[] newThreads = ModelUtils.ThreadsFromXML(this, payload); if (threads == null) threads = newThreads; --- 254,272 ---- } + /** + * @return an existing thread with a given id (null if none) + */ + private IThread findThreadByID(String thread_id) throws DebugException { + for (int i = 0; i < threads.length; i++) + if (thread_id.equals(((PyThread)threads[i]).getId())) + return threads[i]; + return null; + } + + /** + * Add it to the list of threads + */ private void processThreadCreated(String payload) { ! IThread[] newThreads = XMLUtils.ThreadsFromXML(this, payload); if (threads == null) threads = newThreads; *************** *** 249,251 **** --- 284,372 ---- fireEvent(new DebugEvent(newThreads[i], DebugEvent.CREATE)); } + + // Remote this from our thread list + private void processThreadKilled(String thread_id) { + try { + IThread threadToDelete = findThreadByID(thread_id); + if (threadToDelete != null) { + int j = 0; + IThread[] newThreads = new IThread[threads.length - 1]; + for (int i=0; i < threads.length; i++) + if (threads[i] != threadToDelete) + newThreads[j++] = threads[i]; + threads = newThreads; + fireEvent(new DebugEvent(threadToDelete, DebugEvent.TERMINATE)); + } + } catch (DebugException e) { + PydevDebugPlugin.log(IStatus.ERROR, "Unexpected error thread kill", e); + } + } + + private void processThreadSuspended(String payload) { + try { + Object[] threadNstack = XMLUtils.XMLToStack(payload); + PyThread t = (PyThread)findThreadByID((String)threadNstack[0]); + int reason = DebugEvent.UNSPECIFIED; + String stopReason = (String) threadNstack[1]; + if (stopReason != null) { + int stopReason_i = Integer.parseInt(stopReason); + if (stopReason_i == AbstractDebuggerCommand.CMD_STEP_OVER || + stopReason_i == AbstractDebuggerCommand.CMD_STEP_INTO || + stopReason_i == AbstractDebuggerCommand.CMD_STEP_RETURN) + reason = DebugEvent.STEP_END; + else if (stopReason_i == AbstractDebuggerCommand.CMD_THREAD_SUSPEND) + reason = DebugEvent.CLIENT_REQUEST; + else { + PydevDebugPlugin.log(IStatus.ERROR, "Unexpected reason for suspension", null); + reason = DebugEvent.UNSPECIFIED; + } + } + if (t != null) { + t.setSuspended(true, (IStackFrame[])threadNstack[2]); + fireEvent(new DebugEvent(t, DebugEvent.SUSPEND, reason)); + } + } catch (DebugException e) { + PydevDebugPlugin.log(IStatus.ERROR, "Unexpected error thread suspended", e); + } + } + + static Pattern threadRunPattern = Pattern.compile("(\\d+)\\t(\\w*)"); + private void processThreadRun(String payload) { + try { + String threadID = ""; + int resumeReason = DebugEvent.UNSPECIFIED; + Matcher m = threadRunPattern.matcher(payload); + if (m.matches()) { + threadID = m.group(1); + try { + int raw_reason = Integer.parseInt(m.group(2)); + if (raw_reason == AbstractDebuggerCommand.CMD_STEP_OVER) + resumeReason = DebugEvent.STEP_OVER; + else if (raw_reason == AbstractDebuggerCommand.CMD_STEP_RETURN) + resumeReason = DebugEvent.STEP_RETURN; + else if (raw_reason == AbstractDebuggerCommand.CMD_STEP_INTO) + resumeReason = DebugEvent.STEP_INTO; + else if (raw_reason == AbstractDebuggerCommand.CMD_THREAD_RUN) + resumeReason = DebugEvent.CLIENT_REQUEST; + else { + PydevDebugPlugin.log(IStatus.ERROR, "Unexpected resume reason code", null); + resumeReason = DebugEvent.UNSPECIFIED; + } } + catch (NumberFormatException e) { + // expected, when pydevd reports "None" + resumeReason = DebugEvent.UNSPECIFIED; + } + } + else + PydevDebugPlugin.log(IStatus.ERROR, "Unexpected treadRun payload " + payload, null); + + PyThread t = (PyThread)findThreadByID(threadID); + if (t != null) { + t.setSuspended(false, null); + fireEvent(new DebugEvent(t, DebugEvent.RESUME, resumeReason)); + } + } catch (DebugException e) { + PydevDebugPlugin.log(IStatus.ERROR, "Unexpected error thread run", e); + } + } } Index: VersionCommand.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/model/VersionCommand.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** VersionCommand.java 22 Apr 2004 10:56:17 -0000 1.1 --- VersionCommand.java 27 Apr 2004 19:12:59 -0000 1.2 *************** *** 9,19 **** * Version debugger command. * ! * See protocol definition for more info */ ! public class VersionCommand extends RemoteDebuggerCommand { static final String VERSION = "1.0"; - int sequence; /** * @param debugger --- 9,18 ---- * Version debugger command. * ! * See protocol definition for more info. Used as */ ! public class VersionCommand extends AbstractDebuggerCommand { static final String VERSION = "1.0"; /** * @param debugger *************** *** 21,25 **** public VersionCommand(RemoteDebugger debugger) { super(debugger); - sequence = debugger.getNextSequence(); } --- 20,23 ---- *************** *** 31,38 **** return true; } - - public int getSequence() { - return sequence; - } public void processResponse(int cmdCode, String payload) { --- 29,32 ---- --- NEW FILE: ThreadKillCommand.java --- /* * Author: atotic * Created on Apr 22, 2004 * License: Common Public License v1.0 */ package org.python.pydev.debug.model; /** * KILL_THREAD debugger command * */ public class ThreadKillCommand extends AbstractDebuggerCommand { String thread_id; public ThreadKillCommand(RemoteDebugger debugger, String thread_id) { super(debugger); this.thread_id = thread_id; } public String getOutgoing() { return makeCommand(Integer.toString(CMD_THREAD_KILL), sequence, thread_id); } } --- NEW FILE: PySourceLocator.java --- /* * Author: atotic * Created on Apr 23, 2004 * License: Common Public License v1.0 */ package org.python.pydev.debug.model; import org.eclipse.core.runtime.IPath; import org.eclipse.debug.core.model.ISourceLocator; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.ui.ISourcePresentation; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.python.pydev.plugin.PydevPlugin; /** * * TODO Comment this class * * Take a look at IDebugModelPresentation */ public class PySourceLocator implements ISourceLocator, ISourcePresentation { public Object getSourceElement(IStackFrame stackFrame) { return stackFrame; } public IEditorInput getEditorInput(Object element) { if (element instanceof PyStackFrame) { IPath path = ((PyStackFrame)element).getPath(); if (path != null) { IEditorPart part = PydevPlugin.getDefault().doOpenEditor(path, false); if (part != null) return part.getEditorInput(); } } return null; } public String getEditorId(IEditorInput input, Object element) { return "org.python.pydev.editor.PythonEditor"; } } --- NEW FILE: XMLUtils.java --- /* * Author: atotic * Created on Apr 22, 2004 * License: Common Public License v1.0 */ package org.python.pydev.debug.model; import java.io.IOException; import java.io.StringBufferInputStream; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Iterator; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * Various utilities */ public class XMLUtils { static SAXParserFactory parserFactory = SAXParserFactory.newInstance(); /** * SAX parser for thread info * <xml><thread name="name" id="id"/><xml> */ static class XMLToThreadInfo extends DefaultHandler { public PyDebugTarget target; public ArrayList threads = new ArrayList(); public XMLToThreadInfo(PyDebugTarget target) { this.target = target; } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equals("thread")) { String name = attributes.getValue("name"); String id = attributes.getValue("id"); if (name != null) name = URLDecoder.decode(name); threads.add(new PyThread(target, name, id)); } } } /** * Creates IThread[] from the XML response */ static public IThread[] ThreadsFromXML(PyDebugTarget target, String payload) { IThread[] threads = null; try { SAXParser parser; synchronized(parserFactory) { parser = parserFactory.newSAXParser(); } XMLToThreadInfo info = new XMLToThreadInfo(target); parser.parse(new StringBufferInputStream(payload), info); threads = new IThread[info.threads.size()]; Iterator it = info.threads.iterator(); int i = 0; while (it.hasNext()) threads[i++] = (IThread)it.next(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return threads; } static class XMLToStackInfo extends DefaultHandler { public String thread_id; public String stop_reason; public ArrayList stack = new ArrayList(); /* """ <xml> <thread id="id"/> <frame id="id" name="functionName " file="file" line="line"> */ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equals("thread")) { thread_id = attributes.getValue("id"); stop_reason = attributes.getValue("stop_reason"); } else if (qName.equals("frame")) { String name = attributes.getValue("name"); String id = attributes.getValue("id"); String file = attributes.getValue("file"); String line = attributes.getValue("line"); IPath filePath = new Path(file); stack.add(new PyStackFrame(id, name, filePath, Integer.parseInt(line))); } } } /** * @param payload * @return an array of [thread_id, stop_reason, IStackFrame[]] */ public static Object[] XMLToStack(String payload) { String thread_id; IStackFrame[] stack; Object[] retVal = new Object[3]; try { SAXParser parser; synchronized(parserFactory) { parser = parserFactory.newSAXParser(); } XMLToStackInfo info = new XMLToStackInfo(); parser.parse(new StringBufferInputStream(payload), info); stack = new IStackFrame[info.stack.size()]; Iterator it = info.stack.iterator(); int i = 0; while (it.hasNext()) stack[i++] = (IStackFrame)it.next(); retVal[0] = info.thread_id; retVal[1] = info.stop_reason; retVal[2] = stack; } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return retVal; } } --- NEW FILE: AbstractDebuggerCommand.java --- /* * Author: atotic * Created on Mar 23, 2004 * License: Common Public License v1.0 */ package org.python.pydev.debug.model; import org.eclipse.core.runtime.IStatus; import org.python.pydev.debug.core.PydevDebugPlugin; /** * Superclass of all debugger commands. * * Debugger commands know how to interact with pydevd.py. * See pydevd.py for protocol information. * * Command lifecycle: * cmd = new Command() // creation * cmd.getSequence() // get the sequence number of the command * cmd.getOutgoing() // asks command for outgoing message * cmd.aboutToSend() // called right before we go on wire * // by default, if command needs response * // it gets posted to in the response queue * if (cmd.needsResponse()) * post the command to response queue, otherwise we are done * when response arrives: * if response is an error * cmd.processResponse() * else * cmd.processErrorResponse() * */ public abstract class AbstractDebuggerCommand { static final int CMD_LIST_THREADS = 102; static final int CMD_THREAD_CREATED = 103; static final int CMD_THREAD_KILL = 104; static final int CMD_THREAD_SUSPEND = 105; static final int CMD_THREAD_RUN = 106; static final int CMD_STEP_INTO = 107; static final int CMD_STEP_OVER = 108; static final int CMD_STEP_RETURN = 109; static final int CMD_ERROR = 901; static final int CMD_VERSION = 501; static final int CMD_RETURN = 502; protected RemoteDebugger debugger; int sequence; public AbstractDebuggerCommand(RemoteDebugger debugger) { this.debugger = debugger; sequence = debugger.getNextSequence(); } /** * @return outgoing message */ public abstract String getOutgoing(); /** * Notification right before the command is sent. * If subclassed, call super() */ public void aboutToSend() { // if we need a response, put me on the waiting queue if (needResponse()) debugger.addToResponseQueue(this); } /** * Does this command require a response? */ public boolean needResponse() { return false; } /** * returns Sequence # */ public final int getSequence() { return sequence; } /** * notification of the response to the command. * You'll get either processResponse or processErrorResponse */ public void processResponse(int cmdCode, String payload) { PydevDebugPlugin.log(IStatus.ERROR, "Debugger command ignored response " + getClass().toString() + payload, null); } /** * notification of the response to the command. * You'll get either processResponse or processErrorResponse */ public void processErrorResponse(int cmdCode, String payload) { PydevDebugPlugin.log(IStatus.ERROR, "Debugger command ignored error response " + getClass().toString() + payload, null); } public static String makeCommand(String code, int sequence, String payload) { StringBuffer s = new StringBuffer(); s.append(code); s.append("\t"); s.append(sequence); s.append("\t"); s.append(payload); return s.toString(); } } --- RemoteDebuggerCommand.java DELETED --- |
From: Aleksandar T. <at...@us...> - 2004-04-27 19:13:07
|
Update of /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/ui/launching In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10447/src/org/python/pydev/debug/ui/launching Modified Files: PythonRunner.java Log Message: Stepping works. Index: PythonRunner.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/ui/launching/PythonRunner.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** PythonRunner.java 22 Apr 2004 10:56:17 -0000 1.3 --- PythonRunner.java 27 Apr 2004 19:12:58 -0000 1.4 *************** *** 22,25 **** --- 22,26 ---- import org.python.pydev.debug.core.PydevDebugPlugin; import org.python.pydev.debug.model.PyDebugTarget; + import org.python.pydev.debug.model.PySourceLocator; import org.python.pydev.debug.model.RemoteDebugger; *************** *** 76,79 **** --- 77,82 ---- PyDebugTarget t = new PyDebugTarget(launch, process, config.file, debugger); + launch.setSourceLocator(new PySourceLocator()); + debugger.startTransmission(); // this starts reading/writing from sockets } |
From: Aleks T. <a...@to...> - 2004-04-27 15:12:32
|
Is the CVS mailing daemon working? Aleks |
From: Aleksandar T. <at...@us...> - 2004-04-27 01:07:53
|
Update of /cvsroot/pydev/org.python.pydev In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv428 Modified Files: Changes.txt plugin.xml Log Message: plugin.xml now exports all the libraries, so that our debug plugin can import them Index: Changes.txt =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/Changes.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Changes.txt 15 Apr 2004 23:19:21 -0000 1.3 --- Changes.txt 27 Apr 2004 01:07:44 -0000 1.4 *************** *** 11,21 **** - Added Python properties to projects that have Python nature - Editor now has a python icon. Icon is ugly, help! ! - .pyc files are filtered in the resource view ! - Parsing now happens either immediately on return, or a second after the last typing. This makes error notifications nicer and more predictable - New double-clicking strategy, copied from Java - Moved debug preferences into main plugin. We need them for import paths parsing - Hyperlinks on simple imports now work. For them to find system includes, you'll need to ! set up the python interpreter in the preferences Bug fixes: - Moved parsing so that all pydev parsers use single thread --- 11,29 ---- - Added Python properties to projects that have Python nature - Editor now has a python icon. Icon is ugly, help! ! - .pyc files are filtered out in the resource view ! - Parsing now happens either immediately on return, or a second after input This makes error notifications nicer and more predictable - New double-clicking strategy, copied from Java - Moved debug preferences into main plugin. We need them for import paths parsing - Hyperlinks on simple imports now work. For them to find system includes, you'll need to ! set up the python interpreter in the preferences. ! active hyperlinks are: ! [imports] import sys: you can click on sys, and sys.py will open ! [local function calls]: functions defined in the same file ! [class constructors]: a = SomeClass() takes you to class definition ! [self.method calls]: self.method_name works if method is defined in the same file ! - When you are editing in the tab mode, paste will replace spaces with tabs ! - tabs/spaces conversion only takes place inside code, not inside comments ! Bug fixes: - Moved parsing so that all pydev parsers use single thread Index: plugin.xml =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/plugin.xml,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** plugin.xml 22 Apr 2004 10:34:32 -0000 1.12 --- plugin.xml 27 Apr 2004 01:07:44 -0000 1.13 *************** *** 8,12 **** <runtime> ! <library name="pydev.jar"/> </runtime> <requires> --- 8,14 ---- <runtime> ! <library name="pydev.jar"> ! <export name="*"/> ! </library> </runtime> <requires> |
From: Aleksandar T. <at...@us...> - 2004-04-27 01:07:09
|
Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/model In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32709/src/org/python/pydev/editor/model Modified Files: AbstractNode.java ModelUtils.java Location.java package.html Scope.java Log Message: Minor bug fixes: - model elements take a better guess where they are with tabs - OpenAction worker method got refactored into PydevPlugin Index: Scope.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/model/Scope.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Scope.java 22 Apr 2004 10:35:22 -0000 1.3 --- Scope.java 27 Apr 2004 01:06:58 -0000 1.4 *************** *** 104,109 **** /** ! * @param name: function name ! * @param c: comparator to test for. * @return an ArrayList of AbstractNode to the function/class definitions. * each returned item will test as equal in c.compare(token, item); --- 104,109 ---- /** ! * @param token : function name ! * @param c : comparator to test for. * @return an ArrayList of AbstractNode to the function/class definitions. * each returned item will test as equal in c.compare(token, item); *************** *** 144,148 **** /** * get all the import files ! * @param startingPoint: a file to start searching from * @return an ordered ArrayList of File of all import paths for the project. */ --- 144,148 ---- /** * get all the import files ! * @param startingPoint : a file to start searching from * @return an ordered ArrayList of File of all import paths for the project. */ Index: package.html =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/model/package.html,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** package.html 10 Apr 2004 01:48:13 -0000 1.1 --- package.html 27 Apr 2004 01:06:58 -0000 1.2 *************** *** 2,10 **** The model represents the structure of the python file. ! <p>{@link org.python.pydev.model.ModelMaker ModelMaker} creates the model from AST by traversing the tree. ! <p>{@link org.python.pydev.model.ModelUtils ModelUtils} have various utility functions for model traversal, etc. ! <p>{@link org.python.pydev.model.AbstractNode AbstractNode} is the main node API. Subclasses modify it as needed. See ClassNode, FunctionCallNode, etc... --- 2,10 ---- The model represents the structure of the python file. ! <p>{@link ModelMaker ModelMaker} creates the model from AST by traversing the tree. ! <p>{@link ModelUtils} have various utility functions for model traversal, etc. ! <p>{@link org.python.pydev.editor.model.AbstractNode AbstractNode} is the main node API. Subclasses modify it as needed. See ClassNode, FunctionCallNode, etc... Index: Location.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/model/Location.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Location.java 10 Apr 2004 01:48:13 -0000 1.1 --- Location.java 27 Apr 2004 01:06:58 -0000 1.2 *************** *** 39,45 **** /** ! * @param location ! * @param location2 ! * @return */ public boolean contained(Location start, Location end) { --- 39,43 ---- /** ! * @return true if location is completely enclosed between start & end. */ public boolean contained(Location start, Location end) { Index: AbstractNode.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/model/AbstractNode.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** AbstractNode.java 22 Apr 2004 10:35:22 -0000 1.3 --- AbstractNode.java 27 Apr 2004 01:06:58 -0000 1.4 *************** *** 120,131 **** public void fixColumnLocation(Location loc, String lineText) { int where = 0; - int tabCount = 0; where = lineText.indexOf("\t", where); while (where != -1 && where <= loc.column) { where = lineText.indexOf("\t", where+1); ! tabCount++; } - if (tabCount > 0) - loc.column = loc.column - tabCount * 7; if (loc.column < 0) { loc.column = 0; --- 120,128 ---- public void fixColumnLocation(Location loc, String lineText) { int where = 0; where = lineText.indexOf("\t", where); while (where != -1 && where <= loc.column) { where = lineText.indexOf("\t", where+1); ! loc.column -= 7; } if (loc.column < 0) { loc.column = 0; Index: ModelUtils.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/model/ModelUtils.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ModelUtils.java 22 Apr 2004 10:35:22 -0000 1.3 --- ModelUtils.java 27 Apr 2004 01:06:58 -0000 1.4 *************** *** 52,59 **** /** * Depth-first search for a node that spans given location. ! * @param root: node to start the search with ! * @param loc: location we are looking for ! * @param properties: properties node must match. Pass in PROP_ANY for all nodes ! * @return */ public static AbstractNode getElement(AbstractNode root, Location loc, int properties) { --- 52,58 ---- /** * Depth-first search for a node that spans given location. ! * @param root : node to start the search with ! * @param loc : location we are looking for ! * @param properties : properties node must match. Pass in PROP_ANY for all nodes */ public static AbstractNode getElement(AbstractNode root, Location loc, int properties) { *************** *** 123,127 **** * and each parent is smaller than its children. * The siblings after me are greater, the ones before are smaller - * @return */ public static AbstractNode getPreviousNode(AbstractNode node) { --- 122,125 ---- |
From: Aleksandar T. <at...@us...> - 2004-04-27 01:07:08
|
Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/actions In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32709/src/org/python/pydev/editor/actions Modified Files: PyAddBlockComment.java PyOpenAction.java Log Message: Minor bug fixes: - model elements take a better guess where they are with tabs - OpenAction worker method got refactored into PydevPlugin Index: PyOpenAction.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/actions/PyOpenAction.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PyOpenAction.java 22 Apr 2004 10:35:24 -0000 1.2 --- PyOpenAction.java 27 Apr 2004 01:06:59 -0000 1.3 *************** *** 9,15 **** import org.eclipse.core.resources.IFile; - import org.eclipse.core.resources.IStorage; - import org.eclipse.core.resources.IWorkspace; - import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; --- 9,12 ---- *************** *** 19,34 **** import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.TextSelection; - import org.eclipse.ui.IEditorDescriptor; - import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; - import org.eclipse.ui.IEditorRegistry; - import org.eclipse.ui.IWorkbenchPage; - import org.eclipse.ui.PartInitException; - import org.eclipse.ui.PlatformUI; import org.eclipse.ui.texteditor.ITextEditor; import org.python.pydev.editor.model.ItemPointer; import org.python.pydev.editor.model.Location; - import org.python.pydev.plugin.ExternalEditorInput; - import org.python.pydev.plugin.FileStorage; import org.python.pydev.plugin.PydevPlugin; --- 16,23 ---- *************** *** 36,41 **** * Opens an editor and selects text in it. * ! * Inspired by {@link org.eclipse.jdt.ui.actions.OpenAction}, but simplifies ! * traversal of functions. */ public class PyOpenAction extends Action { --- 25,30 ---- * Opens an editor and selects text in it. * ! * Inspired by org.eclipse.jdt.ui.actions.OpenAction, but simplifies ! * all handling in a single class. */ public class PyOpenAction extends Action { *************** *** 43,88 **** public PyOpenAction() { } ! ! /** ! * Opens the file, and sets the selection. ! * @param start: ok if null, won't set selection ! * @param end ! */ ! private void openInFile(IFile file, Location start, Location end) { ! if (file == null) ! return; ! IWorkbenchPage p = PydevPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage(); ! try { ! IEditorPart editorPart= p.openEditor(file, null, true); ! if (start != null && ! editorPart instanceof ITextEditor) { ! ITextEditor textEdit = (ITextEditor)editorPart; ! showInEditor(textEdit, start, end); ! } ! } catch (PartInitException e) { ! PydevPlugin.log(IStatus.ERROR, "Unexpected error opening file", e); ! } ! } ! ! private void openInExternalFile(IPath path, Location start, Location end) { ! IStorage storage = new FileStorage(path); ! IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry(); ! IEditorDescriptor desc = registry.getDefaultEditor(path.lastSegment()); ! if (desc == null) ! desc = registry.getDefaultEditor(); ! IEditorInput input = new ExternalEditorInput(storage); ! IWorkbenchPage p = PydevPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage(); ! try { ! IEditorPart editor = p.openEditor(input, desc.getId()); ! if (start != null && ! editor instanceof ITextEditor) { ! ITextEditor textEdit = (ITextEditor)editor; ! showInEditor(textEdit, start, end); ! } ! } catch (PartInitException e) { ! PydevPlugin.log(IStatus.ERROR, "Unexpected error opening external file", e); ! } ! } ! private void showInEditor( ITextEditor textEdit, --- 32,36 ---- public PyOpenAction() { } ! private void showInEditor( ITextEditor textEdit, *************** *** 104,129 **** - public void run(ItemPointer p) { if (p.file instanceof IFile) ! openInFile((IFile)p.file, p.start, p.end); else if (p.file instanceof File) { ! IPath path = new Path(((File)p.file).getAbsolutePath()); ! IWorkspace w = ResourcesPlugin.getWorkspace(); ! IFile file = w.getRoot().getFileForLocation(path); ! if (file != null && file.exists()) ! openInFile(file, p.start, p.end); ! else { ! openInExternalFile(path, p.start, p.end); ! } ! // I wrote a plugin that does something like this; see the Fileopen plugin at ! // www.eclipsepowered.org (open source on sourceforge). Since you don't want to ! // save the file it's even easier, see the sample code posted for ! // https://bugs.eclipse.org/bugs/show_bug.cgi?id=2869 . Basically it's the same ! // idea used by the CVS plugin to view source code on an arbitrary revision, so ! // that's another place to look. HTH. } ! else { ! PydevPlugin.log(IStatus.ERROR, "Unknown ItemPointer file format", null); } } --- 52,68 ---- public void run(ItemPointer p) { + IEditorPart editor = null; if (p.file instanceof IFile) ! editor = PydevPlugin.getDefault().doOpenEditor(((IFile)p.file).getFullPath()); ! else if (p.file instanceof IPath) { ! editor = PydevPlugin.getDefault().doOpenEditor((IPath)p.file); ! } else if (p.file instanceof File) { ! Path path = new Path(((File)p.file).getAbsolutePath()); ! editor = PydevPlugin.getDefault().doOpenEditor(path); } ! if (editor instanceof ITextEditor) { ! showInEditor((ITextEditor)editor, p.start, p.end); } } Index: PyAddBlockComment.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/actions/PyAddBlockComment.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** PyAddBlockComment.java 20 Apr 2004 14:42:05 -0000 1.4 --- PyAddBlockComment.java 27 Apr 2004 01:06:59 -0000 1.5 *************** *** 21,24 **** --- 21,25 ---- /** + * . * Insert a comment block. * #===... |
From: Aleksandar T. <at...@us...> - 2004-04-27 01:07:08
|
Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/plugin In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32709/src/org/python/pydev/plugin Modified Files: PydevPlugin.java ExternalEditorInput.java Log Message: Minor bug fixes: - model elements take a better guess where they are with tabs - OpenAction worker method got refactored into PydevPlugin Index: ExternalEditorInput.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/plugin/ExternalEditorInput.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ExternalEditorInput.java 15 Apr 2004 23:19:22 -0000 1.1 --- ExternalEditorInput.java 27 Apr 2004 01:06:58 -0000 1.2 *************** *** 19,22 **** --- 19,27 ---- /** * An EditorInput for an external file. + * + * From Eclipse: EditorInput is like a file name, but more abstract + * It gets passed in to EditorPart. FileStorageEditorInput exposes the + * file, and that's how documents get their bytes. StorageEditorInput + * exposes the InputStream. */ public class ExternalEditorInput implements IStorageEditorInput { Index: PydevPlugin.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/plugin/PydevPlugin.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** PydevPlugin.java 22 Apr 2004 10:35:23 -0000 1.5 --- PydevPlugin.java 27 Apr 2004 01:06:58 -0000 1.6 *************** *** 4,13 **** --- 4,18 ---- import java.util.ResourceBundle; + import org.eclipse.core.resources.IFile; + import org.eclipse.core.resources.IStorage; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; + import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPluginDescriptor; + import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Preferences; import org.eclipse.core.runtime.Status; + import org.eclipse.ui.*; import org.eclipse.ui.plugin.AbstractUIPlugin; *************** *** 100,102 **** --- 105,136 ---- } + /** + * Utility function that opens an editor on a given path. + * + * @return part that is the editor + */ + public IEditorPart doOpenEditor(IPath path) { + if (path == null) + return null; + IWorkspace w = ResourcesPlugin.getWorkspace(); + IFile file = w.getRoot().getFileForLocation(path); + IWorkbenchPage wp = getWorkbench().getActiveWorkbenchWindow().getActivePage(); + try { + if (file != null && file.exists()) { + // File is inside the workspace + return wp.openEditor(file, null, true); + } else { + IStorage storage = new FileStorage(path); + IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry(); + IEditorDescriptor desc = registry.getDefaultEditor(path.lastSegment()); + if (desc == null) + desc = registry.getDefaultEditor(); + IEditorInput input = new ExternalEditorInput(storage); + return wp.openEditor(input, desc.getId()); + } + } catch (PartInitException e) { + log(IStatus.ERROR, "Unexpected error opening path " + path.toString(),e); + return null; + } + } } |
From: Aleksandar T. <at...@us...> - 2004-04-27 01:07:08
|
Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/parser In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32709/src/org/python/pydev/parser Modified Files: package.html Log Message: Minor bug fixes: - model elements take a better guess where they are with tabs - OpenAction worker method got refactored into PydevPlugin Index: package.html =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/parser/package.html,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** package.html 10 Apr 2004 01:48:14 -0000 1.1 --- package.html 27 Apr 2004 01:06:59 -0000 1.2 *************** *** 5,11 **** 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> \ No newline at end of file --- 5,8 ---- The parser continuously parses the input into AST (Abstract Syntax Tree). Listeners can register with PyParser to receive events when parse is complete. ! <p>Instead of using the parse tree directly, try {@link org.python.pydev.editor.model} first </body> \ No newline at end of file |
From: Aleksandar T. <at...@us...> - 2004-04-27 01:07:07
|
Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/outline In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32709/src/org/python/pydev/outline Modified Files: ParsedModel.java Log Message: Minor bug fixes: - model elements take a better guess where they are with tabs - OpenAction worker method got refactored into PydevPlugin Index: ParsedModel.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/outline/ParsedModel.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ParsedModel.java 10 Apr 2004 01:48:12 -0000 1.4 --- ParsedModel.java 27 Apr 2004 01:06:57 -0000 1.5 *************** *** 28,32 **** /** * @param outline - If not null, view to notify when parser changes - * @param parser */ public ParsedModel(PyOutlinePage outline, PyEdit editor) { --- 28,31 ---- |
From: Aleksandar T. <at...@us...> - 2004-04-27 01:07:07
|
Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32709/src/org/python/pydev/editor Modified Files: PythonCompletionProcessor.java Hyperlink.java PyEdit.java Log Message: Minor bug fixes: - model elements take a better guess where they are with tabs - OpenAction worker method got refactored into PydevPlugin Index: PyEdit.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/PyEdit.java,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** PyEdit.java 22 Apr 2004 10:35:23 -0000 1.13 --- PyEdit.java 27 Apr 2004 01:06:57 -0000 1.14 *************** *** 284,290 **** IEditorInput input = getEditorInput(); IPath filePath = null; ! if (input instanceof IStorageEditorInput) try { filePath = ((IStorageEditorInput)input).getStorage().getFullPath(); } catch (CoreException e2) { PydevPlugin.log(IStatus.ERROR, "unexpected error getting path", e2); --- 284,295 ---- IEditorInput input = getEditorInput(); IPath filePath = null; ! if (input instanceof IFileEditorInput) { ! IFile file = ((IFileEditorInput)input).getFile(); ! filePath = file.getLocation(); ! } ! else if (input instanceof IStorageEditorInput) try { filePath = ((IStorageEditorInput)input).getStorage().getFullPath(); + filePath = ((IPath)filePath).makeAbsolute(); } catch (CoreException e2) { PydevPlugin.log(IStatus.ERROR, "unexpected error getting path", e2); Index: PythonCompletionProcessor.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/PythonCompletionProcessor.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PythonCompletionProcessor.java 2 Apr 2004 18:20:45 -0000 1.1 --- PythonCompletionProcessor.java 27 Apr 2004 01:06:57 -0000 1.2 *************** *** 95,99 **** * @param doc * @param documentOffset - * @return */ private String getQualifier(IDocument doc, int documentOffset) { --- 95,98 ---- Index: Hyperlink.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/Hyperlink.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Hyperlink.java 22 Apr 2004 10:35:23 -0000 1.3 --- Hyperlink.java 27 Apr 2004 01:06:57 -0000 1.4 *************** *** 710,714 **** * * @return the SWT modifier bit, or <code>0</code> if no match was found ! * @see findModifier * @since 2.1.1 */ --- 710,714 ---- * * @return the SWT modifier bit, or <code>0</code> if no match was found ! * * @since 2.1.1 */ |
From: Aleksandar T. <at...@us...> - 2004-04-22 10:59:21
|
Update of /cvsroot/pydev/org.python.pydev.debug In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19116 Removed Files: build.xml Log Message: Checkpoint checkin. Debugger is starting to breathe, I do not want to lose it --- build.xml DELETED --- |
From: Aleksandar T. <at...@us...> - 2004-04-22 10:57:16
|
Update of /cvsroot/pydev/org.python.pydev.debug In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18672 Modified Files: plugin.xml Log Message: upgraded version to 0.4 Index: plugin.xml =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/plugin.xml,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** plugin.xml 15 Apr 2004 23:24:50 -0000 1.6 --- plugin.xml 22 Apr 2004 10:57:07 -0000 1.7 *************** *** 3,7 **** id="org.python.pydev.debug" name="Pydev debug" ! version="0.3.0" provider-name="Aleks Totic" class="org.python.pydev.debug.core.PydevDebugPlugin"> --- 3,7 ---- id="org.python.pydev.debug" name="Pydev debug" ! version="0.4.0" provider-name="Aleks Totic" class="org.python.pydev.debug.core.PydevDebugPlugin"> *************** *** 32,39 **** name="Python" delegate="org.python.pydev.debug.ui.launching.PythonLaunchConfigurationDelegate" ! modes="run, debug" id="org.python.pydev.debug.launchConfigurationType"> </launchConfigurationType> - <!--- set category="org.python.pydev.debug" to disable display in debug window--> </extension> <!--- the launcher icon --> --- 32,38 ---- name="Python" delegate="org.python.pydev.debug.ui.launching.PythonLaunchConfigurationDelegate" ! modes="run, debug" id="org.python.pydev.debug.launchConfigurationType"> </launchConfigurationType> </extension> <!--- the launcher icon --> *************** *** 64,68 **** class="org.python.pydev.debug.launching.LaunchShortcut" id="org.python.pydev.debug.launchShortcut"> ! <perspective id="org.eclipse.debug.ui.DebugPerspective"/> </shortcut> </extension> --- 63,69 ---- class="org.python.pydev.debug.launching.LaunchShortcut" id="org.python.pydev.debug.launchShortcut"> ! <perspective ! id="org.eclipse.debug.ui.DebugPerspective"> ! </perspective> </shortcut> </extension> *************** *** 114,118 **** id="org.python.pydev.debug.debug"> </launchGroup> ! <launchGroup label="Run" bannerImage="icons/python-big.gif" --- 115,119 ---- id="org.python.pydev.debug.debug"> </launchGroup> ! <launchGroup label="Run" bannerImage="icons/python-big.gif" *************** *** 132,137 **** </consoleLineTracker> </extension> - <!--- breakpoint marker --> <!--- TODO just a placeholder for now --> <extension id="pyBreakpointMarker" --- 133,138 ---- </consoleLineTracker> </extension> <!--- TODO just a placeholder for now --> + <!--- breakpoint marker --> <extension id="pyBreakpointMarker" *************** *** 156,158 **** --- 157,160 ---- </attribute> </extension> + </plugin> |
From: Aleksandar T. <at...@us...> - 2004-04-22 10:56:28
|
Update of /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/model In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18445/src/org/python/pydev/debug/model Modified Files: RemoteDebuggerCommand.java RemoteDebugger.java Added Files: PyThread.java VersionCommand.java ModelUtils.java ListThreadsCommand.java PyDebugTarget.java Removed Files: PythonDebugTarget.java Log Message: The beginning of the new debugger technology --- NEW FILE: VersionCommand.java --- /* * Author: atotic * Created on Apr 19, 2004 * License: Common Public License v1.0 */ package org.python.pydev.debug.model; /** * Version debugger command. * * See protocol definition for more info */ public class VersionCommand extends RemoteDebuggerCommand { static final String VERSION = "1.0"; int sequence; /** * @param debugger */ public VersionCommand(RemoteDebugger debugger) { super(debugger); sequence = debugger.getNextSequence(); } public String getOutgoing() { return makeCommand(Integer.toString(CMD_VERSION), sequence, VERSION); } public boolean needResponse() { return true; } public int getSequence() { return sequence; } public void processResponse(int cmdCode, String payload) { System.err.println("The version is " + payload); } } Index: RemoteDebugger.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/model/RemoteDebugger.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** RemoteDebugger.java 29 Mar 2004 17:07:25 -0000 1.1 --- RemoteDebugger.java 22 Apr 2004 10:56:18 -0000 1.2 *************** *** 9,85 **** import java.net.*; import java.util.ArrayList; ! import java.util.Iterator; /** * Network interface to the remote debugger. */ ! public class RemoteDebugger implements Runnable { ! // socket communication ! Socket socket; ! PrintWriter toServer; ! BufferedReader fromServer; ! InputStream sin; ! ArrayList commands = new ArrayList(); // command queue ! public RemoteDebugger(Socket socket) throws IOException { ! this.socket = socket; ! OutputStream sout = socket.getOutputStream(); ! sin = socket.getInputStream(); ! fromServer = new BufferedReader(new InputStreamReader(sin)); ! toServer = new PrintWriter(new OutputStreamWriter(sout)); ! } ! public void sendCommand(RemoteDebuggerCommand command) { ! synchronized(commands) { ! commands.add(command); } - } ! private void execute1Command(RemoteDebuggerCommand c) { ! String sendThis = c.getXMLMessage(); ! toServer.write(sendThis); ! // TODO process result } ! /** ! * ! * @param commandList - a list of RemoteDebuggerCommand's to be executed ! */ ! private void executeCommands(ArrayList commandList) { ! Iterator iter = commandList.iterator(); ! while (!iter.hasNext()) { ! execute1Command((RemoteDebuggerCommand)iter.next()); } } ! /** ! * Execute commands in an infinite loop. */ ! public void run() { ! try { ! while (!socket.isClosed()) { ! if (!commands.isEmpty()) { ! ArrayList toExecute = new ArrayList(); ! synchronized(commands) { ! while (!commands.isEmpty()) ! toExecute.add(commands.remove(0)); } ! executeCommands(toExecute); ! } ! if (fromServer.ready()) { ! char[] cbuf = new char[2048]; ! int howMany = fromServer.read(cbuf); ! System.out.print(new String(cbuf, 0, howMany)); } Thread.sleep(100); } - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO handle this - e.printStackTrace(); } } --- 9,305 ---- import java.net.*; import java.util.ArrayList; ! import java.util.Hashtable; ! ! import org.eclipse.core.runtime.CoreException; ! import org.eclipse.core.runtime.IProgressMonitor; ! import org.eclipse.core.runtime.IStatus; ! import org.eclipse.core.runtime.Status; ! import org.eclipse.debug.core.model.IProcess; ! import org.python.pydev.debug.core.PydevDebugPlugin; ! import org.python.pydev.debug.ui.launching.PythonRunnerConfig; /** * Network interface to the remote debugger. */ ! public class RemoteDebugger extends Object { ! private int sequence = -1; // sequence seed for command numbers ! ! private Socket socket; // connection socket ! private Reader reader; // reading thread ! private Writer writer; // writing thread ! private ListenConnector connector; // Runnable that connects to the debugger ! private Thread connectThread; // ! private PythonRunnerConfig config; ! private PyDebugTarget target = null; ! protected class ListenConnector implements Runnable { ! int port; ! int timeout; ! ServerSocket serverSocket; ! Socket socket; // what got accepted ! Exception e; ! ! boolean terminated; ! ! public ListenConnector(int port, int timeout) throws IOException { ! this.port = port; ! this.timeout = timeout; ! serverSocket = new ServerSocket(port); ! } ! ! Exception getException() { ! return e; ! } ! public Socket getSocket() { ! return socket; ! } ! public void stopListening() { ! if (serverSocket != null) ! try { ! serverSocket.close(); ! } catch (IOException e) { ! PydevDebugPlugin.log(IStatus.WARNING, "Error closing pydevd socket", e); ! } ! terminated = true; } ! public void run() { ! try { ! serverSocket.setSoTimeout(timeout); ! socket = serverSocket.accept(); ! } ! catch (IOException e) { ! this.e = e; ! } ! } } ! /** ! * Writer writes debugger commands to the network. ! * Use postCommand to put new ones in queue. ! */ ! protected class Writer implements Runnable { ! ArrayList cmdQueue; // a list of RemoteDebuggerCommands ! PrintWriter out; ! boolean done; ! ! public Writer(Socket s) throws IOException { ! done = false; ! cmdQueue = new ArrayList(); ! OutputStream sout; ! sout = s.getOutputStream(); ! out = new PrintWriter(new OutputStreamWriter(sout)); ! } ! ! /** ! * Add command for processing ! */ ! public void postCommand(RemoteDebuggerCommand cmd) { ! synchronized(cmdQueue) { ! cmdQueue.add(cmd); ! } ! } ! ! public void done() { ! this.done = true; ! } ! ! /** ! * Loops and writes commands to the output ! */ ! public void run() { ! while (!done) { ! RemoteDebuggerCommand cmd = null; ! synchronized (cmdQueue) { ! if (cmdQueue.size() > 0) ! cmd = (RemoteDebuggerCommand) cmdQueue.remove(0); ! } ! if (cmd != null) { ! cmd.aboutToSend(); ! out.write(cmd.getOutgoing()); ! out.write("\n"); ! out.flush(); ! } ! try { ! Thread.sleep(100); ! } catch (InterruptedException e) { ! // TODO Auto-generated catch block ! e.printStackTrace(); ! } ! } } } ! ! /** ! * Reads and dispatches commands */ ! protected class Reader implements Runnable { ! boolean done; ! Hashtable responseQueue; // commands waiting for response. Their keys are the sequence ids ! BufferedReader in; ! ! public Reader(Socket socket) throws IOException { ! done = false; ! responseQueue = new Hashtable(); ! InputStream sin = socket.getInputStream(); ! in = new BufferedReader(new InputStreamReader(sin)); ! } ! ! public void done() { ! this.done = true; ! } ! ! public void addToResponseQueue(RemoteDebuggerCommand cmd) { ! responseQueue.put(new Integer(cmd.getSequence()), cmd); ! Object o = responseQueue.remove(new Integer(cmd.getSequence())); ! System.out.println(o.toString()); ! responseQueue.put(new Integer(cmd.getSequence()), cmd); ! } ! ! /** ! * Parses & dispatches the command ! */ ! private void processCommand(String cmdLine) { ! int cmdCode; ! int seqCode; ! String payload; ! String[] cmdParsed = cmdLine.split("\t", 3); ! cmdCode = Integer.parseInt(cmdParsed[0]); ! seqCode = Integer.parseInt(cmdParsed[1]); ! payload = cmdParsed[2]; ! // is there a response waiting ! RemoteDebuggerCommand cmd = (RemoteDebuggerCommand)responseQueue.remove(new Integer(seqCode)); ! if (cmd == null) ! if (target != null) ! target.processCommand(cmdParsed[0], cmdParsed[1], cmdParsed[2]); ! else ! PydevDebugPlugin.log(IStatus.ERROR, "internal error, command received no target", null); ! else { ! if (cmdParsed[0].startsWith("9")) ! cmd.processErrorResponse(cmdCode, payload); ! else ! cmd.processResponse(cmdCode, payload); ! } ! } ! ! public void run() { ! while (!done) { ! try { ! if (in.ready()) { ! String cmdLine = in.readLine(); ! processCommand(cmdLine); } ! Thread.sleep(100); ! } catch (IOException e) { ! PydevDebugPlugin.log(IStatus.WARNING, "Unexpected termination of remote dbg input stream", e); ! } catch (InterruptedException e1) { ! e1.printStackTrace(); } + if (socket.isConnected() == false) + System.err.println("no longer connected"); + } + } + } + + public RemoteDebugger(PythonRunnerConfig config) { + this.config = config; + } + + public void setTarget(PyDebugTarget target) { + this.target = target; + } + + /** + * @return next available debugger command sequence number + */ + public int getNextSequence() { + sequence += 2; + return sequence; + } + + public void startConnect(IProgressMonitor monitor) throws IOException, CoreException { + monitor.subTask("Finding free socket..."); + connector = new ListenConnector(config.getDebugPort(), config.acceptTimeout); + connectThread = new Thread(connector, "pydevd.connect"); + connectThread.start(); + } + + /** + * Wait for the connection to the debugger to complete. + * + * If this method returns without an exception, we've connected. + * @return true if operation was cancelled by user + */ + public boolean waitForConnect(IProgressMonitor monitor, Process p, IProcess ip) throws Exception { + // Launch the debug listener on a thread, and wait until it completes + while (connectThread.isAlive()) { + if (monitor.isCanceled()) { + connector.stopListening(); + p.destroy(); + return true; + } + try { + p.exitValue(); // throws exception if process has terminated + // process has terminated - stop waiting for a connection + connector.stopListening(); + String errorMessage= ip.getStreamsProxy().getErrorStreamMonitor().getContents(); + if (errorMessage.length() != 0) + // not sure if this is really an error + throw new CoreException(new Status(IStatus.ERROR, PydevDebugPlugin.getPluginID(), 0, "Something got printed in the error stream", null)); + } catch (IllegalThreadStateException e) { + // expected while process is alive + } + try { Thread.sleep(100); + } catch (InterruptedException e) { } } + if (connector.getException() != null) + throw connector.getException(); + connected(connector.getSocket()); + return false; + } + + /** + * Remote debugger has connected + */ + public void connected(Socket socket) throws IOException { + this.socket = socket; + this.reader = new Reader(socket); + this.writer = new Writer(socket); + Thread t = new Thread(reader, "pydevd.reader"); + t.start(); + t = new Thread(writer, "pydevd.writer"); + t.start(); + writer.postCommand(new VersionCommand(this)); + } + /** + * Dispose must be called to clean up. + */ + public void dispose() { + if (connector != null) + connector.stopListening(); + if (reader != null) + reader.done(); + if (writer != null) + writer.done(); + if (socket != null && socket.isConnected()) + try { + socket.close(); + } catch (IOException e) { + // other end might have closed first + } + target = null; + } + + public void addToResponseQueue(RemoteDebuggerCommand cmd) { + reader.addToResponseQueue(cmd); + } + + public void postCommand(RemoteDebuggerCommand cmd) { + writer.postCommand(cmd); } --- NEW FILE: ModelUtils.java --- /* * Author: atotic * Created on Apr 22, 2004 * License: Common Public License v1.0 */ package org.python.pydev.debug.model; import java.io.IOException; import java.io.StringBufferInputStream; import java.util.ArrayList; import java.util.Iterator; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.eclipse.debug.core.model.IThread; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * Various utilities */ public class ModelUtils { /** * SAX parser for thread info * <xml><thread name="name" id="id"/><xml> */ static class XMLToThreadInfo extends DefaultHandler { public PyDebugTarget target; public ArrayList threads = new ArrayList(); public XMLToThreadInfo(PyDebugTarget target) { this.target = target; } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equals("thread")) { String name = attributes.getValue("name"); String id = attributes.getValue("id"); threads.add(new PyThread(target, name, id)); } } } /** * Creates IThread[] from the XML response */ static public IThread[] ThreadsFromXML(PyDebugTarget target, String payload) { IThread[] threads = null; try { SAXParserFactory parserFactory = SAXParserFactory.newInstance(); SAXParser parser = parserFactory.newSAXParser(); XMLToThreadInfo info = new XMLToThreadInfo(target); parser.parse(new StringBufferInputStream(payload), info); threads = new IThread[info.threads.size()]; Iterator it = info.threads.iterator(); int i = 0; while (it.hasNext()) threads[i++] = (IThread)it.next(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return threads; } } --- PythonDebugTarget.java DELETED --- --- NEW FILE: ListThreadsCommand.java --- /* * Author: atotic * Created on Apr 21, 2004 * License: Common Public License v1.0 */ package org.python.pydev.debug.model; import org.eclipse.core.runtime.IStatus; import org.eclipse.debug.core.model.IThread; import org.python.pydev.debug.core.PydevDebugPlugin; /** * ListThreads command. * * See protocol for more info */ public class ListThreadsCommand extends RemoteDebuggerCommand { int sequence; boolean done; PyDebugTarget target; IThread[] threads; public ListThreadsCommand(RemoteDebugger debugger, PyDebugTarget target) { super(debugger); this.target = target; sequence = debugger.getNextSequence(); done = false; } public void waitUntilDone(int timeout) throws InterruptedException { while (!done && timeout > 0) { timeout -= 100; Thread.sleep(100); } if (timeout < 0) throw new InterruptedException(); } public IThread[] getThreads() { return threads; } public int getSequence() { return sequence; } public String getOutgoing() { return makeCommand(Integer.toString(CMD_LIST_THREADS), sequence, ""); } public boolean needResponse() { return true; } /** * The response is a list of threads */ public void processResponse(int cmdCode, String payload) { if (cmdCode != 102) { PydevDebugPlugin.log(IStatus.ERROR, "Unexpected response to LIST THREADS" + payload, null); return; } threads = ModelUtils.ThreadsFromXML(target, payload); done = true; } public void processErrorResponse(int cmdCode, String payload) { PydevDebugPlugin.log(IStatus.ERROR, "LIST THREADS got an error " + payload, null); } } --- NEW FILE: PyThread.java --- /* * Author: atotic * Created on Apr 21, 2004 * License: Common Public License v1.0 */ package org.python.pydev.debug.model; import org.eclipse.core.resources.IResource; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; /** * Represents python threads. * * */ public class PyThread implements IThread { private PyDebugTarget target; private String name; private String id; public PyThread(PyDebugTarget target, String name, String id) { this.target = target; this.name = name; this.id = id; } public String getName() throws DebugException { return name; } public int getPriority() throws DebugException { // TODO maybe daemon status of the threads? return 0; } public String getModelIdentifier() { return target.getModelIdentifier(); } public IDebugTarget getDebugTarget() { return target; } public ILaunch getLaunch() { return target.getLaunch(); } public boolean canTerminate() { return true; } public boolean isTerminated() { return target.isTerminated(); } public void terminate() throws DebugException { System.out.print("Terminating thread"); } public boolean canResume() { // TODO Auto-generated method stub return false; } public boolean canSuspend() { // TODO Auto-generated method stub return true; } public boolean isSuspended() { // TODO Auto-generated method stub return false; } public void resume() throws DebugException { // TODO Auto-generated method stub } public void suspend() throws DebugException { // TODO Auto-generated method stub } public boolean canStepInto() { // TODO Auto-generated method stub return false; } public boolean canStepOver() { // TODO Auto-generated method stub return false; } public boolean canStepReturn() { // TODO Auto-generated method stub return false; } public boolean isStepping() { // TODO Auto-generated method stub return false; } public void stepInto() throws DebugException { // TODO Auto-generated method stub } public void stepOver() throws DebugException { // TODO Auto-generated method stub } public void stepReturn() throws DebugException { // TODO Auto-generated method stub } public IStackFrame[] getStackFrames() throws DebugException { // TODO Auto-generated method stub return null; } public boolean hasStackFrames() throws DebugException { // TODO Auto-generated method stub return false; } public IStackFrame getTopStackFrame() throws DebugException { // TODO Auto-generated method stub return null; } public IBreakpoint[] getBreakpoints() { // TODO Auto-generated method stub return null; } public Object getAdapter(Class adapter) { if (adapter.equals(ILaunch.class) || adapter.equals(IResource.class)) return target.getAdapter(adapter); // ongoing, I do not fully understand all the interfaces they'd like me to support System.err.println("PythonThread Need adapter " + adapter.toString()); return null; } } Index: RemoteDebuggerCommand.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/model/RemoteDebuggerCommand.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** RemoteDebuggerCommand.java 29 Mar 2004 17:07:25 -0000 1.1 --- RemoteDebuggerCommand.java 22 Apr 2004 10:56:18 -0000 1.2 *************** *** 6,79 **** package org.python.pydev.debug.model; /** ! * Interacts with jpydaemon.py. * ! * Knows how to create and interpret jpydaemon commands. * ! * jpydaemon commands: * - * STOP: exits the debugger - * CMD <command>: takes a command and executes it - - success: - <JPY> <COMMAND cmd="CMD a=1" operation="a=1" result="OK" /></JPY> - <JPY> <STDOUT content="1" /></JPY> - <JPY> <STDOUT content="/EOL/" /></JPY> - <JPY> <COMMAND cmd="CMD print a" operation="print a" result="OK" /></JPY> - error: - <JPY> <COMMAND cmd="CMD er!" operation="er!" result="Error on CMD" /></JPY> - <JPY> <COMMANDDETAIL content="Traceback (most recent call last):" /></JPY> - <JPY> <COMMANDDETAIL content=" File "D:\pydevspace2\org.python.pydev.debug\pysrc\jpydaemon.py", line 231, in dealWithCmd code = compile( arg ,"<string>" , cmdType)" /></JPY> - <JPY> <COMMANDDETAIL content=" File "<string>", line 1" /></JPY> - <JPY> <COMMANDDETAIL content=" er!" /></JPY> - <JPY> <COMMANDDETAIL content=" ^" /></JPY> - <JPY> <COMMANDDETAIL content="SyntaxError: unexpected EOF while parsing" /></JPY> - - * READSRC <filename>: reads in the whole file - * SETARGS : sets arguments before we start execution - <JPY> <COMMAND cmd="SETARGS -u -v" operation="-u -v" result="OK" /></JPY> - - * DBG: - <JPY><COMMAND cmd="DBG test.py" /></JPY> - <JPY> <LINE cmd="31" fn="<string>" lineno="1" name="?" line="" /></JPY> */ ! public class RemoteDebuggerCommand { ! public final static String VERSION = "JpyDbg 0.0.3" ; ! public final static int INACTIVE = 0 ; ! public final static int STARTING = 1 ; ! public final static int STARTED = 2 ; ! ! private final static String _ERROR_ = "ERROR:" ; ! private final static String _END_OF_LINE_ = "\n" ; ! private final static String _INACTIVE_TEXT_ = "inactive" ; ! private final static String _READY_TEXT_ = "ready" ; ! private final static String _STRING_ ="<string>" ; ! private final static String _EOL_ = "/EOL/" ; ! private final static String _OK_ = "OK" ; ! ! private final static String _COMMAND_ = "CMD " ; ! private final static String _BPSET_ = "BP+ " ; ! private final static String _BPCLEAR_ = "BP- " ; ! private final static String _DBG_ = "DBG " ; ! private final static String _SETARGS_ = "SETARGS " ; ! private final static String _READSRC_ = "READSRC " ; ! private final static String _NEXT_ = "NEXT " ; ! private final static String _SET_ = "set " ; ! private final static String _STEP_ = "STEP " ; ! private final static String _RUN_ = "RUN " ; ! private final static String _STOP_ = "STOP " ; ! private final static String _STACK_ = "STACK " ; ! private final static String _GLOBALS_ = "GLOBALS " ; ! private final static String _GLOBAL_ = "global" ; ! private final static String _EQUAL_ = "=" ; ! private final static String _SEMICOLON_= ";" ; ! private final static String _SILENT_ = "silent" ; ! private final static String _LOCALS_ = "LOCALS " ; ! private final static String _SPACE_ = " " ; ! String xmlMessage; ! public String getXMLMessage() { ! return xmlMessage; } } --- 6,99 ---- package org.python.pydev.debug.model; + import org.eclipse.core.runtime.IStatus; + import org.python.pydev.debug.core.PydevDebugPlugin; + /** ! * Superclass of all debugger commands. * ! * Debugger commands know how to interact with pydevd.py. ! * See pydevd.py for protocol information. * ! * Command lifecycle: ! * cmd = new Command() // creation ! * cmd.getSequence() // get the sequence number of the command ! * cmd.getOutgoing() // asks command for outgoing message ! * cmd.aboutToSend() // called right before we go on wire ! * // by default, if command needs response ! * // it gets posted to in the response queue ! * if (cmd.needsResponse()) ! * post the command to response queue, otherwise we are done ! * when response arrives: ! * if response is an error ! * cmd.processResponse() ! * else ! * cmd.processErrorResponse() * */ ! public abstract class RemoteDebuggerCommand { ! ! static final int CMD_LIST_THREADS = 102; ! static final int CMD_THREAD_CREATED = 103; ! static final int CMD_ERROR = 501; ! static final int CMD_VERSION = 901; ! static final int CMD_RETURN = 902; ! ! protected RemoteDebugger debugger; ! ! public RemoteDebuggerCommand(RemoteDebugger debugger) { ! this.debugger = debugger; ! } ! /** ! * @return outgoing message ! */ ! public abstract String getOutgoing(); ! /** ! * Notification right before the command is sent. ! * If subclassed, call super() ! */ ! public void aboutToSend() { ! // if we need a response, put me on the waiting queue ! if (needResponse()) ! debugger.addToResponseQueue(this); ! } ! ! /** ! * Does this command require a response? ! */ ! public boolean needResponse() { ! return false; ! } ! ! /** ! * returns Sequence # ! */ ! public int getSequence() { ! System.err.println("Fatal: must override getSequence"); ! PydevDebugPlugin.log(IStatus.ERROR, "getSequence must be overridden", null); ! return 0; ! } ! ! /** ! * notification of the response to the command. ! * You'll get either processResponse or processErrorResponse ! */ ! public void processResponse(int cmdCode, String payload) { ! PydevDebugPlugin.log(IStatus.ERROR, "Debugger command ignored response " + getClass().toString() + payload, null); ! } ! ! public void processErrorResponse(int cmdCode, String payload) { ! PydevDebugPlugin.log(IStatus.ERROR, "Debugger command ignored error response " + getClass().toString() + payload, null); ! } ! ! public static String makeCommand(String code, int sequence, String payload) { ! StringBuffer s = new StringBuffer(); ! s.append(code); ! s.append("\t"); ! s.append(sequence); ! s.append("\t"); ! s.append(payload); ! return s.toString(); } } --- NEW FILE: PyDebugTarget.java --- /* * Author: atotic * Created on Mar 23, 2004 * License: Common Public License v1.0 */ package org.python.pydev.debug.model; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchListener; import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.core.model.IThread; import org.python.pydev.debug.core.PydevDebugPlugin; /** * * TODO Comment this class * Make sure we fire the right org.eclipse.debug.core.DebugEvents */ public class PyDebugTarget implements IDebugTarget, ILaunchListener { ILaunch launch; IProcess process; RemoteDebugger debugger; IPath file; IThread[] threads; public PyDebugTarget(ILaunch launch, IProcess process, IPath file, RemoteDebugger debugger) { this.launch = launch; this.process = process; this.file = file; this.debugger = debugger; this.threads = new IThread[0]; launch.addDebugTarget(this); debugger.setTarget(this); // we have to know when we get removed, so that we can shut off the debugger DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this); } public void launchRemoved(ILaunch launch) { // shut down the remote debugger when parent launch if (launch == this.launch) { debugger.dispose(); debugger = null; } } public void launchAdded(ILaunch launch) { // noop } public void launchChanged(ILaunch launch) { // noop } // From IDebugElement public String getModelIdentifier() { return PydevDebugPlugin.getPluginID(); } // From IDebugElement public IDebugTarget getDebugTarget() { return this; } // From IDebugElement public ILaunch getLaunch() { return launch; } public IProcess getProcess() { return process; } public String getName() throws DebugException { if (file != null) return file.lastSegment(); else return "unknown"; } public boolean canTerminate() { // We can always terminate, it makes no harm return true; } public boolean isTerminated() { return process.isTerminated(); } public void terminate() throws DebugException { process.terminate(); } public boolean canDisconnect() { // TODO NOW Auto-generated method stub return true; } public void disconnect() throws DebugException { // TODO Auto-generated method stub } public boolean isDisconnected() { // TODO NOW Auto-generated method stub return false; } public boolean canResume() { // TODO NOW Auto-generated method stub return false; } public boolean canSuspend() { // TODO NOW Auto-generated method stub return true; } public boolean isSuspended() { // TODO Auto-generated method stub return false; } public void resume() throws DebugException { // TODO Auto-generated method stub } public void suspend() throws DebugException { // TODO Auto-generated method stub } public IThread[] getThreads() throws DebugException { if (threads == null) { ListThreadsCommand cmd = new ListThreadsCommand(debugger, this); debugger.postCommand(cmd); try { cmd.waitUntilDone(1000); threads = cmd.getThreads(); } catch (InterruptedException e) { threads = new IThread[0]; } } return threads; } public boolean hasThreads() throws DebugException { return true; } public boolean supportsBreakpoint(IBreakpoint breakpoint) { // TODO Auto-generated method stub return false; } public void breakpointAdded(IBreakpoint breakpoint) { // TODO Auto-generated method stub } public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) { // TODO Auto-generated method stub } public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) { // TODO Auto-generated method stub } public boolean supportsStorageRetrieval() { // TODO Auto-generated method stub return false; } public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException { // TODO Auto-generated method stub return null; } public Object getAdapter(Class adapter) { // TODO Auto-generated method stub if (adapter.equals(ILaunch.class)) return launch; else if (adapter.equals(IResource.class)) { IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(file); if (files != null && files.length > 0) return files[0]; else return null; } else System.err.println("Need adapter " + adapter.toString()); return null; } /** * When a command that originates from daemon is received, * this routine processes it. * The responses to commands originating from here * are processed by commands themselves */ public void processCommand(String sCmdCode, String sSeqCode, String payload) { int cmdCode = Integer.parseInt(sCmdCode); int seqCode = Integer.parseInt(sSeqCode); if (cmdCode == RemoteDebuggerCommand.CMD_THREAD_CREATED) processThreadCreated(payload); else PydevDebugPlugin.log(IStatus.WARNING, "Unexpected debugger command" + sCmdCode, null); } private void fireEvent(DebugEvent event) { DebugPlugin manager= DebugPlugin.getDefault(); if (manager != null) { manager.fireDebugEventSet(new DebugEvent[]{event}); } } private void processThreadCreated(String payload) { IThread[] newThreads = ModelUtils.ThreadsFromXML(this, payload); if (threads == null) threads = newThreads; else { IThread[] combined = new IThread[threads.length + newThreads.length]; int i = 0; for (i = 0; i < threads.length; i++) combined[i] = threads[i]; for (int j = 0; j < newThreads.length; i++, j++) combined[i] = newThreads[j]; threads = combined; } // Now notify debugger that new threads were added for (int i =0; i< newThreads.length; i++) fireEvent(new DebugEvent(newThreads[i], DebugEvent.CREATE)); } } |
From: Aleksandar T. <at...@us...> - 2004-04-22 10:56:27
|
Update of /cvsroot/pydev/org.python.pydev.debug/src/org In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18445/src/org Added Files: .cvsignore Log Message: The beginning of the new debugger technology --- NEW FILE: .cvsignore --- jymc |
From: Aleksandar T. <at...@us...> - 2004-04-22 10:56:26
|
Update of /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/ui/launching In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18445/src/org/python/pydev/debug/ui/launching Modified Files: PythonRunner.java PythonRunnerConfig.java Log Message: The beginning of the new debugger technology Index: PythonRunner.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/ui/launching/PythonRunner.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PythonRunner.java 15 Apr 2004 23:24:49 -0000 1.2 --- PythonRunner.java 22 Apr 2004 10:56:17 -0000 1.3 *************** *** 21,25 **** import org.python.pydev.debug.core.Constants; import org.python.pydev.debug.core.PydevDebugPlugin; ! import org.python.pydev.debug.model.PythonDebugTarget; import org.python.pydev.debug.model.RemoteDebugger; --- 21,25 ---- import org.python.pydev.debug.core.Constants; import org.python.pydev.debug.core.PydevDebugPlugin; ! import org.python.pydev.debug.model.PyDebugTarget; import org.python.pydev.debug.model.RemoteDebugger; *************** *** 32,75 **** public class PythonRunner { - class DebugConnector implements Runnable { - int port; - int timeout; - ServerSocket serverSocket; - Socket socket; // what got accepted - Exception e; - - boolean terminated; - - public DebugConnector(int port, int timeout) throws IOException { - this.port = port; - this.timeout = timeout; - serverSocket = new ServerSocket(port); - } - - Exception getException() { - return e; - } - - public Socket getSocket() { - return socket; - } - - public void stopListening() throws IOException { - if (serverSocket != null) - serverSocket.close(); - terminated = true; - } - - public void run() { - try { - serverSocket.setSoTimeout(timeout); - socket = serverSocket.accept(); - } - catch (IOException e) { - this.e = e; - } - } - } public void runDebug(PythonRunnerConfig config, ILaunch launch, IProgressMonitor monitor) throws CoreException, IOException { if (monitor == null) --- 32,41 ---- public class PythonRunner { + /** + * Launches the config in the debug mode. + * + * Loosely modeled upon Ant launcher. + */ public void runDebug(PythonRunnerConfig config, ILaunch launch, IProgressMonitor monitor) throws CoreException, IOException { if (monitor == null) *************** *** 79,91 **** // Launch & connect to the debugger ! subMonitor.subTask("Finding free socket..."); ! DebugConnector server = new DebugConnector(config.getDebugPort(), config.acceptTimeout); ! subMonitor.worked(1); subMonitor.subTask("Constructing command_line..."); String[] cmdLine = config.getCommandLine(); ! subMonitor.worked(1); ! ! Thread connectThread = new Thread(server, "Pydev debug listener"); ! connectThread.start(); Process p = DebugPlugin.exec(cmdLine, config.workingDirectory); if (p == null) --- 45,53 ---- // Launch & connect to the debugger ! RemoteDebugger debugger = new RemoteDebugger(config); ! debugger.startConnect(subMonitor); subMonitor.subTask("Constructing command_line..."); String[] cmdLine = config.getCommandLine(); ! Process p = DebugPlugin.exec(cmdLine, config.workingDirectory); if (p == null) *************** *** 94,127 **** IProcess process = registerWithDebugPlugin(config, launch, p); ! // Register the process with the debug plugin ! subMonitor.worked(2); ! subMonitor.subTask("Starting debugger..."); ! // Launch the debug listener on a thread, and wait until it completes ! while (connectThread.isAlive()) { ! if (monitor.isCanceled()) { ! server.stopListening(); ! p.destroy(); return; } - try { - p.exitValue(); // throws exception if process has terminated - // process has terminated - stop waiting for a connection - try { - server.stopListening(); - } catch (IOException e) { - // expected - } - checkErrorMessage(process); - } catch (IllegalThreadStateException e) { - // expected while process is alive - } - try { - Thread.sleep(100); - } catch (InterruptedException e) { - } } ! ! Exception ex = server.getException(); ! if (ex != null) { process.terminate(); p.destroy(); --- 56,68 ---- IProcess process = registerWithDebugPlugin(config, launch, p); ! subMonitor.subTask("Waiting for connection..."); ! try { ! boolean userCanceled = debugger.waitForConnect(subMonitor, p, process); ! if (userCanceled) { ! debugger.dispose(); return; } } ! catch (Exception ex) { process.terminate(); p.destroy(); *************** *** 129,148 **** if (ex instanceof SocketTimeoutException) message = "Timed out after " + Float.toString(config.acceptTimeout/1000) + " seconds while waiting for python script to connect."; ! throw new CoreException(new Status(IStatus.ERROR, PydevDebugPlugin.getPluginID(), 0, message, ex)); } // hook up debug model, and we are off & running ! RemoteDebugger debugger = new RemoteDebugger(server.getSocket()); ! PythonDebugTarget t = new PythonDebugTarget(launch, process, ! config.getRunningName(), debugger); ! Thread dt = new Thread(debugger, "Pydev remote debug connection"); ! dt.start(); } /** ! * launches the debug configuration ! * @param config ! * @param launch ! * @param monitor ! * @throws CoreException */ public void run(PythonRunnerConfig config, ILaunch launch, IProgressMonitor monitor) throws CoreException, IOException { --- 70,85 ---- if (ex instanceof SocketTimeoutException) message = "Timed out after " + Float.toString(config.acceptTimeout/1000) + " seconds while waiting for python script to connect."; ! throw new CoreException(new Status(IStatus.ERROR, PydevDebugPlugin.getPluginID(), 0, message, ex)); } + subMonitor.subTask("Done"); // hook up debug model, and we are off & running ! PyDebugTarget t = new PyDebugTarget(launch, process, ! config.file, debugger); } /** ! * Launches the configuration ! * ! * The code is modeled after Ant launching example. */ public void run(PythonRunnerConfig config, ILaunch launch, IProgressMonitor monitor) throws CoreException, IOException { *************** *** 159,163 **** subMonitor.subTask("Constructing command_line..."); String[] cmdLine = config.getCommandLine(); - subMonitor.worked(1); subMonitor.subTask("Exec..."); --- 96,99 ---- *************** *** 167,171 **** // Register the process with the debug plugin - subMonitor.worked(2); subMonitor.subTask("Done"); registerWithDebugPlugin(config, launch, p); --- 103,106 ---- *************** *** 173,177 **** /** ! * TODO document */ private IProcess registerWithDebugPlugin(PythonRunnerConfig config, ILaunch launch, Process p) { --- 108,113 ---- /** ! * The debug plugin needs to be notified about our process. ! * It'll then display the appropriate UI. */ private IProcess registerWithDebugPlugin(PythonRunnerConfig config, ILaunch launch, Process p) { *************** *** 181,190 **** return DebugPlugin.newProcess(launch,p, config.file.lastSegment(), processAttributes); } - - protected void checkErrorMessage(IProcess process) throws CoreException { - String errorMessage= process.getStreamsProxy().getErrorStreamMonitor().getContents(); - if (errorMessage.length() != 0) - // TODO not sure if this is really an error - throw new CoreException(new Status(IStatus.ERROR, PydevDebugPlugin.getPluginID(), 0, "Something got printed in the error stream", null)); - } } --- 117,119 ---- Index: PythonRunnerConfig.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/ui/launching/PythonRunnerConfig.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PythonRunnerConfig.java 15 Apr 2004 23:24:49 -0000 1.2 --- PythonRunnerConfig.java 22 Apr 2004 10:56:17 -0000 1.3 *************** *** 91,95 **** */ public static String getDebugScript() throws CoreException { ! IPath relative = new Path("pysrc").addTrailingSeparator().append("jpydaemon.py"); // IPath relative = new Path("pysrc").addTrailingSeparator().append("rpdb.py"); URL location = org.python.pydev.debug.core.PydevDebugPlugin.getDefault().find(relative); --- 91,96 ---- */ public static String getDebugScript() throws CoreException { ! IPath relative = new Path("pysrc").addTrailingSeparator().append("pydevd.py"); ! // IPath relative = new Path("pysrc").addTrailingSeparator().append("jpydaemon.py"); // IPath relative = new Path("pysrc").addTrailingSeparator().append("rpdb.py"); URL location = org.python.pydev.debug.core.PydevDebugPlugin.getDefault().find(relative); *************** *** 112,118 **** --- 113,125 ---- // cmdArgs.add("-c"); // cmdArgs.add("-p"+Integer.toString(debugPort)); + // jpydebug cmdArgs.add(debugScript); + // cmdArgs.add("localhost"); + // cmdArgs.add(Integer.toString(debugPort)); cmdArgs.add(debugScript); + cmdArgs.add("--client"); cmdArgs.add("localhost"); + cmdArgs.add("--port"); cmdArgs.add(Integer.toString(debugPort)); + cmdArgs.add("--file"); } cmdArgs.add(file.toOSString()); |
From: Aleksandar T. <at...@us...> - 2004-04-22 10:56:25
|
Update of /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/ui In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18445/src/org/python/pydev/debug/ui Modified Files: PythonConsoleLineTracker.java Log Message: The beginning of the new debugger technology Index: PythonConsoleLineTracker.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/src/org/python/pydev/debug/ui/PythonConsoleLineTracker.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** PythonConsoleLineTracker.java 15 Apr 2004 23:24:49 -0000 1.3 --- PythonConsoleLineTracker.java 22 Apr 2004 10:56:16 -0000 1.4 *************** *** 6,9 **** --- 6,10 ---- package org.python.pydev.debug.ui; + import java.io.File; import java.util.regex.Matcher; import java.util.regex.Pattern; *************** *** 15,27 **** import org.eclipse.debug.ui.console.FileLink; import org.eclipse.debug.ui.console.IConsole; import org.eclipse.debug.ui.console.IConsoleLineTracker; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IRegion; import org.python.pydev.debug.core.PydevDebugPlugin; /** * Line tracker that hyperlinks error lines: 'File "D:\mybad.py" line 3\n n Syntax error' * ! * @see org.eclipse.ant.internal.ui.console.BuildFailedTracker */ public class PythonConsoleLineTracker implements IConsoleLineTracker { --- 16,32 ---- import org.eclipse.debug.ui.console.FileLink; import org.eclipse.debug.ui.console.IConsole; + import org.eclipse.debug.ui.console.IConsoleHyperlink; import org.eclipse.debug.ui.console.IConsoleLineTracker; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IRegion; import org.python.pydev.debug.core.PydevDebugPlugin; + import org.python.pydev.editor.actions.PyOpenAction; + import org.python.pydev.editor.model.ItemPointer; + import org.python.pydev.editor.model.Location; /** * Line tracker that hyperlinks error lines: 'File "D:\mybad.py" line 3\n n Syntax error' * ! * see org.eclipse.ant.internal.ui.console.BuildFailedTracker */ public class PythonConsoleLineTracker implements IConsoleLineTracker { *************** *** 30,33 **** --- 35,58 ---- /** pattern for detecting error lines */ static Pattern linePattern = Pattern.compile("\\s*File \\\"([^\\\"]*)\\\", line (\\d*).*"); + + /** + * Opens up a file with a given line + */ + public class ConsoleLink implements IConsoleHyperlink { + + ItemPointer pointer; + + public ConsoleLink(ItemPointer pointer) { + this.pointer = pointer; + } + + public void linkEntered() {} + public void linkExited() {} + + public void linkActivated() { + PyOpenAction open = new PyOpenAction(); + open.run(pointer); + } + } public void init(IConsole console) { *************** *** 59,74 **** int num = -1; try { ! num = lineNumber != null ? Integer.parseInt(lineNumber) : -1; } catch (NumberFormatException e) { } IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(new Path(fileName)); ! IFile file= null; ! if (files.length > 0) ! file= files[0]; ! if (file != null && file.exists()) { ! FileLink link = new FileLink(file, null, -1, -1, num); ! console.addLink(link, lineOffset + fileStart, lineLength - fileStart); } } } catch (BadLocationException e) { --- 84,105 ---- int num = -1; try { ! num = lineNumber != null ? Integer.parseInt(lineNumber) - 1: 0; } catch (NumberFormatException e) { + num = 0; } + IConsoleHyperlink link = null; IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(new Path(fileName)); ! if (files.length > 0 && files[0].exists()) ! link = new FileLink(files[0], null, -1, -1, num); ! else { // files outside of the workspace ! File realFile = new File(fileName); ! if (realFile.exists()) { ! ItemPointer p = new ItemPointer(realFile, new Location(num, 0), null); ! link = new ConsoleLink(p); ! } } + if (link != null) + console.addLink(link, lineOffset + fileStart, lineLength - fileStart); } } catch (BadLocationException e) { |
From: Aleksandar T. <at...@us...> - 2004-04-22 10:55:01
|
Update of /cvsroot/pydev/org.python.pydev.debug/pysrc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18122/pysrc Added Files: pydevd.py Log Message: pydevd is a python debugging daemon we'll interact with --- NEW FILE: pydevd.py --- """ pydevd - a debugging daemon This is the daemon you launch for python remote debugging. Protocol: each command has a format: id\tsequence-num\ttext id: protocol command number sequence-num: each request has a sequence number. Sequence numbers originating at the debugger are odd, sequence numbers originating at the daemon are even. Every response uses the same sequence number as the request. Commands: NUMBER NAME FROM* ARGUMENTS RESPONSE NOTE 100 series: program execution 101 RUN RDB - - 102 LIST_THREADS RDB RETURN with XML listing of all threads 103 THREAD_CREATED PYDB - XML with thread information 500 series: errors 501 ERROR either - This is reserved for unexpected errors. 900 series diagnostics/ok 901 VERSION either Version string (1.0) 902 RETURN either Depends on caller - * RDB - remote debugger, the java end * PYDB - pydevd, the python end """ import sys import threading import types from Queue import * from socket import * VERSION_STRING = "1.0" CMD_RUN = 101 CMD_LIST_THREADS = 102 CMD_THREAD_CREATED = 103 CMD_ERROR = 501 CMD_VERSION = 901 CMD_RETURN = 902 Debugger = None __all__ = (); _trace = 2 def log(level, s): """ levels are: 0 most serious warnings/errors 1 warnings/significant events 2 informational trace """ if (level <= _trace): print s class ReaderThread(threading.Thread): """ reader thread reads and dispatches commands in an infinite loop """ def __init__(self, sock): threading.Thread.__init__(self) self.sock = sock self.setName("pydevd.Reader") self.setDaemon(True) def run(self): buffer = "" while(True): buffer += self.sock.recv(1024) while (buffer.find('\n') != -1): [command, buffer] = buffer.split('\n', 1) log(2, "received command " + command) args = command.split('\t', 2) PyDB.instance.processNetCommand(int(args[0]), int(args[1]), args[2]) class WriterThread(threading.Thread): """ writer thread writes out the commands in an infinite loop """ def __init__(self, sock): threading.Thread.__init__(self) self.sock = sock self.setName("pydevd.Writer") self.setDaemon(True) self.cmdQueue = Queue() def addCommand(self, cmd): """ cmd is NetCommand """ self.cmdQueue.put(cmd) def run(self): """ just loop and write responses """ while(True): cmd = self.cmdQueue.get(1) log(2, "sending cmd " + cmd.getOutgoing()) self.sock.sendall(cmd.getOutgoing()) class NetCommand: """ Commands received/sent over the network. Command can represent command received from the debugger, or one to be sent by daemon. """ next_seq = 0 # sequence numbers def __init__(self, id, seq, text): """ smart handling of paramaters if sequence is 0, new sequence will be generated if text has carriage returns they'll be replaced""" self.id = id if (seq == 0): seq = self.getNextSeq() if text: text.replace("\n","\\n") # make sure we have no carriage returns self.seq = seq self.text = text self.outgoing = self.makeMessage(id, seq, text) def getNextSeq(self): """ returns next sequence number """ NetCommand.next_seq += 2 return NetCommand.next_seq def getOutgoing(self): """ returns the outgoing message""" return self.outgoing def makeMessage(self, cmd, seq, payload): return str(cmd) + '\t' + str(seq) + '\t' + str(payload)+ "\n" class NetCommandFactory: def __init_(self): self.next_seq = 0 def threadToXML(self, thread): """ thread information as XML """ cmdText = '<thread name="' + thread.getName() + '"' cmdText += ' id="' + str(id(thread)) + '" />' return cmdText def makeErrorMessage(self, seq, text): if (seq == 0): seq = getNextSeq() cmd = NetCommand(CMD_ERROR, seq, text) return cmd; def makeThreadCreatedMessage(self,thread): cmdText = "<xml>" + self.threadToXML(thread) + "</xml>" return NetCommand(CMD_THREAD_CREATED, 0, cmdText) def makeListThreadsMessage(self, seq): """ returns thread listing as XML """ try: t = threading.enumerate() cmdText = "<xml>" for i in t: cmdText += self.threadToXML(i) cmdText += "</xml>" return NetCommand(CMD_RETURN, seq, cmdText) except: return self.makeErrorMessage(self, seq, sys.exc_info()[0]) def makeVersionMessage(self, seq): try: return NetCommand(CMD_VERSION, seq, VERSION_STRING) except: return self.makeErrorMessage(self, seq, sys.exc_info()[0]) class PyDB: """ Main debugging class Lots of stuff going on here: PyDB starts two threads on startup that connect to remote debugger (RDB) The threads continuously read & write commands to RDB. PyDB communicates with these threads through command queues. Every RDB command is processed by calling processNetCommand. Every PyDB net command is sent to the net by posting NetCommand to WriterThread queue Some commands need to be executed on the right thread (suspend/resume & friends) These are placed on the internal command queue. """ instance = None def __init__(self): PyDB.instance = self self.reader = None self.writer = None self.quitting = None self.cmdFactory = NetCommandFactory() self.cmdQueue = {} def initializeNetwork(self, sock): sock.settimeout(None) # infinite, no timeouts from now on self.reader = ReaderThread(sock) self.reader.start() self.writer = WriterThread(sock) self.writer.start() def startServer(self, port): """ binds to a port, waits for the debugger to connect """ # TODO untested s = socket(AF_INET, SOCK_STREAM) s.bind(port) s.listen(1) newSock, addr = s.accept() self.initializeNetwork(newSock) def startClient(self, host, port): """ connects to a host/port """ log(1, "Connecting to " + host + ":" + str(port)) try: s = socket(AF_INET, SOCK_STREAM); s.settimeout(10) # seconds s.connect((host, port)) log(1, "Connected.") self.initializeNetwork(s) except timeout, e: print "server timed out after 10 seconds, could not connect to " + host + ":" + str(port) print "Exiting. Bye!" sys.exit(1) def connect(self, host, port): if (host): self.startClient(host, port) else: self.startServer(port) def processNetCommand(self, id, seq, text): cmd = None if (id == CMD_VERSION): # response is version number cmd = self.cmdFactory.makeVersionMessage(seq) elif (id == CMD_LIST_THREADS): # response is a list of threads cmd = self.cmdFactory.makeListThreadsMessage(seq) else: cmd = self.cmdFactory.makeErrorCommand(seq, "unexpected command " + str(id)) if cmd: self.writer.addCommand(cmd) def getQueueForThread(self, thread): """ returns intenal command queue for a given thread. if new queue is created, notify the RDB about it """ myID = id(thread) queue = None try: return self.cmdQueue[myID] except KeyError: self.cmdQueue[myID] = Queue() cmd = self.cmdFactory.makeThreadCreatedMessage(thread) print "found a new thread" self.writer.addCommand(cmd) return self.cmdQueue[myID] def processQueuedEvents(self, frame, event, arg): queue = self.getQueueForThread(threading.currentThread()) def trace_dispatch(self, frame, event, arg): self.processQueuedEvents(frame, event, arg) if self.quitting: return # None if event == 'line': return self.dispatch_line(frame) if event == 'call': return self.dispatch_call(frame, arg) if event == 'return': return self.dispatch_return(frame, arg) if event == 'exception': return self.dispatch_exception(frame, arg) print 'bdb.Bdb.dispatch: unknown debugging event:', `event` return self.trace_dispatch def dispatch_line(self, frame): print "L " + str(frame) return self.trace_dispatch def dispatch_call(self, frame, arg): print "C " + str(frame) + " " + str(arg) return self.trace_dispatch def dispatch_return(self, frame, arg): print "R " + str(frame) + " " + str(arg) return self.trace_dispatch def dispatch_exception(self, frame, arg): print "E " + str(frame) + " " + str(arg) return self.trace_dispatch def run(self, cmd, globals=None, locals=None): if globals is None: import __main__ globals = __main__.__dict__ if locals is None: locals = globals if not isinstance(cmd, types.CodeType): cmd = cmd+'\n' threading.settrace(self.trace_dispatch) # for all threads sys.settrace(self.trace_dispatch) # for this thread try: try: exec cmd in globals, locals except: print sys.stderr, "Debugger exiting with exception" raise finally: print "Quitting now" self.quitting = 1 def processCommandLine(argv): """ parses the arguments. removes our arguments from the command line """ retVal = {} retVal['client'] = '' retVal['server'] = False retVal['port'] = 0 retVal['file'] = '' i=0 del argv[0] while (i < len(argv)): if (argv[i] == '--port'): del argv[i] retVal['port'] = int(argv[i]) del argv[i] elif (argv[i] == '--client'): del argv[i] retVal['client'] = argv[i] del argv[i] elif (argv[i] == '--server'): del argv[i] retVal['server'] = True elif (argv[i] == '--file'): del argv[i] retVal['file'] = argv[i]; i = len(argv) # pop out, file is our last argument else: raise ValueError, "unexpected option " + argv[i] return retVal def usage(doExit=0): print 'Usage:' print 'pydevd.py --port=N [(--client hostname) | --server] --file executable [file_options]' if (doExit): sys.exit(0) def quittingNow(): log(1, "Exit function called. Bye") if __name__ == '__main__': print sys.stderr, "pydev debugger" # parse the command line. --file is our last argument that is required try: setup = processCommandLine(sys.argv) except ValueError, e: print e usage(1) log(2, "Executing file " + setup['file']) log(2, "arguments:" + str(sys.argv)) import atexit atexit.register(quittingNow) debugger = PyDB() debugger.connect(setup['client'], setup['port']) debugger.run('execfile(' + `setup['file']` + ')', None, None) |
Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/model In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14105/src/org/python/pydev/editor/model Modified Files: ItemPointer.java AbstractNode.java ModelUtils.java NameEqualsMainNode.java Scope.java ModuleNode.java ModelMaker.java Log Message: Lots of minor changes: double-clicking, more hyperlink navigation, making editor more useable. Moved some files here from debug, and pruned some obsolete ones. Index: NameEqualsMainNode.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/model/NameEqualsMainNode.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** NameEqualsMainNode.java 15 Apr 2004 23:19:21 -0000 1.2 --- NameEqualsMainNode.java 22 Apr 2004 10:35:22 -0000 1.3 *************** *** 18,23 **** super(parent); this.astNode = astNode; ! this.setStart(new Location(astNode.beginLine, astNode.beginColumn-1)); ! this.setEnd(new Location(astNode.beginLine, astNode.beginColumn + 22)); } --- 18,23 ---- super(parent); this.astNode = astNode; ! this.setStart(new Location(astNode.beginLine-1, astNode.beginColumn-1)); ! this.setEnd(new Location(astNode.beginLine-1, astNode.beginColumn + 22)); } Index: ModelMaker.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/model/ModelMaker.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ModelMaker.java 15 Apr 2004 23:19:21 -0000 1.2 --- ModelMaker.java 22 Apr 2004 10:35:22 -0000 1.3 *************** *** 6,10 **** package org.python.pydev.editor.model; ! import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.text.BadLocationException; --- 6,10 ---- package org.python.pydev.editor.model; ! import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.text.BadLocationException; *************** *** 26,30 **** * */ ! public static ModuleNode createModel(SimpleNode root, IDocument doc, IFile file) { int lastLine = doc.getNumberOfLines(); int lineLength = 255; --- 26,30 ---- * */ ! public static ModuleNode createModel(SimpleNode root, IDocument doc, IPath file) { int lastLine = doc.getNumberOfLines(); int lineLength = 255; Index: ModelUtils.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/model/ModelUtils.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ModelUtils.java 15 Apr 2004 23:19:21 -0000 1.2 --- ModelUtils.java 22 Apr 2004 10:35:22 -0000 1.3 *************** *** 11,19 **** import java.util.Iterator; - import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.python.pydev.plugin.PydevPlugin; --- 11,19 ---- import java.util.Iterator; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; + import org.python.parser.ast.Name; import org.python.pydev.plugin.PydevPlugin; *************** *** 177,180 **** --- 177,189 ---- } + public static Scope findEnclosingClassScope(AbstractNode node) { + if (node == null) + return null; + Scope s = node.getScope(); + while (s != null && !(s.getStartNode() instanceof ClassNode)) + s = s.getParent(); + return s; + } + /** * Finds where the given node is defined. *************** *** 184,188 **** */ public static ArrayList findDefinition(AbstractNode node) { - IFile file; ArrayList retVal = new ArrayList(); // simple function calls --- 193,196 ---- *************** *** 198,211 **** for (Iterator i = funcCalls.iterator(); i.hasNext();) { FunctionNode funcNode = (FunctionNode)i.next(); ! retVal.add(new ItemPointer(funcNode.getFile(), funcNode.getStart(), funcNode.getEnd())); } ! } else if (node instanceof ImportAlias) { // imports: // import sys ! File myImport = node.getScope().findImport(node.getName(), node.getFile()); if (myImport != null) retVal.add(new ItemPointer(myImport)); ! }else if (node instanceof AttributeNode) { // method calls. ex: self.break_here() } return retVal; --- 206,240 ---- for (Iterator i = funcCalls.iterator(); i.hasNext();) { FunctionNode funcNode = (FunctionNode)i.next(); ! retVal.add(new ItemPointer(funcNode.getPath(), funcNode.getStart(), funcNode.getEnd())); } ! } else if (node instanceof ImportAlias || node instanceof ImportFromNode) { // imports: // import sys ! File myImport = node.getScope().findImport(node.getName(), node.getPath()); if (myImport != null) retVal.add(new ItemPointer(myImport)); ! } else if (node instanceof AttributeNode && ! node.parent instanceof FunctionCallNode && ! ((AttributeNode)node).astNode.value instanceof Name && ! ((Name)((AttributeNode)node).astNode.value).id.equals("self")) ! { ! // self. method calls // method calls. ex: self.break_here() + // Find the function calls in the containing class that + Scope s = node.getScope(); + s = s.findContainingClass(); + if (s != null) { + ArrayList funcCalls = s.findFunctionCalls( + node.getName(), false, + new Comparator() { + public int compare(Object token, Object funcCall) { + return ((String)token).compareTo(((AbstractNode)funcCall).getName()); + }} + ); + for (Iterator i = funcCalls.iterator(); i.hasNext();) { + FunctionNode funcNode = (FunctionNode)i.next(); + retVal.add(new ItemPointer(funcNode.getPath(), funcNode.getStart(), funcNode.getEnd())); + } + } } return retVal; Index: Scope.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/model/Scope.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Scope.java 15 Apr 2004 23:19:21 -0000 1.2 --- Scope.java 22 Apr 2004 10:35:22 -0000 1.3 *************** *** 11,15 **** import java.util.Iterator; - import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IPath; import org.python.pydev.plugin.PydevPrefs; --- 11,14 ---- *************** *** 107,111 **** * @param name: function name * @param c: comparator to test for. ! * @return an ArrayList of ItemPointers to the function definitions. * each returned item will test as equal in c.compare(token, item); * null is never returned, there will be an empty array if none were found. --- 106,110 ---- * @param name: function name * @param c: comparator to test for. ! * @return an ArrayList of AbstractNode to the function/class definitions. * each returned item will test as equal in c.compare(token, item); * null is never returned, there will be an empty array if none were found. *************** *** 130,133 **** --- 129,135 ---- } } + if (start != null && start instanceof ClassNode) + // class name can also be a function call + retVal.add(start); // now traverse parents ArrayList ancestors = null; *************** *** 145,153 **** * @return an ordered ArrayList of File of all import paths for the project. */ ! private ArrayList getImportPaths(IFile startingPoint) { ArrayList retVal = new ArrayList(); // 1) the directory where the file is if (startingPoint != null) { ! IPath fileDir = startingPoint.getLocation().removeLastSegments(1); retVal.add(fileDir.toFile()); } --- 147,155 ---- * @return an ordered ArrayList of File of all import paths for the project. */ ! private ArrayList getImportPaths(IPath startingPoint) { ArrayList retVal = new ArrayList(); // 1) the directory where the file is if (startingPoint != null) { ! IPath fileDir = startingPoint.removeLastSegments(1); retVal.add(fileDir.toFile()); } *************** *** 165,169 **** * @return ArrayList of File objects that match. */ ! public File findImport(String name, IFile startAt) { ArrayList importPaths = getImportPaths(startAt); for (Iterator i= importPaths.iterator();i.hasNext();) { --- 167,171 ---- * @return ArrayList of File objects that match. */ ! public File findImport(String name, IPath startAt) { ArrayList importPaths = getImportPaths(startAt); for (Iterator i= importPaths.iterator();i.hasNext();) { *************** *** 175,177 **** --- 177,186 ---- return null; } + + public Scope findContainingClass() { + if (this.start instanceof ClassNode) + return this; + else + return parent != null ? parent.findContainingClass() : null; + } } Index: ItemPointer.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/model/ItemPointer.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ItemPointer.java 15 Apr 2004 23:19:21 -0000 1.1 --- ItemPointer.java 22 Apr 2004 10:35:22 -0000 1.2 *************** *** 7,18 **** /** ! * ! * TODO Comment this class */ public class ItemPointer { ! ! public Object file; // IFile or File... ! public Location start; ! public Location end; public ItemPointer(Object file) { --- 7,20 ---- /** ! * Pointer points to a python resource inside a file system. ! * ! * You can create one of these, and use PyOpenAction to open the ! * right editor. */ public class ItemPointer { ! ! public Object file; // IFile or File object ! public Location start; // (first character) ! public Location end; // (last character) public ItemPointer(Object file) { *************** *** 25,28 **** this.end = end; } - } --- 27,29 ---- Index: ModuleNode.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/model/ModuleNode.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ModuleNode.java 15 Apr 2004 23:19:21 -0000 1.2 --- ModuleNode.java 22 Apr 2004 10:35:22 -0000 1.3 *************** *** 6,10 **** package org.python.pydev.editor.model; ! import org.eclipse.core.resources.IFile; /** --- 6,10 ---- package org.python.pydev.editor.model; ! import org.eclipse.core.runtime.IPath; /** *************** *** 16,22 **** Scope scope; ! IFile file; ! public ModuleNode(IFile file, int lines, int cols) { super(null); scope = new Scope(this); --- 16,22 ---- Scope scope; ! IPath file; ! public ModuleNode(IPath file, int lines, int cols) { super(null); scope = new Scope(this); *************** *** 28,36 **** public String getName() { ! // TODO module needs a name, probably a file it comes from ! return "module"; } ! public IFile getFile() { return file; } --- 28,35 ---- public String getName() { ! return (file != null) ? file.lastSegment() : "module"; } ! public IPath getPath() { return file; } Index: AbstractNode.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/model/AbstractNode.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** AbstractNode.java 15 Apr 2004 23:19:21 -0000 1.2 --- AbstractNode.java 22 Apr 2004 10:35:22 -0000 1.3 *************** *** 8,12 **** import java.util.ArrayList; ! import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IStatus; import org.python.pydev.plugin.PydevPlugin; --- 8,12 ---- import java.util.ArrayList; ! import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.python.pydev.plugin.PydevPlugin; *************** *** 101,106 **** public abstract String getName(); ! public IFile getFile() { ! return parent.getFile(); } --- 101,106 ---- public abstract String getName(); ! public IPath getPath() { ! return parent.getPath(); } |
From: Aleksandar T. <at...@us...> - 2004-04-22 10:35:34
|
Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/dictionary In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14105/src/org/python/pydev/editor/dictionary Removed Files: package.html Log Message: Lots of minor changes: double-clicking, more hyperlink navigation, making editor more useable. Moved some files here from debug, and pruned some obsolete ones. --- package.html DELETED --- |
From: Aleksandar T. <at...@us...> - 2004-04-22 10:35:34
|
Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/plugin In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14105/src/org/python/pydev/plugin Modified Files: PydevPlugin.java PydevPrefs.java Log Message: Lots of minor changes: double-clicking, more hyperlink navigation, making editor more useable. Moved some files here from debug, and pruned some obsolete ones. Index: PydevPlugin.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/plugin/PydevPlugin.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** PydevPlugin.java 8 Jan 2004 22:40:33 -0000 1.4 --- PydevPlugin.java 22 Apr 2004 10:35:23 -0000 1.5 *************** *** 35,39 **** super.startup(); try { ! resourceBundle= ResourceBundle.getBundle("org.python.pydev.PydevPluginResources"); } catch (MissingResourceException x) { resourceBundle = null; --- 35,39 ---- super.startup(); try { ! resourceBundle= ResourceBundle.getBundle("org.python.pydev.PyDevPluginResources"); } catch (MissingResourceException x) { resourceBundle = null; Index: PydevPrefs.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/plugin/PydevPrefs.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** PydevPrefs.java 15 Apr 2004 23:19:22 -0000 1.5 --- PydevPrefs.java 22 Apr 2004 10:35:24 -0000 1.6 *************** *** 48,51 **** --- 48,53 ---- public static final String INTERPRETER_PATH = "INTERPRETER_PATH"; protected static final String DEFAULT_INTERPRETER_PATH = "python"; + public static final String HYPERLINK_COLOR = "HYPERLINK_COLOR"; + private static final RGB DEFAULT_HYPERLINK_COLOR = new RGB(0, 0, 238); /** *************** *** 103,106 **** --- 105,109 ---- prefs.setDefault(STRING_COLOR,StringConverter.asString(DEFAULT_STRING_COLOR)); prefs.setDefault(COMMENT_COLOR,StringConverter.asString(DEFAULT_COMMENT_COLOR)); + prefs.setDefault(HYPERLINK_COLOR, StringConverter.asString(DEFAULT_HYPERLINK_COLOR)); } } |
From: Aleksandar T. <at...@us...> - 2004-04-22 10:35:34
|
Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/actions In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14105/src/org/python/pydev/editor/actions Modified Files: PyOpenAction.java Log Message: Lots of minor changes: double-clicking, more hyperlink navigation, making editor more useable. Moved some files here from debug, and pruned some obsolete ones. Index: PyOpenAction.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/actions/PyOpenAction.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyOpenAction.java 15 Apr 2004 23:19:21 -0000 1.1 --- PyOpenAction.java 22 Apr 2004 10:35:24 -0000 1.2 *************** *** 62,67 **** } catch (PartInitException e) { PydevPlugin.log(IStatus.ERROR, "Unexpected error opening file", e); - } catch (BadLocationException e1) { - PydevPlugin.log(IStatus.ERROR, "Error setting selection", e1); } } --- 62,65 ---- *************** *** 77,80 **** --- 75,83 ---- try { IEditorPart editor = p.openEditor(input, desc.getId()); + if (start != null && + editor instanceof ITextEditor) { + ITextEditor textEdit = (ITextEditor)editor; + showInEditor(textEdit, start, end); + } } catch (PartInitException e) { PydevPlugin.log(IStatus.ERROR, "Unexpected error opening external file", e); *************** *** 82,93 **** } ! private void showInEditor(ITextEditor textEdit, Location start, Location end) ! throws BadLocationException { ! IDocument doc = textEdit.getDocumentProvider().getDocument(textEdit.getEditorInput()); ! int s; s = start.toOffset(doc); ! int e = end == null ? s : end.toOffset(doc); ! TextSelection sel = new TextSelection(s, e - s); ! textEdit.getSelectionProvider().setSelection(sel); } --- 85,104 ---- } ! private void showInEditor( ! ITextEditor textEdit, ! Location start, ! Location end) { ! try { ! IDocument doc = ! textEdit.getDocumentProvider().getDocument( ! textEdit.getEditorInput()); ! int s; s = start.toOffset(doc); ! int e = end == null ? s : end.toOffset(doc); ! TextSelection sel = new TextSelection(s, e - s); ! textEdit.getSelectionProvider().setSelection(sel); ! } catch (BadLocationException e1) { ! PydevPlugin.log(IStatus.ERROR, "Error setting selection", e1); ! } } |
From: Aleksandar T. <at...@us...> - 2004-04-22 10:35:33
|
Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14105/src/org/python/pydev/editor Modified Files: PyAutoIndentStrategy.java Hyperlink.java PyDoubleClickStrategy.java PyEditConfiguration.java PyEdit.java Log Message: Lots of minor changes: double-clicking, more hyperlink navigation, making editor more useable. Moved some files here from debug, and pruned some obsolete ones. Index: PyAutoIndentStrategy.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/PyAutoIndentStrategy.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PyAutoIndentStrategy.java 8 Jan 2004 22:41:38 -0000 1.2 --- PyAutoIndentStrategy.java 22 Apr 2004 10:35:23 -0000 1.3 *************** *** 32,35 **** --- 32,43 ---- this.forceTabs = forceTabs; } + + private String createSpaceString(int width) { + StringBuffer b = new StringBuffer(width); + while (tabWidth-- > 0) + b.append(" "); + return b.toString(); + } + /** returns correct single-step indentation */ private String getIndentationString() { *************** *** 40,49 **** tabWidth = PydevPrefs.getPreferences().getInt(PydevPrefs.TAB_WIDTH); useSpaces = PydevPrefs.getPreferences().getBoolean(PydevPrefs.SUBSTITUTE_TABS); ! if (useSpaces && !forceTabs) { ! StringBuffer b = new StringBuffer(tabWidth); ! while (tabWidth-- > 0) ! b.append(" "); ! identString = b.toString(); ! } else identString = "\t"; } --- 48,54 ---- tabWidth = PydevPrefs.getPreferences().getInt(PydevPrefs.TAB_WIDTH); useSpaces = PydevPrefs.getPreferences().getBoolean(PydevPrefs.SUBSTITUTE_TABS); ! if (useSpaces && !forceTabs) ! identString = createSpaceString(tabWidth); ! else identString = "\t"; } *************** *** 63,73 **** * tab location * - * @param document - * @param length - * @param text - * @param offset - * @param indentString - * @return String - * @throws BadLocationException */ protected String convertTabs( --- 68,71 ---- *************** *** 104,107 **** --- 102,117 ---- return text; } + + /** + * Converts spaces to strings. Useful when pasting + */ + protected String convertSpaces( + IDocument document, int length, String text, int offset, + String indentString) throws BadLocationException + { + if (text.length() > 2) + return text; + return text.replaceAll(createSpaceString(tabWidth), "\t"); + } /** *************** *** 173,176 **** --- 183,189 ---- document, command.length, command.text, command.offset, getIndentationString()); + else command.text = convertSpaces( + document, command.length, command.text, command.offset, + getIndentationString()); } catch (BadLocationException e) { e.printStackTrace(); Index: PyEditConfiguration.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/PyEditConfiguration.java,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** PyEditConfiguration.java 15 Apr 2004 23:19:21 -0000 1.8 --- PyEditConfiguration.java 22 Apr 2004 10:35:23 -0000 1.9 *************** *** 86,90 **** if (autoIndentStrategy == null) autoIndentStrategy = new PyAutoIndentStrategy(); ! return autoIndentStrategy; } --- 86,93 ---- if (autoIndentStrategy == null) autoIndentStrategy = new PyAutoIndentStrategy(); ! if (contentType == null || contentType.equals(IDocument.DEFAULT_CONTENT_TYPE)) ! return autoIndentStrategy; ! else ! return super.getAutoIndentStrategy(sourceViewer, contentType); } *************** *** 186,190 **** "if","import","in","is","lambda","not", "or","pass","print","raise","return", ! "try","while","yield","None" }; public GreatKeywordDetector() { --- 189,193 ---- "if","import","in","is","lambda","not", "or","pass","print","raise","return", ! "try","while","yield","False", "None", "True" }; public GreatKeywordDetector() { *************** *** 280,290 **** // next create a content assistant processor to populate the completions window IContentAssistProcessor processor = new PythonCompletionProcessor(); ! assistant.setContentAssistProcessor(processor,PyPartitionScanner.PY_SINGLELINE_STRING ); ! assistant.setContentAssistProcessor(processor,PyPartitionScanner.PY_MULTILINE_STRING ); assistant.setContentAssistProcessor(processor,IDocument.DEFAULT_CONTENT_TYPE ); assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer)); // Allow automatic activation after 500 msec ! assistant.enableAutoActivation(true); ! assistant.setAutoActivationDelay(500); Color bgColor = colorCache.getColor(new RGB(230,255,230)); assistant.setProposalSelectorBackground(bgColor); --- 283,294 ---- // next create a content assistant processor to populate the completions window IContentAssistProcessor processor = new PythonCompletionProcessor(); ! // No code completion in strings ! // assistant.setContentAssistProcessor(processor,PyPartitionScanner.PY_SINGLELINE_STRING ); ! // assistant.setContentAssistProcessor(processor,PyPartitionScanner.PY_MULTILINE_STRING ); assistant.setContentAssistProcessor(processor,IDocument.DEFAULT_CONTENT_TYPE ); assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer)); // Allow automatic activation after 500 msec ! // assistant.enableAutoActivation(true); ! // assistant.setAutoActivationDelay(500); Color bgColor = colorCache.getColor(new RGB(230,255,230)); assistant.setProposalSelectorBackground(bgColor); Index: PyEdit.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/PyEdit.java,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** PyEdit.java 15 Apr 2004 23:19:21 -0000 1.12 --- PyEdit.java 22 Apr 2004 10:35:23 -0000 1.13 *************** *** 12,16 **** --- 12,18 ---- import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; + import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; + import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Preferences; *************** *** 25,28 **** --- 27,31 ---- import org.eclipse.ui.IEditorSite; import org.eclipse.ui.IFileEditorInput; + import org.eclipse.ui.IStorageEditorInput; import org.eclipse.ui.PartInitException; import org.eclipse.ui.editors.text.TextEditor; *************** *** 94,98 **** editConfiguration = new PyEditConfiguration(colorCache); setSourceViewerConfiguration(editConfiguration); ! indentStrategy = (PyAutoIndentStrategy)editConfiguration.getAutoIndentStrategy(null, null); setRangeIndicator(new DefaultRangeIndicator()); // enables standard vertical ruler --- 97,101 ---- editConfiguration = new PyEditConfiguration(colorCache); setSourceViewerConfiguration(editConfiguration); ! indentStrategy = (PyAutoIndentStrategy)editConfiguration.getAutoIndentStrategy(null, IDocument.DEFAULT_CONTENT_TYPE); setRangeIndicator(new DefaultRangeIndicator()); // enables standard vertical ruler *************** *** 250,255 **** return; // nothing to see here boolean wholeLine = false; - // if (node instanceof ImportNode) - // wholeLine = true; Location start = node.getStart(); Location end = node.getEnd(); --- 253,256 ---- *************** *** 282,299 **** // Remove all the error markers IEditorInput input = getEditorInput(); ! IFile original= (input instanceof IFileEditorInput) ? ((IFileEditorInput) input).getFile() : null; try { ! if (original != null) ! original.deleteMarkers(IMarker.PROBLEM, false, 1); } catch (CoreException e) { // What bad can come from removing markers? Ignore this exception PydevPlugin.log(IStatus.WARNING, "Unexpected error removing markers", e); } ! IDocument document = getDocumentProvider().getDocument(getEditorInput()); int lastLine = document.getNumberOfLines(); IRegion r; try { r = document.getLineInformation(lastLine-1); ! pythonModel = ModelMaker.createModel(root, document, original); fireModelChanged(pythonModel); } catch (BadLocationException e1) { --- 283,310 ---- // Remove all the error markers IEditorInput input = getEditorInput(); ! IPath filePath = null; ! if (input instanceof IStorageEditorInput) ! try { ! filePath = ((IStorageEditorInput)input).getStorage().getFullPath(); ! } catch (CoreException e2) { ! PydevPlugin.log(IStatus.ERROR, "unexpected error getting path", e2); ! } ! else ! PydevPlugin.log(IStatus.ERROR, "unexpected type of editor input " + input.getClass().toString(), null); ! try { ! IResource res = (IResource) input.getAdapter(IResource.class); ! if (res != null) ! res.deleteMarkers(IMarker.PROBLEM, false, 1); } catch (CoreException e) { // What bad can come from removing markers? Ignore this exception PydevPlugin.log(IStatus.WARNING, "Unexpected error removing markers", e); } ! IDocument document = getDocumentProvider().getDocument(input); int lastLine = document.getNumberOfLines(); IRegion r; try { r = document.getLineInformation(lastLine-1); ! pythonModel = ModelMaker.createModel(root, document, filePath); fireModelChanged(pythonModel); } catch (BadLocationException e1) { *************** *** 374,378 **** private void enableBrowserLikeLinks() { if (fMouseListener == null) { ! fMouseListener= new Hyperlink(getSourceViewer(), this); fMouseListener.install(); } --- 385,389 ---- private void enableBrowserLikeLinks() { if (fMouseListener == null) { ! fMouseListener= new Hyperlink(getSourceViewer(), this, colorCache); fMouseListener.install(); } Index: PyDoubleClickStrategy.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/PyDoubleClickStrategy.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyDoubleClickStrategy.java 15 Apr 2004 23:19:21 -0000 1.1 --- PyDoubleClickStrategy.java 22 Apr 2004 10:35:23 -0000 1.2 *************** *** 6,16 **** package org.python.pydev.editor; ! import org.eclipse.jdt.internal.ui.text.JavaPairMatcher; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextDoubleClickStrategy; import org.eclipse.jface.text.ITextViewer; /** --- 6,20 ---- package org.python.pydev.editor; ! import java.io.IOException; ! import java.io.Reader; ! import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; + import org.eclipse.jface.text.Region; import org.eclipse.jface.text.ITextDoubleClickStrategy; import org.eclipse.jface.text.ITextViewer; + import org.eclipse.jface.text.source.ICharacterPairMatcher; /** *************** *** 22,26 **** --- 26,454 ---- protected static final char[] BRACKETS = { '{', '}', '(', ')', '[', ']' }; + + + public class JavaCodeReader extends Reader { + + /** The EOF character */ + public static final int EOF= -1; + + private boolean fSkipComments= false; + private boolean fSkipStrings= false; + private boolean fForward= false; + + private IDocument fDocument; + private int fOffset; + + private int fEnd= -1; + private int fCachedLineNumber= -1; + private int fCachedLineOffset= -1; + + + public int read(char cbuf[], int off, int len) throws IOException { + int end= off + len; + for (int i= off; i < end; i++) { + int ch= read(); + if (ch == -1) { + if (i == off) { + return -1; + } else { + return i - off; + } + } + cbuf[i]= (char)ch; + } + return len; + } + + /** + * @see Reader#ready() + */ + public boolean ready() throws IOException { + return true; + } + + /** + * Gets the content as a String + */ + public String getString() throws IOException { + StringBuffer buf= new StringBuffer(); + int ch; + while ((ch= read()) != -1) { + buf.append((char)ch); + } + return buf.toString(); + } + public JavaCodeReader() { + } + + /** + * Returns the offset of the last read character. Should only be called after read has been called. + */ + public int getOffset() { + return fForward ? fOffset -1 : fOffset; + } + + public void configureForwardReader(IDocument document, int offset, int length, boolean skipComments, boolean skipStrings) throws IOException { + fDocument= document; + fOffset= offset; + fSkipComments= skipComments; + fSkipStrings= skipStrings; + + fForward= true; + fEnd= Math.min(fDocument.getLength(), fOffset + length); + } + + public void configureBackwardReader(IDocument document, int offset, boolean skipComments, boolean skipStrings) throws IOException { + fDocument= document; + fOffset= offset; + fSkipComments= skipComments; + fSkipStrings= skipStrings; + + fForward= false; + try { + fCachedLineNumber= fDocument.getLineOfOffset(fOffset); + } catch (BadLocationException x) { + throw new IOException(x.getMessage()); + } + } + + /* + * @see Reader#close() + */ + public void close() throws IOException { + fDocument= null; + } + + /* + * @see SingleCharReader#read() + */ + public int read() throws IOException { + try { + return fForward ? readForwards() : readBackwards(); + } catch (BadLocationException x) { + throw new IOException(x.getMessage()); + } + } + + private void gotoCommentEnd() throws BadLocationException { + while (fOffset < fEnd) { + char current= fDocument.getChar(fOffset++); + if (current == '*') { + if (fOffset < fEnd && fDocument.getChar(fOffset) == '/') { + ++ fOffset; + return; + } + } + } + } + + private void gotoStringEnd(char delimiter) throws BadLocationException { + while (fOffset < fEnd) { + char current= fDocument.getChar(fOffset++); + if (current == '\\') { + // ignore escaped characters + ++ fOffset; + } else if (current == delimiter) { + return; + } + } + } + + private void gotoLineEnd() throws BadLocationException { + int line= fDocument.getLineOfOffset(fOffset); + fOffset= fDocument.getLineOffset(line + 1); + } + + private int readForwards() throws BadLocationException { + while (fOffset < fEnd) { + char current= fDocument.getChar(fOffset++); + + switch (current) { + case '/': + + if (fSkipComments && fOffset < fEnd) { + char next= fDocument.getChar(fOffset); + if (next == '*') { + // a comment starts, advance to the comment end + ++ fOffset; + gotoCommentEnd(); + continue; + } else if (next == '/') { + // '//'-comment starts, advance to the line end + gotoLineEnd(); + continue; + } + } + + return current; + + case '"': + case '\'': + + if (fSkipStrings) { + gotoStringEnd(current); + continue; + } + + return current; + } + + return current; + } + + return EOF; + } + + private void handleSingleLineComment() throws BadLocationException { + int line= fDocument.getLineOfOffset(fOffset); + if (line < fCachedLineNumber) { + fCachedLineNumber= line; + fCachedLineOffset= fDocument.getLineOffset(line); + int offset= fOffset; + while (fCachedLineOffset < offset) { + char current= fDocument.getChar(offset--); + if (current == '/' && fCachedLineOffset <= offset && fDocument.getChar(offset) == '/') { + fOffset= offset; + return; + } + } + } + } + + private void gotoCommentStart() throws BadLocationException { + while (0 < fOffset) { + char current= fDocument.getChar(fOffset--); + if (current == '*' && 0 <= fOffset && fDocument.getChar(fOffset) == '/') + return; + } + } + + private void gotoStringStart(char delimiter) throws BadLocationException { + while (0 < fOffset) { + char current= fDocument.getChar(fOffset); + if (current == delimiter) { + if ( !(0 <= fOffset && fDocument.getChar(fOffset -1) == '\\')) + return; + } + -- fOffset; + } + } + + private int readBackwards() throws BadLocationException { + + while (0 < fOffset) { + -- fOffset; + + handleSingleLineComment(); + + char current= fDocument.getChar(fOffset); + switch (current) { + case '/': + + if (fSkipComments && fOffset > 1) { + char next= fDocument.getChar(fOffset - 1); + if (next == '*') { + // a comment ends, advance to the comment start + fOffset -= 2; + gotoCommentStart(); + continue; + } + } + + return current; + + case '"': + case '\'': + + if (fSkipStrings) { + -- fOffset; + gotoStringStart(current); + continue; + } + + return current; + } + + return current; + } + + return EOF; + } + }; + + + /** + * swiped an internal class straight out of Java code + * it was originaly org.eclipse.jdt.internal.ui.text.JavaPairMatcher + */ + public class JavaPairMatcher implements ICharacterPairMatcher { + + protected char[] fPairs; + protected IDocument fDocument; + protected int fOffset; + + protected int fStartPos; + protected int fEndPos; + protected int fAnchor; + + protected JavaCodeReader fReader= new JavaCodeReader(); + + + public JavaPairMatcher(char[] pairs) { + fPairs= pairs; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.source.ICharacterPairMatcher#match(org.eclipse.jface.text.IDocument, int) + */ + public IRegion match(IDocument document, int offset) { + fOffset= offset; + + if (fOffset < 0) + return null; + + fDocument= document; + + if (fDocument != null && matchPairsAt() && fStartPos != fEndPos) + return new Region(fStartPos, fEndPos - fStartPos + 1); + + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.source.ICharacterPairMatcher#getAnchor() + */ + public int getAnchor() { + return fAnchor; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.source.ICharacterPairMatcher#dispose() + */ + public void dispose() { + clear(); + fDocument= null; + fReader= null; + } + + /* + * @see org.eclipse.jface.text.source.ICharacterPairMatcher#clear() + */ + public void clear() { + if (fReader != null) { + try { + fReader.close(); + } catch (IOException x) { + // ignore + } + } + } + + protected boolean matchPairsAt() { + + int i; + int pairIndex1= fPairs.length; + int pairIndex2= fPairs.length; + + fStartPos= -1; + fEndPos= -1; + + // get the chars preceding and following the start position + try { + + char prevChar= fDocument.getChar(Math.max(fOffset - 1, 0)); + // modified behavior for http://dev.eclipse.org/bugs/show_bug.cgi?id=16879 + // char nextChar= fDocument.getChar(fOffset); + + // search for opening peer character next to the activation point + for (i= 0; i < fPairs.length; i= i + 2) { + // if (nextChar == fPairs[i]) { + // fStartPos= fOffset; + // pairIndex1= i; + // } else + if (prevChar == fPairs[i]) { + fStartPos= fOffset - 1; + pairIndex1= i; + } + } + + // search for closing peer character next to the activation point + for (i= 1; i < fPairs.length; i= i + 2) { + if (prevChar == fPairs[i]) { + fEndPos= fOffset - 1; + pairIndex2= i; + } + // else if (nextChar == fPairs[i]) { + // fEndPos= fOffset; + // pairIndex2= i; + // } + } + + if (fEndPos > -1) { + fAnchor= RIGHT; + fStartPos= searchForOpeningPeer(fEndPos, fPairs[pairIndex2 - 1], fPairs[pairIndex2], fDocument); + if (fStartPos > -1) + return true; + else + fEndPos= -1; + } else if (fStartPos > -1) { + fAnchor= LEFT; + fEndPos= searchForClosingPeer(fStartPos, fPairs[pairIndex1], fPairs[pairIndex1 + 1], fDocument); + if (fEndPos > -1) + return true; + else + fStartPos= -1; + } + + } catch (BadLocationException x) { + } catch (IOException x) { + } + + return false; + } + + protected int searchForClosingPeer(int offset, int openingPeer, int closingPeer, IDocument document) throws IOException { + + fReader.configureForwardReader(document, offset + 1, document.getLength(), true, true); + + int stack= 1; + int c= fReader.read(); + while (c != JavaCodeReader.EOF) { + if (c == openingPeer && c != closingPeer) + stack++; + else if (c == closingPeer) + stack--; + + if (stack == 0) + return fReader.getOffset(); + + c= fReader.read(); + } + + return -1; + } + + protected int searchForOpeningPeer(int offset, int openingPeer, int closingPeer, IDocument document) throws IOException { + + fReader.configureBackwardReader(document, offset, true, true); + + int stack= 1; + int c= fReader.read(); + while (c != JavaCodeReader.EOF) { + if (c == closingPeer && c != openingPeer) + stack++; + else if (c == openingPeer) + stack--; + + if (stack == 0) + return fReader.getOffset(); + + c= fReader.read(); + } + + return -1; + } + } protected JavaPairMatcher fPairMatcher = new JavaPairMatcher(BRACKETS); Index: Hyperlink.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/Hyperlink.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Hyperlink.java 15 Apr 2004 23:19:21 -0000 1.2 --- Hyperlink.java 22 Apr 2004 10:35:23 -0000 1.3 *************** *** 10,15 **** import org.eclipse.core.runtime.IStatus; - import org.eclipse.jdt.internal.ui.JavaPlugin; - import org.eclipse.jdt.ui.PreferenceConstants; import org.eclipse.jface.action.Action; import org.eclipse.jface.preference.IPreferenceStore; --- 10,13 ---- *************** *** 27,32 **** import org.eclipse.jface.text.Region; import org.eclipse.jface.text.source.ISourceViewer; - import org.eclipse.jface.util.IPropertyChangeListener; - import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyleRange; --- 25,28 ---- *************** *** 54,57 **** --- 50,55 ---- import org.python.pydev.editor.model.ModelUtils; import org.python.pydev.plugin.PydevPlugin; + import org.python.pydev.plugin.PydevPrefs; + import org.python.pydev.ui.ColorCache; /** *************** *** 61,65 **** */ public class Hyperlink implements KeyListener, MouseListener, MouseMoveListener, ! FocusListener, PaintListener, IPropertyChangeListener, IDocumentListener, ITextInputListener { /** The session is active. */ --- 59,63 ---- */ public class Hyperlink implements KeyListener, MouseListener, MouseMoveListener, ! FocusListener, PaintListener, IDocumentListener, ITextInputListener { /** The session is active. */ *************** *** 78,81 **** --- 76,81 ---- private int fKeyModifierMask; + private ColorCache fColorCache; + /************ * ALEKS ADDITIONS *************** *** 85,104 **** private AbstractNode fClickedNode; ! public Hyperlink(ISourceViewer sourceViewer, PyEdit editor) { fSourceViewer = sourceViewer; fEditor = editor; } private ISourceViewer getSourceViewer() { return fSourceViewer; ! } ! ! IPreferenceStore fPrefStore = null; ! ! public IPreferenceStore getPreferenceStore() { ! if (fPrefStore == null) ! fPrefStore = JavaPlugin.getDefault().getPreferenceStore(); ! return fPrefStore; ! } public void deactivate() { --- 85,98 ---- private AbstractNode fClickedNode; ! public Hyperlink(ISourceViewer sourceViewer, PyEdit editor, ColorCache colorCache) { fSourceViewer = sourceViewer; fEditor = editor; + fKeyModifierMask = SWT.CTRL; + fColorCache = colorCache; } private ISourceViewer getSourceViewer() { return fSourceViewer; ! } public void deactivate() { *************** *** 137,154 **** text.addFocusListener(this); text.addPaintListener(this); - - updateKeyModifierMask(); - - IPreferenceStore preferenceStore= getPreferenceStore(); - preferenceStore.addPropertyChangeListener(this); - } - - private void updateKeyModifierMask() { - String modifiers= getPreferenceStore().getString(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK); - fKeyModifierMask= computeStateMask(modifiers); - if (fKeyModifierMask == -1) { - // Fallback to stored state mask - fKeyModifierMask= getPreferenceStore().getInt(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK); - }; } --- 131,134 ---- *************** *** 192,199 **** if (document != null) document.removeDocumentListener(this); - - IPreferenceStore preferenceStore= getPreferenceStore(); - if (preferenceStore != null) - preferenceStore.removePropertyChangeListener(this); StyledText text= sourceViewer.getTextWidget(); --- 172,175 ---- *************** *** 207,227 **** text.removePaintListener(this); } - - /* - * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent) - */ - public void propertyChange(PropertyChangeEvent event) { - if (event.getProperty().equals(PreferenceConstants.EDITOR_LINK_COLOR)) { - ISourceViewer viewer= getSourceViewer(); - if (viewer != null) - updateColor(viewer); - } else if (event.getProperty().equals(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER)) { - updateKeyModifierMask(); - } - } private void updateColor(ISourceViewer viewer) { - if (fColor != null) - fColor.dispose(); StyledText text= viewer.getTextWidget(); --- 183,188 ---- *************** *** 229,234 **** return; ! Display display= text.getDisplay(); ! fColor= createColor(getPreferenceStore(), PreferenceConstants.EDITOR_LINK_COLOR, display); } --- 190,194 ---- return; ! fColor = fColorCache.getNamedColor(PydevPrefs.HYPERLINK_COLOR); } |