This is an automated email from the ASF dual-hosted git repository. entl pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push: new 10cb3ff Representation of frames in DebuggingView API. new 714b6a0 Merge pull request #2429 from entlicher/DebuggingViewFrameAPIs 10cb3ff is described below commit 10cb3ff7b77c3c82ba67476c1ab25d301d776a4e Author: Martin Entlicher <martin.entlic...@oracle.com> AuthorDate: Thu Oct 8 18:51:44 2020 +0200 Representation of frames in DebuggingView API. --- ide/spi.debugger.ui/apichanges.xml | 17 +++ ide/spi.debugger.ui/manifest.mf | 2 +- .../netbeans/spi/debugger/ui/DebuggingView.java | 99 +++++++++++++++++ java/debugger.jpda.truffle/nbproject/project.xml | 2 +- .../frames/models/DebuggingTruffleTreeModel.java | 32 +++++- .../frames/models/DebuggingViewTruffleSupport.java | 80 ++++++++++++++ .../jpda/truffle/frames/models/TruffleDVFrame.java | 79 ++++++++++++++ java/debugger.jpda.ui/nbproject/project.xml | 3 +- .../ui/debugging/DebuggingViewSupportImpl.java | 28 ++++- .../debugger/jpda/ui/debugging/JPDADVFrame.java | 117 +++++++++++++++++++++ .../debugger/jpda/ui/debugging/JPDADVThread.java | 57 +++++++++- 11 files changed, 504 insertions(+), 12 deletions(-) diff --git a/ide/spi.debugger.ui/apichanges.xml b/ide/spi.debugger.ui/apichanges.xml index c3e21b4..0703882 100644 --- a/ide/spi.debugger.ui/apichanges.xml +++ b/ide/spi.debugger.ui/apichanges.xml @@ -244,6 +244,23 @@ <issue number="262312"/> </change> + <change id="DebuggingViewFrames"> + <api name="DebuggerCoreSPI"/> + <summary>Frames added into DebuggingView.</summary> + <version major="2" minor="65"/> + <date day="09" month="10" year="2020"/> + <author login="mentlicher"/> + <compatibility binary="compatible" source="compatible" addition="yes" semantic="compatible"/> + <description> + <p> + DebuggingView is enhanced with stack frames. + <code>DVSupport.DVFrame</code> interface was added together with getters on + <code>DVThread</code> class. + </p> + </description> + <class package="org.netbeans.spi.debugger.ui" name="DebuggingView"/> + </change> + </changes> <!-- Now the surrounding HTML text and document structure: --> diff --git a/ide/spi.debugger.ui/manifest.mf b/ide/spi.debugger.ui/manifest.mf index 57dd36d..c410f70 100644 --- a/ide/spi.debugger.ui/manifest.mf +++ b/ide/spi.debugger.ui/manifest.mf @@ -2,6 +2,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.spi.debugger.ui/1 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/debugger/ui/Bundle.properties OpenIDE-Module-Layer: org/netbeans/modules/debugger/resources/mf-layer.xml -OpenIDE-Module-Specification-Version: 2.64 +OpenIDE-Module-Specification-Version: 2.65 OpenIDE-Module-Provides: org.netbeans.spi.debugger.ui OpenIDE-Module-Install: org/netbeans/modules/debugger/ui/DebuggerModule.class diff --git a/ide/spi.debugger.ui/src/org/netbeans/spi/debugger/ui/DebuggingView.java b/ide/spi.debugger.ui/src/org/netbeans/spi/debugger/ui/DebuggingView.java index 63f8c69..263297d 100644 --- a/ide/spi.debugger.ui/src/org/netbeans/spi/debugger/ui/DebuggingView.java +++ b/ide/spi.debugger.ui/src/org/netbeans/spi/debugger/ui/DebuggingView.java @@ -29,7 +29,9 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.ref.Reference; import java.lang.ref.WeakReference; +import java.net.URI; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -172,6 +174,17 @@ public final class DebuggingView { public abstract String getDisplayName(DVThread thread); /** + * Get the display name of the frame. It can contain more information + * than a frame name, like source location, etc. + * @param frame the frame + * @return the frame display name + * @since 2.65 + */ + public String getDisplayName(DVFrame frame) { + return frame.getName(); + } + + /** * Get the thread icon. * @param thread the thread * @return the thread icon @@ -327,6 +340,40 @@ public final class DebuggingView { public void makeCurrent(); /** + * Get frame count of this thread. The frame count is provided when the thread + * is suspended only. + * @return the frame count, <code>0</code> when the thread is running. + * @since 2.65 + */ + public default int getFrameCount() { + return 0; + } + + /** + * Get the stack frames of this thread. Stack frames are provided when the thread + * is suspended only. + * + * @return a list of stack frames, it's empty when the thread is running. + * @since 2.65 + */ + public default List<DVFrame> getFrames() { + return Collections.emptyList(); + } + + /** + * Get the stack frames of this thread. Stack frames are provided when the thread + * is suspended only. + * + * @param from a from index, inclusive + * @param to a to index, exclusive + * @return a list of stack frames, it's empty when the thread is running. + * @since 2.65 + */ + public default List<DVFrame> getFrames(int from, int to) { + return Collections.emptyList(); + } + + /** * Get the debugging view support that provides this thread. * @return the debugging view support */ @@ -402,6 +449,58 @@ public final class DebuggingView { } /** + * Representation of a stack frame in debugging view. + * Nodes representing a stack frame in debugging view model should implement this + * interface. + * @since 2.65 + */ + public static interface DVFrame { + + /** + * Get the name of the frame. Usually the frame's class + method name, or function name. + * @return the name of the frame to be displayed in the debugging view. + * @since 2.65 + */ + String getName(); + + /** + * Get the thread of this frame. + * @since 2.65 + */ + DVThread getThread(); + + /** + * Make this frame current. Code evaluation and stepping should be performed + * in the current frame. + * @since 2.65 + */ + void makeCurrent(); + + /** + * Gen URI of the source file associated with this frame, if any. + * @return a source URI, or <code>null</code> if the file is unknown. + * @since 2.65 + */ + URI getSourceURI(); + + /** + * Line location of the frame in the source code at {@link #getSourceURI()}. + * + * @return the line number, or <code>-1</code> if the line is unknown + * @since 2.65 + */ + int getLine(); + + /** + * Column location of the frame in the source code at {@link #getSourceURI()}. + * + * @return the column number, or <code>-1</code> if the column is unknown + * @since 2.65 + */ + int getColumn(); + } + + /** * Representation of a deadlock - one set of mutually deadlocked threads. */ public static final class Deadlock { diff --git a/java/debugger.jpda.truffle/nbproject/project.xml b/java/debugger.jpda.truffle/nbproject/project.xml index a514da6..60a04ac 100644 --- a/java/debugger.jpda.truffle/nbproject/project.xml +++ b/java/debugger.jpda.truffle/nbproject/project.xml @@ -130,7 +130,7 @@ <compile-dependency/> <run-dependency> <release-version>1</release-version> - <specification-version>2.50</specification-version> + <specification-version>2.65</specification-version> </run-dependency> </dependency> <dependency> diff --git a/java/debugger.jpda.truffle/src/org/netbeans/modules/debugger/jpda/truffle/frames/models/DebuggingTruffleTreeModel.java b/java/debugger.jpda.truffle/src/org/netbeans/modules/debugger/jpda/truffle/frames/models/DebuggingTruffleTreeModel.java index d5451fa..7e85cd9 100644 --- a/java/debugger.jpda.truffle/src/org/netbeans/modules/debugger/jpda/truffle/frames/models/DebuggingTruffleTreeModel.java +++ b/java/debugger.jpda.truffle/src/org/netbeans/modules/debugger/jpda/truffle/frames/models/DebuggingTruffleTreeModel.java @@ -21,6 +21,7 @@ package org.netbeans.modules.debugger.jpda.truffle.frames.models; import java.beans.PropertyChangeListener; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.function.Predicate; import java.util.regex.Pattern; @@ -33,10 +34,13 @@ import org.netbeans.modules.debugger.jpda.truffle.access.TruffleAccess; import org.netbeans.modules.debugger.jpda.truffle.access.TruffleStrataProvider; import org.netbeans.modules.debugger.jpda.truffle.frames.TruffleStackFrame; import org.netbeans.modules.debugger.jpda.truffle.options.TruffleOptions; +import org.netbeans.modules.debugger.jpda.ui.debugging.JPDADVFrame; +import org.netbeans.modules.debugger.jpda.ui.debugging.JPDADVThread; import org.netbeans.modules.debugger.jpda.util.WeakCacheMap; import org.netbeans.spi.debugger.ContextProvider; import org.netbeans.spi.debugger.DebuggerServiceRegistration; import org.netbeans.spi.debugger.ui.DebuggingView; +import org.netbeans.spi.debugger.ui.DebuggingView.DVFrame; import org.netbeans.spi.viewmodel.ModelEvent; import org.netbeans.spi.viewmodel.ModelListener; import org.netbeans.spi.viewmodel.TreeModel; @@ -118,7 +122,7 @@ public class DebuggingTruffleTreeModel implements TreeModelFilter { } } - private Object[] filterAndAppend(Object[] children, TruffleStackFrame[] stackFrames, + private static Object[] filterAndAppend(Object[] children, TruffleStackFrame[] stackFrames, TruffleStackFrame topFrame) { List<Object> newChildren = new ArrayList<>(children.length); //newChildren.addAll(Arrays.asList(children)); @@ -141,5 +145,29 @@ public class DebuggingTruffleTreeModel implements TreeModelFilter { } return newChildren.toArray(); } - + + static List<DVFrame> filterAndAppend(JPDADVThread thread, List<DVFrame> children, + TruffleStackFrame[] stackFrames, + TruffleStackFrame topFrame) { + List<DVFrame> newChildren = new ArrayList<>(children.size()); + for (DVFrame ch : children) { + if (ch instanceof JPDADVFrame) { + String className = ((JPDADVFrame) ch).getCallStackFrame().getClassName(); + if (PREDICATE1.test(className) || + className.startsWith(FILTER2) || + className.startsWith(FILTER3)) { + + continue; + } + } + newChildren.add(ch); + } + int i = 0; + newChildren.add(i++, new TruffleDVFrame(thread, topFrame)); + for (TruffleStackFrame tsf : stackFrames) { + newChildren.add(i++, new TruffleDVFrame(thread, tsf)); + } + return Collections.unmodifiableList(newChildren); + } + } diff --git a/java/debugger.jpda.truffle/src/org/netbeans/modules/debugger/jpda/truffle/frames/models/DebuggingViewTruffleSupport.java b/java/debugger.jpda.truffle/src/org/netbeans/modules/debugger/jpda/truffle/frames/models/DebuggingViewTruffleSupport.java new file mode 100644 index 0000000..b55c647 --- /dev/null +++ b/java/debugger.jpda.truffle/src/org/netbeans/modules/debugger/jpda/truffle/frames/models/DebuggingViewTruffleSupport.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.debugger.jpda.truffle.frames.models; + +import java.util.Collections; +import java.util.List; + +import org.netbeans.modules.debugger.jpda.truffle.access.CurrentPCInfo; +import org.netbeans.modules.debugger.jpda.truffle.access.TruffleAccess; +import org.netbeans.modules.debugger.jpda.truffle.frames.TruffleStackFrame; +import org.netbeans.modules.debugger.jpda.truffle.options.TruffleOptions; +import org.netbeans.modules.debugger.jpda.ui.debugging.DebuggingViewSupportImpl; +import org.netbeans.modules.debugger.jpda.ui.debugging.JPDADVThread; +import org.netbeans.spi.debugger.ContextProvider; +import org.netbeans.spi.debugger.ui.DebuggingView; +import org.netbeans.spi.debugger.ui.DebuggingView.DVFrame; + +/** + * + * @author Martin Entlicher + */ +@DebuggingView.DVSupport.Registration(path="netbeans-JPDASession") +public class DebuggingViewTruffleSupport extends DebuggingViewSupportImpl { + + public DebuggingViewTruffleSupport(ContextProvider lookupProvider) { + super(lookupProvider); + } + + @Override + protected int getFrameCount(JPDADVThread thread) { + CurrentPCInfo currentPCInfo = TruffleAccess.getCurrentPCInfo(thread.getKey()); + if (currentPCInfo != null) { + return getFrames(thread, 0, Integer.MAX_VALUE).size(); + } else { + return super.getFrameCount(thread); + } + } + + @Override + protected List<DVFrame> getFrames(JPDADVThread thread, int from, int to) { + List<DVFrame> frames = super.getFrames(thread, 0, Integer.MAX_VALUE); + CurrentPCInfo currentPCInfo = TruffleAccess.getCurrentPCInfo(thread.getKey()); + if (currentPCInfo != null) { + boolean showInternalFrames = TruffleOptions.isLanguageDeveloperMode(); + TruffleStackFrame[] stackFrames = currentPCInfo.getStack().getStackFrames(showInternalFrames); + frames = DebuggingTruffleTreeModel.filterAndAppend(thread, frames, stackFrames, currentPCInfo.getTopFrame()); + } + if (from >= frames.size()) { + return Collections.emptyList(); + } + to = Math.min(to, frames.size()); + return frames.subList(from, to); + } + + @Override + public String getDisplayName(DVFrame frame) { + if (frame instanceof TruffleDVFrame) { + return ((TruffleDVFrame) frame).getTruffleFrame().getDisplayName(); + } else { + return super.getDisplayName(frame); + } + } + +} diff --git a/java/debugger.jpda.truffle/src/org/netbeans/modules/debugger/jpda/truffle/frames/models/TruffleDVFrame.java b/java/debugger.jpda.truffle/src/org/netbeans/modules/debugger/jpda/truffle/frames/models/TruffleDVFrame.java new file mode 100644 index 0000000..a194c63 --- /dev/null +++ b/java/debugger.jpda.truffle/src/org/netbeans/modules/debugger/jpda/truffle/frames/models/TruffleDVFrame.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.debugger.jpda.truffle.frames.models; + +import java.net.URI; +import org.netbeans.modules.debugger.jpda.truffle.access.CurrentPCInfo; +import org.netbeans.modules.debugger.jpda.truffle.access.TruffleAccess; +import org.netbeans.modules.debugger.jpda.truffle.frames.TruffleStackFrame; +import org.netbeans.spi.debugger.ui.DebuggingView.DVFrame; +import org.netbeans.spi.debugger.ui.DebuggingView.DVThread; + +/** + * + * @author martin + */ +public final class TruffleDVFrame implements DVFrame { + + private final DVThread thread; + private final TruffleStackFrame truffleFrame; + + TruffleDVFrame(DVThread thread, TruffleStackFrame truffleFrame) { + this.thread = thread; + this.truffleFrame = truffleFrame; + } + + TruffleStackFrame getTruffleFrame() { + return truffleFrame; + } + + @Override + public String getName() { + return truffleFrame.getMethodName(); + } + + @Override + public DVThread getThread() { + return thread; + } + + @Override + public void makeCurrent() { + CurrentPCInfo currentPCInfo = TruffleAccess.getCurrentPCInfo(truffleFrame.getThread()); + if (currentPCInfo != null) { + currentPCInfo.setSelectedStackFrame(truffleFrame); + } + } + + @Override + public URI getSourceURI() { + return truffleFrame.getSourcePosition().getSource().getURI(); + } + + @Override + public int getLine() { + return truffleFrame.getSourcePosition().getStartLine(); + } + + @Override + public int getColumn() { + return truffleFrame.getSourcePosition().getStartColumn(); + } + +} diff --git a/java/debugger.jpda.ui/nbproject/project.xml b/java/debugger.jpda.ui/nbproject/project.xml index c905198..023dada 100644 --- a/java/debugger.jpda.ui/nbproject/project.xml +++ b/java/debugger.jpda.ui/nbproject/project.xml @@ -210,7 +210,7 @@ <compile-dependency/> <run-dependency> <release-version>1</release-version> - <specification-version>2.49</specification-version> + <specification-version>2.65</specification-version> </run-dependency> </dependency> <dependency> @@ -359,6 +359,7 @@ <package>org.netbeans.modules.debugger.jpda.ui</package> <package>org.netbeans.modules.debugger.jpda.ui.options</package> <package>org.netbeans.modules.debugger.jpda.ui.breakpoints</package> + <package>org.netbeans.modules.debugger.jpda.ui.debugging</package> </friend-packages> </data> </configuration> diff --git a/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/debugging/DebuggingViewSupportImpl.java b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/debugging/DebuggingViewSupportImpl.java index c7ba6ad..7bbdb69 100644 --- a/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/debugging/DebuggingViewSupportImpl.java +++ b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/debugging/DebuggingViewSupportImpl.java @@ -36,6 +36,7 @@ import org.netbeans.api.debugger.jpda.DeadlockDetector; import org.netbeans.api.debugger.jpda.JPDADebugger; import org.netbeans.api.debugger.jpda.JPDAThread; import org.netbeans.api.debugger.jpda.JPDAThreadGroup; +import org.netbeans.api.debugger.jpda.ThreadsCollector; import org.netbeans.modules.debugger.jpda.JPDADebuggerImpl; import org.netbeans.modules.debugger.jpda.models.JPDAThreadGroupImpl; import org.netbeans.modules.debugger.jpda.models.JPDAThreadImpl; @@ -43,6 +44,7 @@ import org.netbeans.modules.debugger.jpda.ui.models.DebuggingNodeModel; import org.netbeans.modules.debugger.jpda.util.WeakCacheMap; import org.netbeans.spi.debugger.ContextProvider; import org.netbeans.spi.debugger.ui.DebuggingView; +import org.netbeans.spi.debugger.ui.DebuggingView.DVFrame; import org.netbeans.spi.viewmodel.UnknownTypeException; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; @@ -61,7 +63,9 @@ public class DebuggingViewSupportImpl extends DebuggingView.DVSupport { public DebuggingViewSupportImpl(ContextProvider lookupProvider) { debugger = (JPDADebuggerImpl) lookupProvider.lookupFirst(null, JPDADebugger.class); ChangeListener chl = new ChangeListener(); - debugger.addPropertyChangeListener(chl); + debugger.addPropertyChangeListener(JPDADebugger.PROP_STATE, chl); + debugger.addPropertyChangeListener(JPDADebugger.PROP_CURRENT_THREAD, chl); + debugger.getThreadsCollector().addPropertyChangeListener(chl); debugger.getThreadsCollector().getDeadlockDetector().addPropertyChangeListener(chl); } @@ -216,6 +220,14 @@ public class DebuggingViewSupportImpl extends DebuggingView.DVSupport { return dvGroups; } + protected int getFrameCount(JPDADVThread thread) { + return thread.getKey().getStackDepth(); + } + + protected List<DVFrame> getFrames(JPDADVThread thread, int from, int to) { + return JPDADVThread.getFrames(thread, from, to); + } + private class ChangeListener implements PropertyChangeListener { private STATE state = STATE.DISCONNECTED; @@ -223,12 +235,12 @@ public class DebuggingViewSupportImpl extends DebuggingView.DVSupport { @Override public void propertyChange(PropertyChangeEvent evt) { String propertyName = evt.getPropertyName(); - if (JPDADebugger.PROP_THREAD_STARTED.equals(propertyName)) { + if (ThreadsCollector.PROP_THREAD_STARTED.equals(propertyName)) { firePropertyChange(DebuggingView.DVSupport.PROP_THREAD_STARTED, get((JPDAThreadImpl) evt.getOldValue()), get((JPDAThreadImpl) evt.getNewValue())); } else - if (JPDADebugger.PROP_THREAD_DIED.equals(propertyName)) { + if (ThreadsCollector.PROP_THREAD_DIED.equals(propertyName)) { firePropertyChange(DebuggingView.DVSupport.PROP_THREAD_DIED, get((JPDAThreadImpl) evt.getOldValue()), get((JPDAThreadImpl) evt.getNewValue())); @@ -238,6 +250,16 @@ public class DebuggingViewSupportImpl extends DebuggingView.DVSupport { get((JPDAThreadImpl) evt.getOldValue()), get((JPDAThreadImpl) evt.getNewValue())); } else + if (ThreadsCollector.PROP_THREAD_SUSPENDED.equals(propertyName)) { + firePropertyChange(DebuggingView.DVSupport.PROP_THREAD_SUSPENDED, + get((JPDAThreadImpl) evt.getOldValue()), + get((JPDAThreadImpl) evt.getNewValue())); + } else + if (ThreadsCollector.PROP_THREAD_RESUMED.equals(propertyName)) { + firePropertyChange(DebuggingView.DVSupport.PROP_THREAD_RESUMED, + get((JPDAThreadImpl) evt.getOldValue()), + get((JPDAThreadImpl) evt.getNewValue())); + } else if (JPDADebugger.PROP_STATE.equals(propertyName)) { int ds = debugger.getState(); if (ds == JPDADebugger.STATE_RUNNING && this.state != STATE.RUNNING) { diff --git a/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/debugging/JPDADVFrame.java b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/debugging/JPDADVFrame.java new file mode 100644 index 0000000..fce4ac0 --- /dev/null +++ b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/debugging/JPDADVFrame.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.debugger.jpda.ui.debugging; + +import java.net.URI; +import java.net.URISyntaxException; +import org.netbeans.api.debugger.Session; +import org.netbeans.api.debugger.jpda.CallStackFrame; +import org.netbeans.modules.debugger.jpda.JPDADebuggerImpl; +import org.netbeans.modules.debugger.jpda.SourcePath; +import org.netbeans.modules.debugger.jpda.jdi.InternalExceptionWrapper; +import org.netbeans.modules.debugger.jpda.jdi.InvalidStackFrameExceptionWrapper; +import org.netbeans.modules.debugger.jpda.jdi.ObjectCollectedExceptionWrapper; +import org.netbeans.modules.debugger.jpda.jdi.VMDisconnectedExceptionWrapper; +import org.netbeans.modules.debugger.jpda.models.JPDAThreadImpl; +import org.netbeans.modules.debugger.jpda.ui.models.CallStackNodeModel; +import org.netbeans.spi.debugger.ui.DebuggingView.DVFrame; +import org.netbeans.spi.debugger.ui.DebuggingView.DVThread; +import org.openide.util.Exceptions; + +/** + * + * @author Martin Entlicher + */ +public final class JPDADVFrame implements DVFrame { + + private final DVThread thread; + private final CallStackFrame stackFrame; + + JPDADVFrame(DVThread thread, CallStackFrame stackFrame) { + this.thread = thread; + this.stackFrame = stackFrame; + } + + public CallStackFrame getCallStackFrame() { + return stackFrame; + } + + @Override + public String getName() { + String name = CallStackNodeModel.getCSFName(((JPDAThreadImpl) stackFrame.getThread()).getDebugger().getSession(), stackFrame, false); + int colon = name.lastIndexOf(':'); + if (colon > 0 && hasDigitsOnly(name.substring(colon + 1))) { + name = name.substring(0, colon); + } + name += "()"; + return name; + } + + private static boolean hasDigitsOnly(String string) { + for (int i = 0; i < string.length(); i++) { + if (!Character.isDigit(string.charAt(i))) { + return false; + } + } + return !string.isEmpty(); + } + + @Override + public DVThread getThread() { + return thread; + } + + @Override + public void makeCurrent() { + stackFrame.makeCurrent(); + } + + @Override + public URI getSourceURI() { + JPDADebuggerImpl debugger = ((JPDAThreadImpl) stackFrame.getThread()).getDebugger(); + Session session = debugger.getSession(); + String language = session.getCurrentLanguage(); + SourcePath sourcePath = debugger.getEngineContext(); + String url = null; + try { + url = sourcePath.getURL(stackFrame, language); + } catch (InternalExceptionWrapper | InvalidStackFrameExceptionWrapper | ObjectCollectedExceptionWrapper | VMDisconnectedExceptionWrapper e) { + // url stays null + } + if (url != null) { + try { + return new URI(url); + } catch (URISyntaxException ex) { + Exceptions.printStackTrace(ex); + } + } + return null; + } + + @Override + public int getLine() { + return stackFrame.getLineNumber(stackFrame.getDefaultStratum()); + } + + @Override + public int getColumn() { + return -1; + } + +} diff --git a/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/debugging/JPDADVThread.java b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/debugging/JPDADVThread.java index 2b694fb..fcbc308 100644 --- a/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/debugging/JPDADVThread.java +++ b/java/debugger.jpda.ui/src/org/netbeans/modules/debugger/jpda/ui/debugging/JPDADVThread.java @@ -22,13 +22,23 @@ package org.netbeans.modules.debugger.jpda.ui.debugging; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.AbstractList; -import java.util.LinkedList; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Supplier; + +import com.sun.jdi.AbsentInformationException; + import org.netbeans.api.debugger.Breakpoint; +import org.netbeans.api.debugger.jpda.CallStackFrame; import org.netbeans.api.debugger.jpda.JPDAThread; + import org.netbeans.modules.debugger.jpda.models.JPDAThreadImpl; import org.netbeans.modules.debugger.jpda.util.WeakCacheMap; + +import org.netbeans.spi.debugger.ui.DebuggingView; +import org.netbeans.spi.debugger.ui.DebuggingView.DVFrame; import org.netbeans.spi.debugger.ui.DebuggingView.DVSupport; import org.netbeans.spi.debugger.ui.DebuggingView.DVThread; @@ -36,13 +46,13 @@ import org.netbeans.spi.debugger.ui.DebuggingView.DVThread; * * @author Martin Entlicher */ -public class JPDADVThread implements DVThread, WeakCacheMap.KeyedValue<JPDAThreadImpl> { +public final class JPDADVThread implements DVThread, WeakCacheMap.KeyedValue<JPDAThreadImpl>, Supplier<JPDAThread> { private final DebuggingViewSupportImpl dvSupport; private final JPDAThreadImpl t; private PropertyChangeProxyListener proxyListener; - public JPDADVThread(DebuggingViewSupportImpl dvSupport, JPDAThreadImpl t) { + JPDADVThread(DebuggingViewSupportImpl dvSupport, JPDAThreadImpl t) { this.dvSupport = dvSupport; this.t = t; } @@ -73,6 +83,40 @@ public class JPDADVThread implements DVThread, WeakCacheMap.KeyedValue<JPDAThrea } @Override + public int getFrameCount() { + return dvSupport.getFrameCount(this); + } + + @Override + public List<DVFrame> getFrames() { + return getFrames(0, Integer.MAX_VALUE); + } + + @Override + public List<DVFrame> getFrames(int from, int to) { + return dvSupport.getFrames(this, from, to); + } + + static List<DVFrame> getFrames(JPDADVThread thread, int from, int to) { + int depth = thread.t.getStackDepth(); + if (depth == 0 || depth <= from) { + return Collections.emptyList(); + } + //to = Math.min(to, depth); + CallStackFrame[] callStack; + try { + callStack = thread.t.getCallStack(from, to); + } catch (AbsentInformationException ex) { + return Collections.emptyList(); + } + List<DebuggingView.DVFrame> frames = new ArrayList<>(callStack.length); + for (int i = 0; i < callStack.length; i++) { + frames.add(new JPDADVFrame(thread, callStack[i])); + } + return Collections.unmodifiableList(frames); + } + + @Override public DVSupport getDVSupport() { return dvSupport; } @@ -125,7 +169,12 @@ public class JPDADVThread implements DVThread, WeakCacheMap.KeyedValue<JPDAThrea public JPDAThreadImpl getKey() { return t; } - + + @Override + public JPDAThread get() { + return t; + } + private class ThreadListDelegate extends AbstractList<DVThread> { private final List<JPDAThread> threads; --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists