Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

use :hist to get some kinf of stack trace

  • Loading branch information...
commit 16614423d3a55dd0cc0f6376a2c6ee97cd192d6b 1 parent bd5c573
@JPMoresmau authored
View
3  docs/releasenotes/net.sf.eclipsefp.haskell_2.3.2.txt
@@ -21,11 +21,14 @@ Features:
- In preferences for executables, you can install the executable from Haskage
- Install all helper executables from one dialog
- Install all dependencies for one project from right click on project (performs a clean of the project afterwards).
+ - BuildWrapper and scion-browser should build with GHC 7.6
+ - If you run a GHCi session in debug mode and launch a function with :trace, :hist output will show as a stack trace in the Debug perspective
Internal:
- Hopefully performance of some UI operations has been enhanced and the UI should be more responsive in places
Upgrade notes:
+ - Upgrade via the Eclipse install site http://eclipsefp.sf.net/updates.
Known issues:
View
4 net.sf.eclipsefp.haskell.core/src/net/sf/eclipsefp/haskell/core/util/GHCiSyntax.java
@@ -32,7 +32,9 @@
public static final String TYPE_LAST_RESULT_COMMAND=":t it"; //$NON-NLS-1$
public static final String STEP_COMMAND=":step"; //$NON-NLS-1$
-
+ public static final String HIST_COMMAND=":hist"; //$NON-NLS-1$
+ public static final Pattern HIST_LOCATION_PATTERN=Pattern.compile( "\\-(\\d+)\\s+\\:\\s+(.+)\\s+\\((.+)\\:(\\d+)\\:(\\d+)\\-(\\d+)\\)"); //$NON-NLS-1$
+ public static final Pattern HIST_LOCATIONMULTILINE_PATTERN=Pattern.compile( "\\-(\\d+)\\s+\\:\\s+(.+)\\s+\\((.+)\\:\\((\\d+),(\\d+)\\)\\-\\((\\d+),(\\d+)\\)\\)");//$NON-NLS-1$
public static final String SET_PRINT_WITH_SHOW_COMMAND=":set -fprint-evld-with-show"; //$NON-NLS-1$
View
76 ...debug.core/src/net/sf/eclipsefp/haskell/debug/core/internal/debug/HaskellDebugTarget.java
@@ -148,7 +148,11 @@ public boolean canTerminate() {
@Override
public boolean isTerminated() {
- return fProcess.isTerminated();
+ boolean t=fProcess.isTerminated();
+ if (t && connected){
+ dispose();
+ }
+ return t;
}
protected synchronized void sendRequest(final String command,final boolean wait)throws DebugException{
@@ -157,13 +161,15 @@ protected synchronized void sendRequest(final String command,final boolean wait)
atEnd=false;
}
try {
-
- fProcess.getStreamsProxy().write(command);
- fProcess.getStreamsProxy().write(PlatformUtil.NL);
- if (wait){
- waitForPrompt();
+ if (fProcess!=null && !fProcess.isTerminated()){
+ fProcess.getStreamsProxy().write(command);
+ fProcess.getStreamsProxy().write(PlatformUtil.NL);
+ if (wait){
+ waitForPrompt();
+ }
+ } else {
+ dispose();
}
-
} catch (IOException ioe){
throw new DebugException(new Status(IStatus.ERROR,HaskellDebugCore.getPluginId(),ioe.getLocalizedMessage(),ioe));
}
@@ -183,7 +189,9 @@ private synchronized void waitForPrompt(){
@Override
public void terminate() throws DebugException {
+
sendRequest( GHCiSyntax.QUIT_COMMAND,false );
+ dispose();
}
@Override
@@ -295,7 +303,7 @@ public boolean canDisconnect() {
@Override
public void disconnect() throws DebugException {
- connected=false;
+ dispose();
try {
// TODO take out GHCi specific
sendRequest(GHCiSyntax.DELETE_ALL_BREAKPOINTS_COMMAND,true);
@@ -306,6 +314,11 @@ public void disconnect() throws DebugException {
}
+ public void dispose(){
+ connected=false;
+ DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener( this );
+ }
+
@Override
public boolean isDisconnected() {
return !connected;
@@ -357,8 +370,20 @@ public synchronized void streamAppended( final String text, final IStreamMonitor
response.setLength( 0 );
DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent( thread, DebugEvent.CHANGE,DebugEvent.STATE )});
notify();
+ Runnable r=new Runnable(){
+ /* (non-Javadoc)
+ * @see java.lang.Runnable#run()
+ */
+ @Override
+ public void run() {
+ getHistory();
+
+ }
+ };
+ new Thread(r).start();
return;
}
+
}
Matcher m=GHCiSyntax.BREAKPOINT_STOP_PATTERN.matcher( response.toString() );
if (m.find()){
@@ -414,7 +439,40 @@ public synchronized void streamAppended( final String text, final IStreamMonitor
}
+ public synchronized void getHistory() {
+ try {
+ sendRequest( GHCiSyntax.HIST_COMMAND, true );
+ String s=getResultWithoutPrompt();
+ BufferedReader br=new BufferedReader(new StringReader( s ));
+ try {
+ List<HaskellStrackFrame> l=thread.getHistoryFrames();
+ synchronized( l ) {
+ l.clear();
+ String line=br.readLine();
+ while (line!=null){
+ HaskellStrackFrame f2=new HaskellStrackFrame( thread );
+ f2.setHistoryLocation( line );
+ if (f2.getName()!=null){
+ l.add( f2 );
+ }
+ line=br.readLine();
+ }
+ }
+
+ DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent( thread, DebugEvent.CHANGE,DebugEvent.STATE )});
+ notify();
+ } catch (IOException ioe){
+ HaskellCorePlugin.log( ioe );
+ }
+ } catch (DebugException de){
+ HaskellCorePlugin.log( de );
+ }
+ }
+
public synchronized IVariable[] getVariables( final HaskellStrackFrame frame ) throws DebugException {
+ if (!frame.hasVariables()){
+ return new IVariable[0];
+ }
sendRequest( GHCiSyntax.SHOW_BINDINGS_COMMAND, true );
String s=getResultWithoutPrompt();
BufferedReader br=new BufferedReader(new StringReader( s ));
@@ -443,6 +501,8 @@ public synchronized void streamAppended( final String text, final IStreamMonitor
}
}
+
+
public void forceVariable(final HaskellVariable var)throws DebugException{
sendRequest( GHCiSyntax.forceVariableCommand( var.getName() ), true );
DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent( var.getFrame(), DebugEvent.CHANGE,DebugEvent.CONTENT)});
View
637 ...debug.core/src/net/sf/eclipsefp/haskell/debug/core/internal/debug/HaskellStrackFrame.java
@@ -1,277 +1,360 @@
-package net.sf.eclipsefp.haskell.debug.core.internal.debug;
-
-import java.util.regex.Matcher;
-import net.sf.eclipsefp.haskell.core.util.GHCiSyntax;
-import net.sf.eclipsefp.haskell.debug.core.internal.launch.ILaunchAttributes;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.debug.core.DebugEvent;
-import org.eclipse.debug.core.DebugException;
-import org.eclipse.debug.core.DebugPlugin;
-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.jface.text.IDocument;
-import org.eclipse.ui.editors.text.TextFileDocumentProvider;
-import org.eclipse.ui.texteditor.IDocumentProvider;
-
-/**
- * stack frame for debugging haskell. For the moment there is always one stack frame.
- * @author JP Moresmau
- *
- */
-public class HaskellStrackFrame extends HaskellDebugElement implements IStackFrame {
- private final HaskellThread thread;
- private int lineNumber=-1;
- private String name="HaskellStrackFrame"; //$NON-NLS-1$
- /**
- * relative file name
- */
- private String fileName;
- /**
- * full file name
- */
- private String unprocessedFileName;
- private int charEnd=-1;
- private int charStart=-1;
-
- public HaskellStrackFrame(final HaskellThread thread){
- super(thread.getDebugTarget());
- this.thread=thread;
- }
-
- @Override
- public int getCharEnd() {
- // return -1
- return this.charEnd;
- }
-
- @Override
- public int getCharStart() {
- // return -1;
- return this.charStart;
- }
-
- @Override
- public int getLineNumber() {
- return lineNumber;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
-
- public void setLocation( final String location ) {
- name=location;
- lineNumber=-1;
- fileName=null;
- unprocessedFileName=location;
- int endLineNumber = -1, tmpCharStart = -1, tmpCharEnd = -1;
- Matcher m=GHCiSyntax.BREAKPOINT_LOCATION_PATTERN.matcher( location );
- if (m.matches()){
- //name= m.group(1) ;
- endLineNumber=lineNumber=Integer.parseInt( m.group(2)) ;
- unprocessedFileName=m.group( 1 );
-
- tmpCharStart=Integer.parseInt(m.group(3));
- tmpCharEnd=Integer.parseInt(m.group(4));
- } else {
- m=GHCiSyntax.BREAKPOINT_LOCATIONMULTILINE_PATTERN.matcher( location );
- if (m.matches()){
- lineNumber=Integer.parseInt( m.group(2)) ;
- endLineNumber=Integer.parseInt( m.group(4) );
- unprocessedFileName=m.group( 1 );
- tmpCharStart=Integer.parseInt(m.group(3));
- tmpCharEnd=Integer.parseInt(m.group(5));
- } else {
- // It means there was an error
- endLineNumber = -1;
- }
- }
- // Compute real character positions
- if (endLineNumber == -1) {
- // If there was an error
- lineNumber = -1;
- charStart = -1;
- charEnd = -1;
- } else {
- try {
- // Get file name
- String fname=unprocessedFileName;
- IProject p = getProject();
- String projectLocation=p.getLocation().toOSString();
- if (fname.startsWith( projectLocation )){
- fname=fname.substring( projectLocation.length()+1 );
- }
- IFile f= p.getFile( fname );
- IDocumentProvider prov=new TextFileDocumentProvider();
- prov.connect( f );
- try {
- IDocument doc=prov.getDocument( f );
-
- //InputStream st = p.getFile( fname ).getContents();
- // Get document info
- //IDocument d = new Document( ResourceUtil.readStream( st ) );
- //st.close();
- int initLineOffset = doc.getLineOffset( lineNumber - 1 );
- int endLineOffset = doc.getLineOffset( endLineNumber - 1 );
- charStart = initLineOffset + tmpCharStart - 1;
- charEnd = endLineOffset + tmpCharEnd;
- } finally {
- prov.disconnect( f );
- }
- } catch (Exception e) {
- lineNumber = -1;
- charStart = -1;
- charEnd = -1;
- }
- }
-
- DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent( this, DebugEvent.CHANGE, DebugEvent.CONTENT )});
- }
-
-
- public String getFileName() throws CoreException{
- if (fileName==null){
- fileName=unprocessedFileName;
- IProject p = getProject();
- String projectLocation=p.getLocation().toOSString();
- // return file relative to project, since we may have the same file in different folders (Main.hs)
- if (fileName.startsWith( projectLocation )){
- fileName=fileName.substring( projectLocation.length()+1 );
- return fileName;
- }
- // see http://sourceforge.net/projects/eclipsefp/forums/forum/371922/topic/5091430, we don't want to reduce only to our project
- // not found in my project, look in all reference projects
- for (IProject p1:getProject().getReferencedProjects()){
- //
- String projectLocation1=p1.getLocation().toOSString();
- // return file relative to project, since we may have the same file in different folders (Main.hs)
- if (fileName.startsWith( projectLocation1 )){
- fileName=fileName.substring( projectLocation1.length()+1 );
- break;
- }
- }
- }
- return fileName;
- }
-
- public IProject getProject() throws CoreException {
- String projectName=getLaunch().getLaunchConfiguration().getAttribute( ILaunchAttributes.PROJECT_NAME ,(String)null);
- if (projectName!=null){
- IProject p=ResourcesPlugin.getWorkspace().getRoot().getProject( projectName );
- return p;
- }
- return null;
- }
-
- @Override
- public IRegisterGroup[] getRegisterGroups() {
- return new IRegisterGroup[0];
- }
-
- @Override
- public IThread getThread() {
- return thread;
- }
-
- @Override
- public IVariable[] getVariables() throws DebugException {
- return getDebugTarget().getVariables(this);
- }
-
- @Override
- public boolean hasRegisterGroups() {
- return false;
- }
-
- @Override
- public boolean hasVariables() {
- return true;
- }
-
- @Override
- public boolean canStepInto() {
- return thread.canStepInto();
- }
-
- @Override
- public boolean canStepOver() {
- return thread.canStepOver();
- }
-
- @Override
- public boolean canStepReturn() {
- return thread.canStepReturn();
- }
-
- @Override
- public boolean isStepping() {
- return thread.isStepping();
- }
-
- @Override
- public void stepInto() throws DebugException {
- thread.stepInto();
-
- }
-
- @Override
- public void stepOver() {
- thread.stepOver();
-
- }
-
- @Override
- public void stepReturn() {
- thread.stepReturn();
-
- }
-
- @Override
- public boolean canResume() {
- return thread.canResume();
- }
-
- @Override
- public boolean canSuspend() {
- return thread.canSuspend();
- }
-
- @Override
- public boolean isSuspended() {
- return thread.isSuspended();
- }
-
- @Override
- public void resume() throws DebugException {
- thread.resume();
- }
-
- @Override
- public void suspend() {
- thread.suspend();
- }
-
- @Override
- public boolean canTerminate() {
- return thread.canTerminate();
- }
-
- @Override
- public boolean isTerminated() {
- return thread.isTerminated();
- }
-
- @Override
- public void terminate() throws DebugException {
- thread.terminate();
-
- }
-
-}
+package net.sf.eclipsefp.haskell.debug.core.internal.debug;
+
+import java.util.regex.Matcher;
+import net.sf.eclipsefp.haskell.core.util.GHCiSyntax;
+import net.sf.eclipsefp.haskell.debug.core.internal.launch.ILaunchAttributes;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+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.jface.text.IDocument;
+import org.eclipse.ui.editors.text.TextFileDocumentProvider;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+
+/**
+ * stack frame for debugging haskell. For the moment there is always one stack frame.
+ * @author JP Moresmau
+ *
+ */
+public class HaskellStrackFrame extends HaskellDebugElement implements IStackFrame {
+ private final HaskellThread thread;
+ private int lineNumber=-1;
+ private String name="HaskellStrackFrame"; //$NON-NLS-1$
+ /**
+ * relative file name
+ */
+ private String fileName;
+ /**
+ * full file name
+ */
+ private String unprocessedFileName;
+ private int charEnd=-1;
+ private int charStart=-1;
+
+ private boolean hasVariables=false;
+
+ public HaskellStrackFrame(final HaskellThread thread){
+ super(thread.getDebugTarget());
+ this.thread=thread;
+ }
+
+ @Override
+ public int getCharEnd() {
+ // return -1
+ return this.charEnd;
+ }
+
+ @Override
+ public int getCharStart() {
+ // return -1;
+ return this.charStart;
+ }
+
+ @Override
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+
+ public void setLocation( final String location ) {
+ name=location;
+ lineNumber=-1;
+ fileName=null;
+ unprocessedFileName=location;
+ int endLineNumber = -1, tmpCharStart = -1, tmpCharEnd = -1;
+ Matcher m=GHCiSyntax.BREAKPOINT_LOCATION_PATTERN.matcher( location );
+ if (m.matches()){
+ //name= m.group(1) ;
+ endLineNumber=lineNumber=Integer.parseInt( m.group(2)) ;
+ unprocessedFileName=m.group( 1 );
+
+ tmpCharStart=Integer.parseInt(m.group(3));
+ tmpCharEnd=Integer.parseInt(m.group(4));
+ } else {
+ m=GHCiSyntax.BREAKPOINT_LOCATIONMULTILINE_PATTERN.matcher( location );
+ if (m.matches()){
+ lineNumber=Integer.parseInt( m.group(2)) ;
+ endLineNumber=Integer.parseInt( m.group(4) );
+ unprocessedFileName=m.group( 1 );
+ tmpCharStart=Integer.parseInt(m.group(3));
+ tmpCharEnd=Integer.parseInt(m.group(5));
+ } else {
+ // It means there was an error
+ endLineNumber = -1;
+ }
+ }
+ // Compute real character positions
+ if (endLineNumber == -1) {
+ // If there was an error
+ lineNumber = -1;
+ charStart = -1;
+ charEnd = -1;
+ } else {
+ try {
+ hasVariables=true;
+ // Get file name
+ String fname=unprocessedFileName;
+ IProject p = getProject();
+ String projectLocation=p.getLocation().toOSString();
+ if (fname.startsWith( projectLocation )){
+ fname=fname.substring( projectLocation.length()+1 );
+ }
+ IFile f= p.getFile( fname );
+ IDocumentProvider prov=new TextFileDocumentProvider();
+ prov.connect( f );
+ try {
+ IDocument doc=prov.getDocument( f );
+
+ //InputStream st = p.getFile( fname ).getContents();
+ // Get document info
+ //IDocument d = new Document( ResourceUtil.readStream( st ) );
+ //st.close();
+ int initLineOffset = doc.getLineOffset( lineNumber - 1 );
+ int endLineOffset = doc.getLineOffset( endLineNumber - 1 );
+ charStart = initLineOffset + tmpCharStart - 1;
+ charEnd = endLineOffset + tmpCharEnd;
+ } finally {
+ prov.disconnect( f );
+ }
+ } catch (Exception e) {
+ lineNumber = -1;
+ charStart = -1;
+ charEnd = -1;
+ }
+ }
+
+ DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent( this, DebugEvent.CHANGE, DebugEvent.CONTENT )});
+ }
+
+ public void setHistoryLocation( final String location ) {
+ name=null;
+ lineNumber=-1;
+ fileName=null;
+ unprocessedFileName=location;
+ int endLineNumber = -1, tmpCharStart = -1, tmpCharEnd = -1, idx=-1;
+
+ Matcher m=GHCiSyntax.HIST_LOCATION_PATTERN.matcher( location );
+ if (m.matches()){
+ //name= m.group(1) ;
+ idx=Integer.parseInt( m.group(1));
+ endLineNumber=lineNumber=Integer.parseInt( m.group(4)) ;
+ unprocessedFileName=m.group( 3 );
+
+ tmpCharStart=Integer.parseInt(m.group(5));
+ tmpCharEnd=Integer.parseInt(m.group(6));
+ } else {
+ m=GHCiSyntax.HIST_LOCATIONMULTILINE_PATTERN.matcher( location );
+ if (m.matches()){
+ idx=Integer.parseInt( m.group(1));
+ //name= m.group(1) ;
+ lineNumber=Integer.parseInt( m.group(4)) ;
+ endLineNumber=Integer.parseInt( m.group(6) );
+ unprocessedFileName=m.group( 3 );
+ tmpCharStart=Integer.parseInt(m.group(5));
+ tmpCharEnd=Integer.parseInt(m.group(6));
+ } else {
+ // It means there was an error
+ endLineNumber = -1;
+ }
+ }
+ // Compute real character positions
+ if (endLineNumber == -1) {
+ // If there was an error
+ lineNumber = -1;
+ charStart = -1;
+ charEnd = -1;
+ } else {
+ try {
+ hasVariables=idx==1;
+ name=location;
+ int ix=name.indexOf( ':' );
+ name=name.substring( ix+1 ).trim();
+ // Get file name
+ String fname=unprocessedFileName;
+ IProject p = getProject();
+ String projectLocation=p.getLocation().toOSString();
+ if (fname.startsWith( projectLocation )){
+ fname=fname.substring( projectLocation.length()+1 );
+ }
+ IFile f= p.getFile( fname );
+ IDocumentProvider prov=new TextFileDocumentProvider();
+ prov.connect( f );
+ try {
+ IDocument doc=prov.getDocument( f );
+
+ //InputStream st = p.getFile( fname ).getContents();
+ // Get document info
+ //IDocument d = new Document( ResourceUtil.readStream( st ) );
+ //st.close();
+ int initLineOffset = doc.getLineOffset( lineNumber - 1 );
+ int endLineOffset = doc.getLineOffset( endLineNumber - 1 );
+ charStart = initLineOffset + tmpCharStart - 1;
+ charEnd = endLineOffset + tmpCharEnd;
+ } finally {
+ prov.disconnect( f );
+ }
+ } catch (Exception e) {
+ lineNumber = -1;
+ charStart = -1;
+ charEnd = -1;
+ }
+ }
+
+ DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent( this, DebugEvent.CHANGE, DebugEvent.CONTENT )});
+ }
+
+
+ /**
+ * @return the hasVariables
+ */
+ @Override
+ public boolean hasVariables() {
+ return hasVariables;
+ }
+
+ public String getFileName() throws CoreException{
+ if (fileName==null){
+ fileName=unprocessedFileName;
+ IProject p = getProject();
+ String projectLocation=p.getLocation().toOSString();
+ // return file relative to project, since we may have the same file in different folders (Main.hs)
+ if (fileName.startsWith( projectLocation )){
+ fileName=fileName.substring( projectLocation.length()+1 );
+ return fileName;
+ }
+ // see http://sourceforge.net/projects/eclipsefp/forums/forum/371922/topic/5091430, we don't want to reduce only to our project
+ // not found in my project, look in all reference projects
+ for (IProject p1:getProject().getReferencedProjects()){
+ //
+ String projectLocation1=p1.getLocation().toOSString();
+ // return file relative to project, since we may have the same file in different folders (Main.hs)
+ if (fileName.startsWith( projectLocation1 )){
+ fileName=fileName.substring( projectLocation1.length()+1 );
+ break;
+ }
+ }
+ }
+ return fileName;
+ }
+
+ public IProject getProject() throws CoreException {
+ String projectName=getLaunch().getLaunchConfiguration().getAttribute( ILaunchAttributes.PROJECT_NAME ,(String)null);
+ if (projectName!=null){
+ IProject p=ResourcesPlugin.getWorkspace().getRoot().getProject( projectName );
+ return p;
+ }
+ return null;
+ }
+
+ @Override
+ public IRegisterGroup[] getRegisterGroups() {
+ return new IRegisterGroup[0];
+ }
+
+ @Override
+ public IThread getThread() {
+ return thread;
+ }
+
+ @Override
+ public IVariable[] getVariables() throws DebugException {
+ return getDebugTarget().getVariables(this);
+ }
+
+ @Override
+ public boolean hasRegisterGroups() {
+ return false;
+ }
+
+ @Override
+ public boolean canStepInto() {
+ return thread.canStepInto();
+ }
+
+ @Override
+ public boolean canStepOver() {
+ return thread.canStepOver();
+ }
+
+ @Override
+ public boolean canStepReturn() {
+ return thread.canStepReturn();
+ }
+
+ @Override
+ public boolean isStepping() {
+ return thread.isStepping();
+ }
+
+ @Override
+ public void stepInto() throws DebugException {
+ thread.stepInto();
+
+ }
+
+ @Override
+ public void stepOver() {
+ thread.stepOver();
+
+ }
+
+ @Override
+ public void stepReturn() {
+ thread.stepReturn();
+
+ }
+
+ @Override
+ public boolean canResume() {
+ return thread.canResume();
+ }
+
+ @Override
+ public boolean canSuspend() {
+ return thread.canSuspend();
+ }
+
+ @Override
+ public boolean isSuspended() {
+ return thread.isSuspended();
+ }
+
+ @Override
+ public void resume() throws DebugException {
+ thread.resume();
+ }
+
+ @Override
+ public void suspend() {
+ thread.suspend();
+ }
+
+ @Override
+ public boolean canTerminate() {
+ return thread.canTerminate();
+ }
+
+ @Override
+ public boolean isTerminated() {
+ return thread.isTerminated();
+ }
+
+ @Override
+ public void terminate() throws DebugException {
+ thread.terminate();
+
+ }
+
+}
View
349 ...kell.debug.core/src/net/sf/eclipsefp/haskell/debug/core/internal/debug/HaskellThread.java
@@ -1,165 +1,184 @@
-package net.sf.eclipsefp.haskell.debug.core.internal.debug;
-
-import net.sf.eclipsefp.haskell.core.util.GHCiSyntax;
-import net.sf.eclipsefp.haskell.debug.core.internal.util.CoreTexts;
-import org.eclipse.debug.core.DebugEvent;
-import org.eclipse.debug.core.DebugException;
-import org.eclipse.debug.core.DebugPlugin;
-import org.eclipse.debug.core.model.IBreakpoint;
-import org.eclipse.debug.core.model.IStackFrame;
-import org.eclipse.debug.core.model.IThread;
-
-/**
- * thread for debugging haskell. For the moment there is always one thread
- * @author JP Moresmau
- *
- */
-public class HaskellThread extends HaskellDebugElement implements IThread {
- private HaskellBreakpoint breakpoint;
- private String stopLocation;
- private final HaskellStrackFrame frame=new HaskellStrackFrame( this );
- private String name=CoreTexts.thread_default_name;
-
- public HaskellThread(final HaskellDebugTarget target){
- super( target );
- }
-
- @Override
- public IBreakpoint[] getBreakpoints() {
- if (breakpoint!=null){
- return new IBreakpoint[]{breakpoint};
- }
- return new IBreakpoint[0];
- }
-
- public void setBreakpoint( final HaskellBreakpoint breakpoint ) {
- this.breakpoint = breakpoint;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
-
- public void setName( final String name ) {
- this.name = name;
- }
-
- @Override
- public int getPriority() {
- return 0;
- }
-
- @Override
- public IStackFrame[] getStackFrames() {
- if (isSuspended()){
- return new IStackFrame[]{frame};
- }
- return new IStackFrame[0];
-
- }
-
- @Override
- public IStackFrame getTopStackFrame() {
- if (isSuspended()){
- return frame;
- }
- return null;
- }
-
- @Override
- public boolean hasStackFrames() {
- return isSuspended();
- }
-
- @Override
- public boolean canResume() {
- return isSuspended();
- }
-
- @Override
- public boolean canSuspend() {
- return false;
- }
-
- @Override
- public boolean isSuspended() {
- return target.isSuspended();
- }
-
- @Override
- public void resume() throws DebugException {
- target.resume();
- }
-
- @Override
- public void suspend() {
- getDebugTarget().suspend();
-
- }
-
- @Override
- public boolean canStepInto() {
- return isSuspended();
- }
-
- @Override
- public boolean canStepOver() {
- return false;
- }
-
- @Override
- public boolean canStepReturn() {
- return false;
- }
-
- @Override
- public boolean isStepping() {
- return false;
- }
-
- @Override
- public void stepInto() throws DebugException {
- target.sendRequest( GHCiSyntax.STEP_COMMAND, true );
- DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent( frame, DebugEvent.CHANGE,DebugEvent.CONTENT )});
-
- }
-
- @Override
- public void stepOver() {
- // NOOP
-
- }
-
- @Override
- public void stepReturn() {
- // NOOP
- }
-
- @Override
- public boolean canTerminate() {
- return target.canTerminate();
- }
-
- @Override
- public boolean isTerminated() {
- return target.isTerminated();
- }
-
- @Override
- public void terminate() throws DebugException {
- target.terminate();
- }
-
-
- public String getStopLocation() {
- return stopLocation;
- }
-
-
- public void setStopLocation( final String stopLocation ) {
- this.stopLocation = stopLocation;
- }
-
-}
+package net.sf.eclipsefp.haskell.debug.core.internal.debug;
+
+import java.util.ArrayList;
+import java.util.List;
+import net.sf.eclipsefp.haskell.core.util.GHCiSyntax;
+import net.sf.eclipsefp.haskell.debug.core.internal.util.CoreTexts;
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.debug.core.model.IThread;
+
+/**
+ * thread for debugging haskell. For the moment there is always one thread
+ * @author JP Moresmau
+ *
+ */
+public class HaskellThread extends HaskellDebugElement implements IThread {
+ private HaskellBreakpoint breakpoint;
+ private String stopLocation;
+ private final HaskellStrackFrame frame=new HaskellStrackFrame( this );
+ private String name=CoreTexts.thread_default_name;
+
+ private final List<HaskellStrackFrame> historyFrames=new ArrayList<HaskellStrackFrame>();
+
+ public HaskellThread(final HaskellDebugTarget target){
+ super( target );
+ }
+
+ @Override
+ public IBreakpoint[] getBreakpoints() {
+ if (breakpoint!=null){
+ return new IBreakpoint[]{breakpoint};
+ }
+ return new IBreakpoint[0];
+ }
+
+ public void setBreakpoint( final HaskellBreakpoint breakpoint ) {
+ this.breakpoint = breakpoint;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+
+ public void setName( final String name ) {
+ this.name = name;
+ }
+
+ @Override
+ public int getPriority() {
+ return 0;
+ }
+
+ @Override
+ public IStackFrame[] getStackFrames() {
+ if (isSuspended()){
+ synchronized( historyFrames ) {
+ if (historyFrames.size()>0){
+// IStackFrame[] ret=new IStackFrame[historyFrames.size()+1];
+// ret[0]=frame;
+// System.arraycopy(historyFrames.toArray(), 0,ret, 1, historyFrames.size() );
+// return ret;
+ return historyFrames.toArray( new IStackFrame[historyFrames.size()] );
+ }
+
+ }
+ return new IStackFrame[]{frame};
+ }
+ return new IStackFrame[0];
+
+ }
+
+ @Override
+ public IStackFrame getTopStackFrame() {
+ if (isSuspended()){
+ return frame;
+ }
+ return null;
+ }
+
+ @Override
+ public boolean hasStackFrames() {
+ return isSuspended();
+ }
+
+ @Override
+ public boolean canResume() {
+ return isSuspended();
+ }
+
+ @Override
+ public boolean canSuspend() {
+ return false;
+ }
+
+ @Override
+ public boolean isSuspended() {
+ return target.isSuspended();
+ }
+
+ @Override
+ public void resume() throws DebugException {
+ target.resume();
+ }
+
+ @Override
+ public void suspend() {
+ getDebugTarget().suspend();
+
+ }
+
+ @Override
+ public boolean canStepInto() {
+ return isSuspended();
+ }
+
+ @Override
+ public boolean canStepOver() {
+ return false;
+ }
+
+ @Override
+ public boolean canStepReturn() {
+ return false;
+ }
+
+ @Override
+ public boolean isStepping() {
+ return false;
+ }
+
+ @Override
+ public void stepInto() throws DebugException {
+ target.sendRequest( GHCiSyntax.STEP_COMMAND, true );
+ DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent( frame, DebugEvent.CHANGE,DebugEvent.CONTENT )});
+
+ }
+
+ @Override
+ public void stepOver() {
+ // NOOP
+
+ }
+
+ @Override
+ public void stepReturn() {
+ // NOOP
+ }
+
+ @Override
+ public boolean canTerminate() {
+ return target.canTerminate();
+ }
+
+ @Override
+ public boolean isTerminated() {
+ return target.isTerminated();
+ }
+
+ @Override
+ public void terminate() throws DebugException {
+ target.terminate();
+ }
+
+
+ public String getStopLocation() {
+ return stopLocation;
+ }
+
+
+ public void setStopLocation( final String stopLocation ) {
+ this.stopLocation = stopLocation;
+ }
+
+
+ public List<HaskellStrackFrame> getHistoryFrames() {
+ return historyFrames;
+ }
+
+}
Please sign in to comment.
Something went wrong with that request. Please try again.