Skip to content

Commit

Permalink
Cont worked on Node.js debugger not showing all locals properly
Browse files Browse the repository at this point in the history
  • Loading branch information
eranif committed Sep 7, 2015
1 parent d59b3ba commit 0c5ff1f
Show file tree
Hide file tree
Showing 11 changed files with 194 additions and 30 deletions.
4 changes: 2 additions & 2 deletions LiteEditor.workspace
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
<Project Name="wxsqlite3" ConfigName="Win_x86_Release"/>
<Project Name="ZoomNavigator" ConfigName="Win_x86_Release"/>
</WorkspaceConfiguration>
<WorkspaceConfiguration Name="CMake_Release" Selected="yes">
<WorkspaceConfiguration Name="CMake_Release" Selected="no">
<Project Name="ZoomNavigator" ConfigName="DebugUnicode"/>
<Project Name="wxsqlite3" ConfigName="Win_x86_Release"/>
<Project Name="wxshapeframework" ConfigName="Win_x86_Release"/>
Expand Down Expand Up @@ -324,7 +324,7 @@
<Project Name="wxsqlite3" ConfigName="Win_x64_Release"/>
<Project Name="ZoomNavigator" ConfigName="Win_x64_Release"/>
</WorkspaceConfiguration>
<WorkspaceConfiguration Name="Win_x64_Debug" Selected="no">
<WorkspaceConfiguration Name="Win_x64_Debug" Selected="yes">
<Project Name="abbreviation" ConfigName="Win_x64_Debug"/>
<Project Name="CallGraph" ConfigName="Win_x64_Debug"/>
<Project Name="CMakePlugin" ConfigName="Win_x64_Debug"/>
Expand Down
21 changes: 21 additions & 0 deletions WebTools/NodeJSDebugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "NodeJSWorkspaceUserConfiguration.h"
#include <wx/log.h>
#include "NodeJSEvaluateExprHandler.h"
#include "NodeJSLookupHandler.h"

#define CHECK_RUNNING() \
if(!IsConnected()) return
Expand Down Expand Up @@ -584,3 +585,23 @@ void NodeJSDebugger::OnEvalExpression(clDebugEvent& event)
m_socket->WriteRequest(
request, new NodeJSEvaluateExprHandler(event.GetString(), NodeJSEvaluateExprHandler::kContextConsole));
}

void NodeJSDebugger::Lookup(const std::vector<int>& handles)
{
JSONElement request = JSONElement::createObject();
request.addProperty("type", "request");
request.addProperty("command", "lookup");

JSONElement args = JSONElement::createObject("arguments");
request.append(args);

JSONElement arrHandles = JSONElement::createArray("handles");
args.append(arrHandles);

for(size_t i = 0; i < handles.size(); ++i) {
arrHandles.arrayAppend(JSONElement("", handles.at(i), cJSON_Number));
}

// Write the command
m_socket->WriteRequest(request, new NodeJSLookupHandler());
}
7 changes: 6 additions & 1 deletion WebTools/NodeJSDebugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,12 @@ class NodeJSDebugger : public wxEvtHandler
* @brief load the content of a given file name
*/
void GetCurrentFrameSource(const wxString& filename, int line);


/**
* @brief The request lookup is used to lookup objects based on their handle
*/
void Lookup(const std::vector<int>& handles);

//--------------------------------------------------
// API END
//--------------------------------------------------
Expand Down
130 changes: 107 additions & 23 deletions WebTools/NodeJSDebuggerPane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,23 @@
#include "NoteJSWorkspace.h"
#include "imanager.h"

class NodeJSLocalClientData : public wxClientData
{
NodeJSDebuggerPane::Handle m_handle;
bool m_expanded;

public:
NodeJSLocalClientData(const NodeJSDebuggerPane::Handle& h)
: m_handle(h)
, m_expanded(false)
{
}
void SetHandle(const NodeJSDebuggerPane::Handle& handle) { this->m_handle = handle; }
const NodeJSDebuggerPane::Handle& GetHandle() const { return m_handle; }
void SetExpanded(bool expanded) { this->m_expanded = expanded; }
bool IsExpanded() const { return m_expanded; }
};

NodeJSDebuggerPane::NodeJSDebuggerPane(wxWindow* parent)
: NodeJSDebuggerPaneBase(parent)
{
Expand All @@ -20,6 +37,7 @@ NodeJSDebuggerPane::NodeJSDebuggerPane(wxWindow* parent)
EventNotifier::Get()->Bind(wxEVT_NODEJS_DEBUGGER_LOST_INTERACT, &NodeJSDebuggerPane::OnLostControl, this);
EventNotifier::Get()->Bind(wxEVT_NODEJS_DEBUGGER_CONSOLE_LOG, &NodeJSDebuggerPane::OnConsoleLog, this);
EventNotifier::Get()->Bind(wxEVT_NODEJS_DEBUGGER_STARTED, &NodeJSDebuggerPane::OnSessionStarted, this);
EventNotifier::Get()->Bind(wxEVT_NODEJS_DEBUGGER_STOPPED, &NodeJSDebuggerPane::OnSessionStopped, this);
EventNotifier::Get()->Bind(wxEVT_NODEJS_DEBUGGER_EXCEPTION_THROWN, &NodeJSDebuggerPane::OnExceptionThrown, this);
EventNotifier::Get()->Bind(wxEVT_NODEJS_DEBUGGER_SELECT_FRAME, &NodeJSDebuggerPane::OnFrameSelected, this);
EventNotifier::Get()->Bind(
Expand Down Expand Up @@ -191,33 +209,27 @@ void NodeJSDebuggerPane::ClearCallstack()
m_dvListCtrlCallstack->Enable(true);
}

void NodeJSDebuggerPane::AddLocal(wxDataViewItem& parent, const wxString& name, int refId, int depth)
wxDataViewItem NodeJSDebuggerPane::AddLocal(const wxDataViewItem& parent, const wxString& name, int refId)
{
if(depth >= 20) {
// don't go into infinite recurse
return;
}

wxVector<wxVariant> cols;
cols.push_back(name);

// extract the value
if(m_handles.count(refId)) {
wxVector<wxVariant> cols;
Handle h = m_handles.find(refId)->second;
cols.push_back(name);
cols.push_back(h.type);
cols.push_back(h.value);
wxDataViewItem child = m_dataviewLocalsModel->AppendItem(parent, cols);
wxDataViewItem child = m_dataviewLocalsModel->AppendItem(parent, cols, new NodeJSLocalClientData(h));

if(!h.properties.empty()) {
std::for_each(h.properties.begin(), h.properties.end(), [&](const std::pair<int, wxString>& p) {
AddLocal(child, p.second, p.first, depth + 1);
});
cols.clear();
cols.push_back("<dummy>");
cols.push_back("<dummy>");
cols.push_back("<dummy>");
m_dataviewLocalsModel->AppendItem(child, cols);
}
} else {
cols.push_back("");
cols.push_back("");
m_dataviewLocalsModel->AppendItem(parent, cols);
return child;
}
return wxDataViewItem();
}

void NodeJSDebuggerPane::BuildArguments(const JSONElement& json)
Expand All @@ -232,8 +244,7 @@ void NodeJSDebuggerPane::BuildArguments(const JSONElement& json)
int count = arr.arraySize();
for(int i = 0; i < count; ++i) {
JSONElement local = arr.arrayItem(i);
AddLocal(
locals, local.namedObject("name").toString(), local.namedObject("value").namedObject("ref").toInt(), 0);
AddLocal(locals, local.namedObject("name").toString(), local.namedObject("value").namedObject("ref").toInt());
}

if(m_dataviewLocalsModel->HasChildren(locals)) {
Expand All @@ -253,8 +264,7 @@ void NodeJSDebuggerPane::BuildLocals(const JSONElement& json)
int count = arr.arraySize();
for(int i = 0; i < count; ++i) {
JSONElement local = arr.arrayItem(i);
AddLocal(
locals, local.namedObject("name").toString(), local.namedObject("value").namedObject("ref").toInt(), 0);
AddLocal(locals, local.namedObject("name").toString(), local.namedObject("value").namedObject("ref").toInt());
}

if(m_dataviewLocalsModel->HasChildren(locals)) {
Expand Down Expand Up @@ -369,7 +379,7 @@ void NodeJSDebuggerPane::OnExpressionEvaluated(clDebugEvent& event)
event.Skip();
wxString message;
message << "eval(" << m_textCtrlExpression->GetValue() << "):\n" << event.GetString();

wxString currentText = m_consoleLog->GetValue();
if(!currentText.EndsWith("\n")) {
message.Prepend("\n");
Expand All @@ -379,7 +389,81 @@ void NodeJSDebuggerPane::OnExpressionEvaluated(clDebugEvent& event)
}
m_consoleLog->AppendText(message);
m_consoleLog->ScrollToEnd();

// Restore the focus to the text control
m_textCtrlExpression->CallAfter(&wxTextCtrl::SetFocus);
}

void NodeJSDebuggerPane::OnLocalExpanding(wxDataViewEvent& event)
{
event.Skip();
CHECK_ITEM_RET(event.GetItem());
NodeJSLocalClientData* d =
dynamic_cast<NodeJSLocalClientData*>(m_dataviewLocalsModel->GetClientObject(event.GetItem()));

CHECK_PTR_RET(d);
if(d->IsExpanded()) {
// nothing to be done here
return;
}

wxDataViewItemArray children;
if(m_dataviewLocalsModel->GetChildren(event.GetItem(), children) != 1) return;

d->SetExpanded(true);

// Prepare list of refs that we don't have
std::map<int, wxString> unknownRefs;
std::map<int, wxString> knownRefs;
const Handle& h = d->GetHandle();
std::for_each(h.properties.begin(), h.properties.end(), [&](const std::pair<int, wxString>& p) {
if(m_handles.count(p.first) == 0) {
unknownRefs.insert(p);
} else {
knownRefs.insert(p);
}
});
CallAfter(&NodeJSDebuggerPane::DoAddKnownRefs, knownRefs, event.GetItem());
CallAfter(&NodeJSDebuggerPane::DoAddUnKnownRefs, unknownRefs, event.GetItem());
// Delete the dummy node
CallAfter(&NodeJSDebuggerPane::DoDeleteLocalItemAfter, children.Item(0));
}

void NodeJSDebuggerPane::DoDeleteLocalItemAfter(const wxDataViewItem& item) { m_dataviewLocalsModel->DeleteItem(item); }

void NodeJSDebuggerPane::DoAddKnownRefs(const std::map<int, wxString>& refs, const wxDataViewItem& parent)
{
std::for_each(
refs.begin(), refs.end(), [&](const std::pair<int, wxString>& p) { AddLocal(parent, p.second, p.first); });
}

void NodeJSDebuggerPane::DoAddUnKnownRefs(const std::map<int, wxString>& refs, const wxDataViewItem& parent)
{
if(!NodeJSWorkspace::Get()->GetDebugger()) return;

std::vector<int> handles;
std::for_each(refs.begin(), refs.end(), [&](const std::pair<int, wxString>& p) {
wxVector<wxVariant> cols;
cols.push_back(p.second);
cols.push_back("?");
cols.push_back("?");
wxDataViewItem child = m_dataviewLocalsModel->AppendItem(parent, cols);
// TODO: add a dummy child to this item, incase it has children as well
PendingLookup pl;
pl.item = child;
pl.name = p.second;
pl.refID = p.first;
m_pendingLookupRefs.push_back(pl);
handles.push_back(p.first);
});
NodeJSWorkspace::Get()->GetDebugger()->Lookup(handles);
}

void NodeJSDebuggerPane::OnSessionStopped(clDebugEvent& event)
{
event.Skip();
ClearCallstack();
m_dataviewLocalsModel->Clear();
m_pendingLookupRefs.clear();
m_handles.clear();
}
18 changes: 15 additions & 3 deletions WebTools/NodeJSDebuggerPane.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,35 @@ class NodeJSDebuggerPane : public NodeJSDebuggerPaneBase
}
};

public:
struct Handle {
wxString name;
wxString value;
wxString type;
std::map<int, wxString> properties;
std::map<int, wxString> properties; // ref:name
};

struct PendingLookup {
wxDataViewItem item;
int refID;
wxString name;
};

std::map<int, Handle> m_handles;
std::vector<PendingLookup> m_pendingLookupRefs;

protected:
virtual void OnLocalExpanding(wxDataViewEvent& event);
virtual void OnEvaluateExpression(wxCommandEvent& event);
virtual void OnBreakpointSelected(wxDataViewEvent& event);
void ClearCallstack();
void BuildLocals(const JSONElement& json);
void BuildArguments(const JSONElement& json);
void AddLocal(wxDataViewItem& parent, const wxString& name, int refId, int depth);
wxDataViewItem AddLocal(const wxDataViewItem& parent, const wxString& name, int refId);
void ParseRefsArray(const JSONElement& refs);
void DoOpenFile(const wxString& filename, int line);
void DoDeleteLocalItemAfter(const wxDataViewItem& item);
void DoAddKnownRefs(const std::map<int, wxString>& refs, const wxDataViewItem& parent);
void DoAddUnKnownRefs(const std::map<int, wxString>& refs, const wxDataViewItem& parent);

protected:
void OnItemActivated(wxDataViewEvent& event);
Expand All @@ -46,6 +57,7 @@ class NodeJSDebuggerPane : public NodeJSDebuggerPaneBase
void OnLostControl(clDebugEvent& event);
void OnConsoleLog(clDebugEvent& event);
void OnSessionStarted(clDebugEvent& event);
void OnSessionStopped(clDebugEvent& event);
void OnExceptionThrown(clDebugEvent& event);
void OnUpdateDebuggerView(clDebugEvent& event);
void OnFrameSelected(clDebugEvent& event);
Expand Down
13 changes: 13 additions & 0 deletions WebTools/NodeJSLookupHandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "NodeJSLookupHandler.h"

NodeJSLookupHandler::NodeJSLookupHandler()
{
}

NodeJSLookupHandler::~NodeJSLookupHandler()
{
}

void NodeJSLookupHandler::Process(NodeJSDebugger* debugger, const wxString& output)
{
}
17 changes: 17 additions & 0 deletions WebTools/NodeJSLookupHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef NODEJSLOOKUPHANDLER_H
#define NODEJSLOOKUPHANDLER_H

#include "NodeJSHandlerBase.h" // Base class: NodeJSHandlerBase

class NodeJSLookupHandler : public NodeJSHandlerBase
{
public:
NodeJSLookupHandler();
virtual ~NodeJSLookupHandler();

public:
virtual
void Process(NodeJSDebugger* debugger, const wxString& output);
};

#endif // NODEJSLOOKUPHANDLER_H
2 changes: 2 additions & 0 deletions WebTools/WebTools.project
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@
<File Name="NodeJSGetScriptHandler.cpp"/>
<File Name="NodeJSEvaluateExprHandler.h"/>
<File Name="NodeJSEvaluateExprHandler.cpp"/>
<File Name="NodeJSLookupHandler.h"/>
<File Name="NodeJSLookupHandler.cpp"/>
</VirtualDirectory>
<File Name="NodeJSDebuggerPane.h"/>
<File Name="NodeJSDebuggerPane.cpp"/>
Expand Down
2 changes: 2 additions & 0 deletions WebTools/WebToolsBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ NodeJSDebuggerPaneBase::NodeJSDebuggerPaneBase(wxWindow* parent, wxWindowID id,
}
CentreOnParent(wxBOTH);
// Connect events
m_dataviewLocals->Connect(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING, wxDataViewEventHandler(NodeJSDebuggerPaneBase::OnLocalExpanding), NULL, this);
m_dvListCtrlCallstack->Connect(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, wxDataViewEventHandler(NodeJSDebuggerPaneBase::OnItemActivated), NULL, this);
m_dvListCtrlCallstack->Connect(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler(NodeJSDebuggerPaneBase::OnItemActivated), NULL, this);
m_textCtrlExpression->Connect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(NodeJSDebuggerPaneBase::OnEvaluateExpression), NULL, this);
Expand All @@ -468,6 +469,7 @@ NodeJSDebuggerPaneBase::NodeJSDebuggerPaneBase(wxWindow* parent, wxWindowID id,

NodeJSDebuggerPaneBase::~NodeJSDebuggerPaneBase()
{
m_dataviewLocals->Disconnect(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING, wxDataViewEventHandler(NodeJSDebuggerPaneBase::OnLocalExpanding), NULL, this);
m_dvListCtrlCallstack->Disconnect(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, wxDataViewEventHandler(NodeJSDebuggerPaneBase::OnItemActivated), NULL, this);
m_dvListCtrlCallstack->Disconnect(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler(NodeJSDebuggerPaneBase::OnItemActivated), NULL, this);
m_textCtrlExpression->Disconnect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(NodeJSDebuggerPaneBase::OnEvaluateExpression), NULL, this);
Expand Down
1 change: 1 addition & 0 deletions WebTools/WebToolsBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ class NodeJSDebuggerPaneBase : public wxPanel
wxDataViewListCtrl* m_dvListCtrlBreakpoints;

protected:
virtual void OnLocalExpanding(wxDataViewEvent& event) { event.Skip(); }
virtual void OnItemActivated(wxDataViewEvent& event) { event.Skip(); }
virtual void OnEvaluateExpression(wxCommandEvent& event) { event.Skip(); }
virtual void OnBreakpointSelected(wxDataViewEvent& event) { event.Skip(); }
Expand Down
9 changes: 8 additions & 1 deletion WebTools/WebToolsBase.wxcp
Original file line number Diff line number Diff line change
Expand Up @@ -3224,7 +3224,14 @@
"m_label": "Container Item Has Columns",
"m_value": true
}],
"m_events": [],
"m_events": [{
"m_eventName": "wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING",
"m_eventClass": "wxDataViewEvent",
"m_eventHandler": "wxDataViewEventHandler",
"m_functionNameAndSignature": "OnLocalExpanding(wxDataViewEvent& event)",
"m_description": "Process a wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING event",
"m_noBody": false
}],
"m_children": [{
"m_type": 4472,
"proportion": 0,
Expand Down

0 comments on commit 0c5ff1f

Please sign in to comment.