Small bug fixes for the debugger client.
[phpeclipse.git] / net.sourceforge.phpeclipse.debug.core / src / net / sourceforge / phpdt / internal / debug / core / model / PHPThread.java
index 2aad677..231119a 100644 (file)
@@ -1,16 +1,18 @@
 /**********************************************************************
-Copyright (c) 2000, 2002 IBM Corp. and others.
-All rights reserved. This program and the accompanying materials
-are made available under the terms of the Common Public License v1.0
-which accompanies this distribution, and is available at
-http://www.eclipse.org/legal/cpl-v10.html
-
-Contributors:
-    IBM Corporation - Initial implementation
-    Vicente Fernando - www.alfersoft.com.ar
-**********************************************************************/
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ Vicente Fernando - www.alfersoft.com.ar
+ **********************************************************************/
 package net.sourceforge.phpdt.internal.debug.core.model;
 
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
 import org.eclipse.debug.core.DebugEvent;
 import org.eclipse.debug.core.DebugException;
 import org.eclipse.debug.core.DebugPlugin;
@@ -19,21 +21,64 @@ 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;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.model.IWorkbenchAdapter;
 
 public class PHPThread implements IThread {
 
        private PHPStackFrame[] frames;
+
        private IDebugTarget target;
-       private boolean isSuspended = false;
-       private boolean isTerminated = false;
-       private boolean isStepping = false;
-       private String name ;
-       private int id ;
-       
+
+       private String name;
+
+       private int id;
+
+       private class State {
+               private boolean isSuspended = false;
+
+               private boolean isTerminated = false;
+
+               private boolean isStepping = false;
+
+               boolean isSuspended() {
+                       return isSuspended;
+               }
+
+               boolean isTerminated() {
+                       return isTerminated;
+               }
+
+               boolean isStepping() {
+                       return isStepping;
+               }
+
+               void setSuspended(boolean suspended) {
+                       if (isTerminated())
+                               throw new IllegalStateException();
+                       if (suspended && isStepping())
+                               throw new IllegalStateException();
+                       isSuspended = suspended;
+               }
+
+               void setStepping(boolean stepping) {
+                       if (stepping && !isSuspended())
+                               throw new IllegalStateException();
+                       if (isTerminated())
+                               throw new IllegalStateException();
+                       isStepping = stepping;
+               }
+
+               void setTerminated(boolean terminated) {
+                       isTerminated = terminated;
+               }
+       }
+
+       private final State state = new State();
+
        public PHPThread(IDebugTarget target, int id) {
                this.target = target;
-               this.setId(id) ;
-               this.createName() ;
+               this.setId(id);
        }
 
        public IStackFrame[] getStackFrames() throws DebugException {
@@ -62,7 +107,6 @@ public class PHPThread implements IThread {
                return (IStackFrame) frames[0];
        }
 
-
        public IBreakpoint[] getBreakpoints() {
                return null;
        }
@@ -76,105 +120,138 @@ public class PHPThread implements IThread {
        }
 
        public void setDebugTarget(IDebugTarget target) {
-               this.target= target;
+               this.target = target;
        }
-       
+
        public ILaunch getLaunch() {
                return this.getDebugTarget().getLaunch();
        }
 
-       public boolean canResume() {
-               return isSuspended;
+       public synchronized boolean canResume() {
+               return isSuspended();
        }
 
-       public boolean canSuspend() {
-               return !isSuspended;
+       public synchronized boolean canSuspend() {
+               return !isSuspended();
        }
 
-       public boolean isSuspended() {
-               return isSuspended;
-       }
-
-       protected void setSuspended(boolean isSuspended) {
-               this.isSuspended = isSuspended;
+       public synchronized boolean isSuspended() {
+               return state.isSuspended;
        }
 
        protected void prepareForResume() {
-               isSuspended = false;
-               this.createName() ;
-               this.frames = null ;
-               DebugEvent ev = new DebugEvent(this, DebugEvent.RESUME, DebugEvent.CLIENT_REQUEST);
-               DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev });            
+               state.setSuspended(false);
+               this.frames = null;
+               DebugEvent ev = new DebugEvent(this, DebugEvent.RESUME,
+                               DebugEvent.CLIENT_REQUEST);
+               DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev });
        }
 
-       public void resume() throws DebugException {
-               this.prepareForResume() ;
-               ((PHPDebugTarget) this.getDebugTarget()).getPHPDBGProxy().resume(this);
+       public synchronized void resume() throws DebugException {
+               if (!isSuspended())
+                       return;
+               this.prepareForResume();
+               ((PHPDebugTarget) this.getDebugTarget()).getPHPDBGProxy().resume();
        }
 
        /*
-       public void doSuspend(SuspensionPoint suspensionPoint) {
-//             this.getPHPDebuggerProxy().readFrames(this);
-               this.createName(suspensionPoint) ;
-               this.suspend() ;
-       }
-       */
-
-       public void suspend()  {
-               isStepping = false;
-               isSuspended = true;
-               DebugEvent ev = new DebugEvent(this, DebugEvent.SUSPEND, DebugEvent.BREAKPOINT);
+        * public void doSuspend(SuspensionPoint suspensionPoint) { //
+        * this.getPHPDebuggerProxy().readFrames(this);
+        * this.createName(suspensionPoint) ; this.suspend() ; }
+        */
+
+       public synchronized void suspend() throws DebugException {
+               if (isSuspended())
+                       return;
+               state.setSuspended(true);
+               state.setStepping(false);
+               getDebugTarget().suspend();
+               DebugEvent ev = new DebugEvent(this, DebugEvent.SUSPEND,
+                               DebugEvent.BREAKPOINT);
                DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev });
        }
 
        public boolean canStepInto() {
-               return isSuspended && this.hasStackFrames();
+               return isSuspended() && isStepping() && this.hasStackFrames();
        }
 
        public boolean canStepOver() {
-               return isSuspended && this.hasStackFrames();
+               return isSuspended() && isStepping() && this.hasStackFrames();
        }
 
        public boolean canStepReturn() {
-               return false;
+               return isSuspended() && isStepping() && this.hasStackFrames();
        }
 
        public boolean isStepping() {
-               return isStepping;
+               return state.isStepping();
        }
 
        public void stepInto() throws DebugException {
-               isStepping = true ;
-               this.createName() ;
-               this.frames = null ;
+               try { state.setStepping(true); }
+               catch (IllegalStateException x) {
+                       throw new DebugException(PHPeclipsePlugin.error(x));
+               }
+               this.frames = null;
                frames[0].stepInto();
        }
 
        public void stepOver() throws DebugException {
-               isStepping = true ;             
-               this.createName() ;
-               this.frames = null ;            
-               frames[0].stepOver() ;
+               state.setStepping(true);
+               this.frames = null;
+               frames[0].stepOver();
        }
 
        public void stepReturn() throws DebugException {
        }
 
        public boolean canTerminate() {
-               return !isTerminated;
+               return !isTerminated();
        }
 
        public boolean isTerminated() {
-               return isTerminated;
+               return state.isTerminated();
        }
 
-       public void terminate() throws DebugException {
-               isTerminated = true;
+       public synchronized void terminate() throws DebugException {
+               if (isTerminated())
+                       return;
+               state.setTerminated(true);
                this.frames = null;
                getDebugTarget().terminate();
        }
 
        public Object getAdapter(Class arg0) {
+               if (IWorkbenchAdapter.class.equals(arg0)) {
+                       return new IWorkbenchAdapter() {
+                               public Object[] getChildren(Object o) {
+                                       Object[] children = null;
+                                       try {
+                                               IStackFrame[] frames = getStackFrames();
+                                               if (null != frames) {
+                                                       children = new Object[frames.length];
+                                                       for (int i = 0; i < frames.length; ++i)
+                                                               children[i] = frames[i];
+                                               }
+                                       } catch (DebugException x) {
+                                               PHPeclipsePlugin.log("Unable to get stack frames.", x);
+                                       }
+                                       return children;
+                               }
+
+                               public ImageDescriptor getImageDescriptor(Object object) {
+                                       return null;
+                               }
+
+                               public String getLabel(Object o) {
+                                       throw new UnsupportedOperationException();
+                               }
+
+                               public Object getParent(Object o) {
+                                       return getDebugTarget();
+                               }
+                       };
+               }
                return null;
        }
 
@@ -183,6 +260,9 @@ public class PHPThread implements IThread {
        }
 
        public String getName() {
+               String name = this.name;
+               if (isSuspended())
+                       name = name + " (suspended)";
                return name;
        }
 
@@ -190,18 +270,11 @@ public class PHPThread implements IThread {
                this.name = name;
        }
 
-       protected void createName() {
-               //this.createName(null) ;       
-       }
-
-       /*      
-       protected void createName(SuspensionPoint suspensionPoint) {
-               this.name = "PHP Thread - " + this.getId()  ;
-               if (suspensionPoint != null) { 
-                       this.name += " (" + suspensionPoint + ")" ;
-               }
-       }
-       */
+       /*
+        * protected void createName(SuspensionPoint suspensionPoint) { this.name =
+        * "PHP Thread - " + this.getId() ; if (suspensionPoint != null) { this.name += " (" +
+        * suspensionPoint + ")" ; } }
+        */
 
        public int getId() {
                return id;