fix advising of script node being re-initialized in new context, and other fixes
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi
index 57c85c5..0defe23 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi
Binary files differ
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireBPManager.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireBPManager.cpp
index bf4fb5e..f6a828b 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireBPManager.cpp
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireBPManager.cpp
@@ -418,8 +418,7 @@
while (iterator != m_breakpoints->end()) {
CrossfireBreakpoint* breakpoint = iterator->second;
if (breakpoint->appliesToUrl(url)) {
- bool success = target->setBreakpoint(breakpoint);
- // TODO it looks like the result of the above line was to be used for something
+ target->setBreakpoint(breakpoint);
}
iterator++;
}
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp
index 1b10614..6e0db2d 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp
@@ -199,7 +199,6 @@
std::map<IDebugApplicationNode*, PendingScriptLoad*>::iterator iterator = m_pendingScriptLoads->begin();
while (iterator != m_pendingScriptLoads->end()) {
iterator->first->Release();
- iterator->second->detach();
iterator->second->Release();
iterator++;
}
@@ -1073,18 +1072,10 @@
bool CrossfireContext::createValueForScript(IDebugApplicationNode* node, bool includeSource, bool failIfEmpty, Value** _value) {
*_value = NULL;
- URL* url = NULL;
- if (!getScriptUrl(node, &url)) {
- Logger::error("CrossfireContext.createValueForScript(): unknown script");
- delete url;
- return false;
- }
-
CComPtr<IDebugDocument> document = NULL;
HRESULT hr = node->GetDocument(&document);
if (FAILED(hr)) {
Logger::error("CrossfireContext.createValueForScript(): GetDocument() failed", hr);
- delete url;
return false;
}
@@ -1092,7 +1083,6 @@
hr = document->QueryInterface(IID_IDebugDocumentText, (void**)&documentText);
if (FAILED(hr)) {
Logger::error("CrossfireContext.createValueForScript(): QI(IDebugDocumentText) failed", hr);
- delete url;
return false;
}
@@ -1101,11 +1091,15 @@
hr = documentText->GetSize(&numLines, &numChars);
if (FAILED(hr)) {
Logger::error("CrossfireContext.createValueForScript(): GetSize() failed", hr);
- delete url;
return false;
}
if (failIfEmpty && numChars == 0) {
- delete url;
+ return false;
+ }
+
+ URL* url = NULL;
+ if (!getScriptUrl(node, &url)) {
+ Logger::error("CrossfireContext.createValueForScript(): unknown script");
return false;
}
@@ -1570,6 +1564,10 @@
delete[] string;
}
+ if (!url.isValid()) {
+ return false;
+ }
+
if (!m_scriptNodes) {
m_scriptNodes = new std::map<std::wstring, IDebugApplicationNode*>;
}
@@ -1633,20 +1631,38 @@
return true;
}
-bool CrossfireContext::scriptInitialized(IDebugApplicationNode *applicationNode) {
+bool CrossfireContext::scriptInitialized(IDebugApplicationNode *applicationNode, bool isFromAnotherContext) {
+ /*
+ * When navigating from one page to another, the first script node for the new
+ * page is initialized while the context for the old page is still active, and
+ * therefore becomes registered in the wrong context. The CrossfireServer works
+ * around this by re-initializing the script node in the new context where it
+ * belongs. This workaround is aided here by keeping a reference to the last
+ * script node that has been initialized from the document tree (but not from
+ * another context) in case it needs to be accessible to the CrossfireServer for
+ * re-initialization in a new context.
+ */
if (m_lastInitializedScriptNode) {
m_lastInitializedScriptNode->Release();
+ m_lastInitializedScriptNode = NULL;
}
- m_lastInitializedScriptNode = applicationNode;
- m_lastInitializedScriptNode->AddRef();
+ if (!isFromAnotherContext) {
+ m_lastInitializedScriptNode = applicationNode;
+ m_lastInitializedScriptNode->AddRef();
+ }
registerScript(applicationNode, false);
+ scriptLoaded(applicationNode, true);
- if (!scriptLoaded(applicationNode)) {
- /*
- * The script's content has not been loaded yet, so create a listener
- * object that will invoke #scriptLoaded() when this happens
- */
+ /*
+ * Script loading is typically not complete when a script node is initialized, and
+ * there is no way to determine whether it is complete, so create a listener that
+ * will repeatedly invoke #scriptLoaded() as loading of the script progresses.
+ *
+ * This is not done for scripts from another context that are being re-initialized
+ * here because such scripts are advised when this context's debugger is created.
+ */
+ if (!isFromAnotherContext) {
CComObject<PendingScriptLoad>* pendingScriptLoad = NULL;
HRESULT hr = CComObject<PendingScriptLoad>::CreateInstance(&pendingScriptLoad);
if (FAILED(hr)) {
@@ -1664,37 +1680,32 @@
return true;
}
-bool CrossfireContext::scriptLoaded(IDebugApplicationNode *applicationNode) {
- CrossfireBPManager* bpManager = m_server->getBreakpointManager();
-
+void CrossfireContext::scriptLoaded(IDebugApplicationNode *applicationNode, bool sendScriptLoadEvent) {
+ /* set the script's breakpoints if possible */
URL* url = NULL;
if (!getScriptUrl(applicationNode, &url)) {
Logger::error("CrossfireContext.scriptLoaded(): unknown script");
- return false;
+ return;
}
-
/*
* Incoming IBreakpointTarget method invocations should always be for this
- * application node, so store it temporarily so that's it's easily accessible,
+ * application node, so store it temporarily so that it's easily accessible,
* rather than repeatedly looking it up for each IBreakpointTarget invocation.
*/
+ CrossfireBPManager* bpManager = m_server->getBreakpointManager();
m_currentScriptNode = applicationNode;
bpManager->setBreakpointsForScript(url, this);
m_currentScriptNode = NULL;
delete url;
+ if (!sendScriptLoadEvent) {
+ return;
+ }
+
Value* script = NULL;
if (!createValueForScript(applicationNode, false, true, &script)) {
/* the script's content has probably not loaded yet */
- return false;
- }
-
- /* Ensure that there is not a PendingScriptLoad remaining for this node */
- std::map<IDebugApplicationNode*, PendingScriptLoad*>::iterator iterator = m_pendingScriptLoads->find(applicationNode);
- if (iterator != m_pendingScriptLoads->end()) {
- iterator->first->Release();
- iterator->second->Release();
- m_pendingScriptLoads->erase(iterator);
+ return;
}
CrossfireEvent onScriptEvent;
@@ -1704,7 +1715,6 @@
delete script;
onScriptEvent.setBody(&body);
sendEvent(&onScriptEvent);
- return true;
}
void CrossfireContext::sendEvent(CrossfireEvent* eventObj) {
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h
index 2dda24d..5e97574 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h
@@ -45,8 +45,8 @@
virtual wchar_t* getUrl();
virtual void installBreakpoints(std::vector<Value*>* breakpoints);
virtual bool performRequest(CrossfireRequest* request);
- virtual bool scriptInitialized(IDebugApplicationNode *applicationNode);
- virtual bool scriptLoaded(IDebugApplicationNode *applicationNode);
+ virtual bool scriptInitialized(IDebugApplicationNode *applicationNode, bool isFromAnotherContext);
+ virtual void scriptLoaded(IDebugApplicationNode *applicationNode, bool sendScriptLoadEvent);
/* IBreakpointTarget methods */
virtual bool breakpointAttributeChanged(unsigned int handle, wchar_t* name, Value* value);
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireServer.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireServer.cpp
index d2ed0f0..b56ce1e 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireServer.cpp
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireServer.cpp
@@ -189,7 +189,7 @@
CrossfireContext* context = new CrossfireContext(processId, url, this);
m_contexts->insert(std::pair<DWORD,CrossfireContext*> (processId, context));
if (scriptNode) {
- context->scriptInitialized(scriptNode);
+ context->scriptInitialized(scriptNode, true);
scriptNode->Release();
}
eventContextCreated(context);
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp
index dfe3901..031c5af 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp
@@ -88,7 +88,7 @@
Logger::error("IEDebugger.onAddChild(): GetName() failed", hr);
} else {
if (wcscmp(bstrUrl, ABOUT_BLANK) != 0) {
- m_context->scriptInitialized(prddpChild);
+ m_context->scriptInitialized(prddpChild, false);
}
}
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.cpp
index 67d1c81..4f6dae7 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.cpp
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.cpp
@@ -34,9 +34,10 @@
}
STDMETHODIMP PendingScriptLoad::onInsertText(ULONG cCharacterPosition, ULONG cNumToInsert) {
- if (m_context && m_context->scriptLoaded(m_applicationNode)) {
- detach();
+ if (m_context) {
+ m_context->scriptLoaded(m_applicationNode, cNumToInsert != 0);
}
+
return S_OK;
}
@@ -69,7 +70,13 @@
CComPtr<IConnectionPointContainer> connectionPointContainer = NULL;
hr = document->QueryInterface(IID_IConnectionPointContainer, (void**)&connectionPointContainer);
if (FAILED(hr)) {
- Logger::error("PendingScriptLoad.attach(): QI(IConnectionPointContainer) failed", hr);
+ /*
+ * It is expected that this will fail for nodes that represent code evaluations
+ * (eg.- anonymous code, eval code, script blocks).
+ */
+ if (hr != E_NOINTERFACE) {
+ Logger::error("PendingScriptLoad.attach(): QI(IConnectionPointContainer) failed", hr);
+ }
return false;
}
@@ -102,22 +109,21 @@
if (FAILED(hr)) {
/* The node is already destroyed, so nothing to unadvise on */
} else {
- CComPtr <IConnectionPointContainer> connectionPointContainer = NULL;
+ CComPtr<IConnectionPointContainer> connectionPointContainer = NULL;
hr = document->QueryInterface(IID_IConnectionPointContainer, (void**)&connectionPointContainer);
if (FAILED(hr)) {
Logger::error("PendingScriptLoad.detach(): QI(IID_IConnectionPointContainer) failed", hr);
- return false;
- }
- CComPtr <IConnectionPoint> connectionPoint = NULL;
- hr = connectionPointContainer->FindConnectionPoint(IID_IDebugDocumentTextEvents,&connectionPoint);
- if (FAILED(hr)) {
- Logger::error("PendingScriptLoad.detach(): FindConnectionPoint() failed", hr);
- return false;
- }
- hr = connectionPoint->Unadvise(m_cookie);
- if (FAILED(hr)) {
- Logger::error("PendingScriptLoad.detach(): Unadvise() failed", hr);
- return false;
+ } else {
+ CComPtr<IConnectionPoint> connectionPoint = NULL;
+ hr = connectionPointContainer->FindConnectionPoint(IID_IDebugDocumentTextEvents,&connectionPoint);
+ if (FAILED(hr)) {
+ Logger::error("PendingScriptLoad.detach(): FindConnectionPoint() failed", hr);
+ } else {
+ hr = connectionPoint->Unadvise(m_cookie);
+ if (FAILED(hr)) {
+ Logger::error("PendingScriptLoad.detach(): Unadvise() failed", hr);
+ }
+ }
}
}
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.h b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.h
index ff368b8..a7b4071 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.h
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.h
@@ -68,9 +68,9 @@
virtual bool detach();
private:
+ IDebugApplicationNode* m_applicationNode;
CrossfireContext* m_context;
DWORD m_cookie;
- IDebugApplicationNode* m_applicationNode;
};
OBJECT_ENTRY_AUTO(__uuidof(PendingScriptLoad), PendingScriptLoad)
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/URL.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/URL.cpp
index 9e63b03..08de997 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/URL.cpp
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/URL.cpp
@@ -19,14 +19,7 @@
URL::URL(wchar_t* urlString) {
m_value = NULL;
-
- if (urlString) {
- std::wstring string(urlString);
- if (!standardize(&string)) {
- return;
- }
- m_value = _wcsdup(string.c_str());
- }
+ setString(urlString);
}
URL::~URL() {