Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
33bed406
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
33bed406
编写于
10月 18, 2016
作者:
I
isidor
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
debug: introduce sessions in the debug model
上级
b42cf8c2
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
266 addition
and
199 deletion
+266
-199
src/vs/workbench/parts/debug/browser/debugActions.ts
src/vs/workbench/parts/debug/browser/debugActions.ts
+25
-19
src/vs/workbench/parts/debug/browser/debugEditorModelManager.ts
.../workbench/parts/debug/browser/debugEditorModelManager.ts
+5
-7
src/vs/workbench/parts/debug/common/debug.ts
src/vs/workbench/parts/debug/common/debug.ts
+10
-4
src/vs/workbench/parts/debug/common/debugModel.ts
src/vs/workbench/parts/debug/common/debugModel.ts
+114
-79
src/vs/workbench/parts/debug/common/debugSource.ts
src/vs/workbench/parts/debug/common/debugSource.ts
+9
-6
src/vs/workbench/parts/debug/common/debugViewModel.ts
src/vs/workbench/parts/debug/common/debugViewModel.ts
+2
-2
src/vs/workbench/parts/debug/electron-browser/debugService.ts
...vs/workbench/parts/debug/electron-browser/debugService.ts
+33
-31
src/vs/workbench/parts/debug/electron-browser/debugViewer.ts
src/vs/workbench/parts/debug/electron-browser/debugViewer.ts
+18
-8
src/vs/workbench/parts/debug/electron-browser/debugViews.ts
src/vs/workbench/parts/debug/electron-browser/debugViews.ts
+3
-2
src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts
...workbench/parts/debug/electron-browser/rawDebugSession.ts
+6
-6
src/vs/workbench/parts/debug/test/common/debugViewModel.test.ts
.../workbench/parts/debug/test/common/debugViewModel.test.ts
+5
-4
src/vs/workbench/parts/debug/test/common/mockDebugService.ts
src/vs/workbench/parts/debug/test/common/mockDebugService.ts
+5
-1
src/vs/workbench/parts/debug/test/node/debugModel.test.ts
src/vs/workbench/parts/debug/test/node/debugModel.test.ts
+31
-30
未找到文件。
src/vs/workbench/parts/debug/browser/debugActions.ts
浏览文件 @
33bed406
...
...
@@ -169,10 +169,11 @@ export class StepOverAction extends AbstractDebugAction {
}
public
run
(
thread
:
debug
.
IThread
):
TPromise
<
any
>
{
const
threadId
=
thread
&&
thread
instanceof
model
.
Thread
?
thread
.
threadId
:
this
.
debugService
.
getViewModel
().
getFocusedThreadId
();
if
(
!
thread
)
{
thread
=
this
.
debugService
.
getViewModel
().
getFocusedThread
();
}
return
this
.
debugService
.
next
(
threadId
);
return
this
.
debugService
.
next
(
thread
.
thread
Id
);
}
protected
isEnabled
(
state
:
debug
.
State
):
boolean
{
...
...
@@ -189,10 +190,11 @@ export class StepIntoAction extends AbstractDebugAction {
}
public
run
(
thread
:
debug
.
IThread
):
TPromise
<
any
>
{
const
threadId
=
thread
&&
thread
instanceof
model
.
Thread
?
thread
.
threadId
:
this
.
debugService
.
getViewModel
().
getFocusedThreadId
();
if
(
!
thread
)
{
thread
=
this
.
debugService
.
getViewModel
().
getFocusedThread
();
}
return
this
.
debugService
.
stepIn
(
threadId
);
return
this
.
debugService
.
stepIn
(
thread
.
thread
Id
);
}
protected
isEnabled
(
state
:
debug
.
State
):
boolean
{
...
...
@@ -209,10 +211,11 @@ export class StepOutAction extends AbstractDebugAction {
}
public
run
(
thread
:
debug
.
IThread
):
TPromise
<
any
>
{
const
threadId
=
thread
&&
thread
instanceof
model
.
Thread
?
thread
.
threadId
:
this
.
debugService
.
getViewModel
().
getFocusedThreadId
();
if
(
!
thread
)
{
thread
=
this
.
debugService
.
getViewModel
().
getFocusedThread
();
}
return
this
.
debugService
.
stepOut
(
threadId
);
return
this
.
debugService
.
stepOut
(
thread
.
thread
Id
);
}
protected
isEnabled
(
state
:
debug
.
State
):
boolean
{
...
...
@@ -229,10 +232,11 @@ export class StepBackAction extends AbstractDebugAction {
}
public
run
(
thread
:
debug
.
IThread
):
TPromise
<
any
>
{
const
threadId
=
thread
&&
thread
instanceof
model
.
Thread
?
thread
.
threadId
:
this
.
debugService
.
getViewModel
().
getFocusedThreadId
();
if
(
!
thread
)
{
thread
=
this
.
debugService
.
getViewModel
().
getFocusedThread
();
}
return
this
.
debugService
.
stepBack
(
threadId
);
return
this
.
debugService
.
stepBack
(
thread
.
thread
Id
);
}
protected
isEnabled
(
state
:
debug
.
State
):
boolean
{
...
...
@@ -287,10 +291,11 @@ export class ContinueAction extends AbstractDebugAction {
}
public
run
(
thread
:
debug
.
IThread
):
TPromise
<
any
>
{
const
threadId
=
thread
&&
thread
instanceof
model
.
Thread
?
thread
.
threadId
:
this
.
debugService
.
getViewModel
().
getFocusedThreadId
();
if
(
!
thread
)
{
thread
=
this
.
debugService
.
getViewModel
().
getFocusedThread
();
}
return
this
.
debugService
.
continue
(
threadId
);
return
this
.
debugService
.
continue
(
thread
.
thread
Id
);
}
protected
isEnabled
(
state
:
debug
.
State
):
boolean
{
...
...
@@ -307,10 +312,11 @@ export class PauseAction extends AbstractDebugAction {
}
public
run
(
thread
:
debug
.
IThread
):
TPromise
<
any
>
{
const
threadId
=
thread
&&
thread
instanceof
model
.
Thread
?
thread
.
threadId
:
this
.
debugService
.
getViewModel
().
getFocusedThreadId
();
if
(
!
thread
)
{
thread
=
this
.
debugService
.
getViewModel
().
getFocusedThread
();
}
return
this
.
debugService
.
pause
(
threadId
);
return
this
.
debugService
.
pause
(
thread
.
thread
Id
);
}
protected
isEnabled
(
state
:
debug
.
State
):
boolean
{
...
...
@@ -645,7 +651,7 @@ class RunToCursorAction extends EditorAction {
const
bpExists
=
!!
(
debugService
.
getModel
().
getBreakpoints
().
filter
(
bp
=>
bp
.
lineNumber
===
lineNumber
&&
bp
.
source
.
uri
.
toString
()
===
uri
.
toString
()).
pop
());
return
(
bpExists
?
TPromise
.
as
(
null
)
:
debugService
.
addBreakpoints
([{
uri
,
lineNumber
}])).
then
(()
=>
{
debugService
.
continue
(
debugService
.
getViewModel
().
getFocusedThread
Id
()
);
debugService
.
continue
(
debugService
.
getViewModel
().
getFocusedThread
().
threadId
);
});
}
}
...
...
src/vs/workbench/parts/debug/browser/debugEditorModelManager.ts
浏览文件 @
33bed406
...
...
@@ -133,26 +133,24 @@ export class DebugEditorModelManager implements IWorkbenchContribution {
private
createCallStackDecorations
(
modelUrlStr
:
string
):
editorcommon
.
IModelDeltaDecoration
[]
{
const
result
:
editorcommon
.
IModelDeltaDecoration
[]
=
[];
const
focusedStackFrame
=
this
.
debugService
.
getViewModel
().
getFocusedStackFrame
();
const
focusedThreadId
=
this
.
debugService
.
getViewModel
().
getFocusedThreadId
();
const
allThreads
=
this
.
debugService
.
getModel
().
getThreads
();
if
(
!
focusedStackFrame
||
!
allThreads
[
focusedThreadId
]
||
!
allThreads
[
focusedThreadId
].
getCachedCallStack
())
{
const
focusedThread
=
this
.
debugService
.
getViewModel
().
getFocusedThread
();
if
(
!
focusedStackFrame
||
!
focusedThread
||
!
focusedThread
.
getCachedCallStack
())
{
return
result
;
}
// only show decorations for the currently focussed thread.
const
thread
=
allThreads
[
focusedThreadId
];
thread
.
getCachedCallStack
().
filter
(
sf
=>
sf
.
source
.
uri
.
toString
()
===
modelUrlStr
).
forEach
(
sf
=>
{
focusedThread
.
getCachedCallStack
().
filter
(
sf
=>
sf
.
source
.
uri
.
toString
()
===
modelUrlStr
).
forEach
(
sf
=>
{
const
wholeLineRange
=
createRange
(
sf
.
lineNumber
,
sf
.
column
,
sf
.
lineNumber
,
Number
.
MAX_VALUE
);
// compute how to decorate the editor. Different decorations are used if this is a top stack frame, focussed stack frame,
// an exception or a stack frame that did not change the line number (we only decorate the columns, not the whole line).
if
(
sf
===
t
hread
.
getCachedCallStack
()[
0
])
{
if
(
sf
===
focusedT
hread
.
getCachedCallStack
()[
0
])
{
result
.
push
({
options
:
DebugEditorModelManager
.
TOP_STACK_FRAME_MARGIN
,
range
:
createRange
(
sf
.
lineNumber
,
sf
.
column
,
sf
.
lineNumber
,
sf
.
column
+
1
)
});
if
(
t
hread
.
stoppedDetails
.
reason
===
'
exception
'
)
{
if
(
focusedT
hread
.
stoppedDetails
.
reason
===
'
exception
'
)
{
result
.
push
({
options
:
DebugEditorModelManager
.
TOP_STACK_FRAME_EXCEPTION_DECORATION
,
range
:
wholeLineRange
...
...
src/vs/workbench/parts/debug/common/debug.ts
浏览文件 @
33bed406
...
...
@@ -31,7 +31,7 @@ export const DEBUG_SCHEME = 'debug';
export
interface
IRawModelUpdate
{
threadId
:
number
;
sessionId
:
string
;
rawSession
:
IRawDebugSession
;
thread
?:
DebugProtocol
.
Thread
;
callStack
?:
DebugProtocol
.
StackFrame
[];
stoppedDetails
?:
IRawStoppedDetails
;
...
...
@@ -93,7 +93,7 @@ export interface IThread extends ITreeElement {
* Only gets the first 20 stack frames. Calling this method consecutive times
* with getAdditionalStackFrames = true gets the remainder of the call stack.
*/
getCallStack
(
debugService
:
IDebugService
,
getAdditionalStackFrames
?:
boolean
):
TPromise
<
IStackFrame
[]
>
;
getCallStack
(
getAdditionalStackFrames
?:
boolean
):
TPromise
<
IStackFrame
[]
>
;
/**
* Gets the callstack if it has already been received from the debug
...
...
@@ -120,6 +120,7 @@ export interface IScope extends IExpressionContainer {
export
interface
IStackFrame
extends
ITreeElement
{
threadId
:
number
;
sessionId
:
string
;
name
:
string
;
lineNumber
:
number
;
column
:
number
;
...
...
@@ -166,10 +167,13 @@ export interface IExceptionBreakpoint extends IEnablement {
// model interfaces
export
interface
IViewModel
extends
ITreeElement
{
/**
* Returns the active debug session or null if debug is inactive.
*/
activeSession
:
IRawDebugSession
;
getFocusedStackFrame
():
IStackFrame
;
getSelectedExpression
():
IExpression
;
getFocusedThread
Id
():
number
;
getFocusedThread
():
IThread
;
setSelectedExpression
(
expression
:
IExpression
);
getSelectedFunctionBreakpoint
():
IFunctionBreakpoint
;
setSelectedFunctionBreakpoint
(
functionBreakpoint
:
IFunctionBreakpoint
):
void
;
...
...
@@ -180,7 +184,8 @@ export interface IViewModel extends ITreeElement {
}
export
interface
IModel
extends
ITreeElement
{
getThreads
():
{
[
threadId
:
number
]:
IThread
;
};
getSessions
():
IRawDebugSession
[];
getThreads
(
sessionId
):
{
[
threadId
:
number
]:
IThread
;
};
getBreakpoints
():
IBreakpoint
[];
areBreakpointsActivated
():
boolean
;
getFunctionBreakpoints
():
IFunctionBreakpoint
[];
...
...
@@ -271,6 +276,7 @@ export interface IRawBreakpointContribution {
export
interface
IRawDebugSession
{
configuration
:
{
type
:
string
,
capabilities
:
DebugProtocol
.
Capabilities
};
getId
():
string
;
disconnect
(
restart
?:
boolean
,
force
?:
boolean
):
TPromise
<
DebugProtocol
.
DisconnectResponse
>
;
...
...
src/vs/workbench/parts/debug/common/debugModel.ts
浏览文件 @
33bed406
...
...
@@ -89,7 +89,7 @@ export class Thread implements debug.IThread {
public
stoppedDetails
:
debug
.
IRawStoppedDetails
;
public
stopped
:
boolean
;
constructor
(
p
ublic
sessionId
:
string
,
public
name
:
string
,
public
threadId
:
number
)
{
constructor
(
p
rivate
session
:
debug
.
IRawDebugSession
,
public
name
:
string
,
public
threadId
:
number
)
{
this
.
promisedCallStack
=
undefined
;
this
.
stoppedDetails
=
undefined
;
this
.
cachedCallStack
=
undefined
;
...
...
@@ -100,6 +100,10 @@ export class Thread implements debug.IThread {
return
`thread:
${
this
.
sessionId
}
:
${
this
.
name
}
:
${
this
.
threadId
}
`
;
}
public
get
sessionId
():
string
{
return
this
.
session
.
getId
();
}
public
clearCallStack
():
void
{
this
.
promisedCallStack
=
undefined
;
this
.
cachedCallStack
=
undefined
;
...
...
@@ -109,18 +113,18 @@ export class Thread implements debug.IThread {
return
this
.
cachedCallStack
;
}
public
getCallStack
(
debugService
:
debug
.
IDebugService
,
getAdditionalStackFrames
=
false
):
TPromise
<
debug
.
IStackFrame
[]
>
{
public
getCallStack
(
getAdditionalStackFrames
=
false
):
TPromise
<
debug
.
IStackFrame
[]
>
{
if
(
!
this
.
stopped
)
{
return
TPromise
.
as
([]);
}
if
(
!
this
.
promisedCallStack
)
{
this
.
promisedCallStack
=
this
.
getCallStackImpl
(
debugService
,
0
).
then
(
callStack
=>
{
this
.
promisedCallStack
=
this
.
getCallStackImpl
(
0
).
then
(
callStack
=>
{
this
.
cachedCallStack
=
callStack
;
return
callStack
;
});
}
else
if
(
getAdditionalStackFrames
)
{
this
.
promisedCallStack
=
this
.
promisedCallStack
.
then
(
callStackFirstPart
=>
this
.
getCallStackImpl
(
debugService
,
callStackFirstPart
.
length
).
then
(
callStackSecondPart
=>
{
this
.
promisedCallStack
=
this
.
promisedCallStack
.
then
(
callStackFirstPart
=>
this
.
getCallStackImpl
(
callStackFirstPart
.
length
).
then
(
callStackSecondPart
=>
{
this
.
cachedCallStack
=
callStackFirstPart
.
concat
(
callStackSecondPart
);
return
this
.
cachedCallStack
;
}));
...
...
@@ -129,9 +133,8 @@ export class Thread implements debug.IThread {
return
this
.
promisedCallStack
;
}
private
getCallStackImpl
(
debugService
:
debug
.
IDebugService
,
startFrame
:
number
):
TPromise
<
debug
.
IStackFrame
[]
>
{
let
session
=
debugService
.
activeSession
;
return
session
.
stackTrace
({
threadId
:
this
.
threadId
,
startFrame
,
levels
:
20
}).
then
(
response
=>
{
private
getCallStackImpl
(
startFrame
:
number
):
TPromise
<
debug
.
IStackFrame
[]
>
{
return
this
.
session
.
stackTrace
({
threadId
:
this
.
threadId
,
startFrame
,
levels
:
20
}).
then
(
response
=>
{
if
(
!
response
||
!
response
.
body
)
{
return
[];
}
...
...
@@ -139,10 +142,10 @@ export class Thread implements debug.IThread {
this
.
stoppedDetails
.
totalFrames
=
response
.
body
.
totalFrames
;
return
response
.
body
.
stackFrames
.
map
((
rsf
,
level
)
=>
{
if
(
!
rsf
)
{
return
new
StackFrame
(
this
.
threadId
,
0
,
new
Source
({
name
:
UNKNOWN_SOURCE_LABEL
},
false
),
nls
.
localize
(
'
unknownStack
'
,
"
Unknown stack location
"
),
undefined
,
undefined
);
return
new
StackFrame
(
this
.
sessionId
,
this
.
threadId
,
0
,
new
Source
({
name
:
UNKNOWN_SOURCE_LABEL
},
false
),
nls
.
localize
(
'
unknownStack
'
,
"
Unknown stack location
"
),
undefined
,
undefined
);
}
return
new
StackFrame
(
this
.
threadId
,
rsf
.
id
,
rsf
.
source
?
new
Source
(
rsf
.
source
)
:
new
Source
({
name
:
UNKNOWN_SOURCE_LABEL
},
false
),
rsf
.
name
,
rsf
.
line
,
rsf
.
column
);
return
new
StackFrame
(
this
.
sessionId
,
this
.
threadId
,
rsf
.
id
,
rsf
.
source
?
new
Source
(
rsf
.
source
)
:
new
Source
({
name
:
UNKNOWN_SOURCE_LABEL
},
false
),
rsf
.
name
,
rsf
.
line
,
rsf
.
column
);
});
},
(
err
:
Error
)
=>
{
this
.
stoppedDetails
.
framesErrorMessage
=
err
.
message
;
...
...
@@ -373,6 +376,7 @@ export class StackFrame implements debug.IStackFrame {
private
scopes
:
TPromise
<
Scope
[]
>
;
constructor
(
public
sessionId
:
string
,
public
threadId
:
number
,
public
frameId
:
number
,
public
source
:
Source
,
...
...
@@ -384,7 +388,7 @@ export class StackFrame implements debug.IStackFrame {
}
public
getId
():
string
{
return
`stackframe:
${
this
.
threadId
}
:
${
this
.
frameId
}
`
;
return
`stackframe:
${
this
.
sessionId
}
:
${
this
.
threadId
}
:
${
this
.
frameId
}
`
;
}
public
getScopes
(
debugService
:
debug
.
IDebugService
):
TPromise
<
debug
.
IScope
[]
>
{
...
...
@@ -457,13 +461,86 @@ export class ExceptionBreakpoint implements debug.IExceptionBreakpoint {
}
class
DebugSession
{
constructor
(
public
id
:
string
,
public
raw
:
debug
.
IRawDebugSession
,
public
threads
:
{
[
reference
:
number
]:
debug
.
IThread
;
})
{
}
public
threads
:
{
[
reference
:
number
]:
debug
.
IThread
;
};
constructor
(
public
raw
:
debug
.
IRawDebugSession
)
{
this
.
threads
=
{};
}
public
getId
():
string
{
return
this
.
raw
.
getId
();
}
public
rawUpdate
(
data
:
debug
.
IRawModelUpdate
):
void
{
if
(
data
.
thread
&&
!
this
.
threads
[
data
.
threadId
])
{
// A new thread came in, initialize it.
this
.
threads
[
data
.
threadId
]
=
new
Thread
(
this
.
raw
,
data
.
thread
.
name
,
data
.
thread
.
id
);
}
if
(
data
.
stoppedDetails
)
{
// Set the availability of the threads' callstacks depending on
// whether the thread is stopped or not
if
(
data
.
allThreadsStopped
)
{
Object
.
keys
(
this
.
threads
).
forEach
(
ref
=>
{
// Only update the details if all the threads are stopped
// because we don't want to overwrite the details of other
// threads that have stopped for a different reason
this
.
threads
[
ref
].
stoppedDetails
=
objects
.
clone
(
data
.
stoppedDetails
);
this
.
threads
[
ref
].
stopped
=
true
;
this
.
threads
[
ref
].
clearCallStack
();
});
}
else
{
// One thread is stopped, only update that thread.
this
.
threads
[
data
.
threadId
].
stoppedDetails
=
data
.
stoppedDetails
;
this
.
threads
[
data
.
threadId
].
clearCallStack
();
this
.
threads
[
data
.
threadId
].
stopped
=
true
;
}
}
}
public
clearThreads
(
removeThreads
:
boolean
,
reference
:
number
=
undefined
):
void
{
if
(
reference
)
{
if
(
this
.
threads
[
reference
])
{
this
.
threads
[
reference
].
clearCallStack
();
this
.
threads
[
reference
].
stoppedDetails
=
undefined
;
this
.
threads
[
reference
].
stopped
=
false
;
if
(
removeThreads
)
{
delete
this
.
threads
[
reference
];
}
}
}
else
{
Object
.
keys
(
this
.
threads
).
forEach
(
ref
=>
{
this
.
threads
[
ref
].
clearCallStack
();
this
.
threads
[
ref
].
stoppedDetails
=
undefined
;
this
.
threads
[
ref
].
stopped
=
false
;
});
if
(
removeThreads
)
{
this
.
threads
=
{};
ExpressionContainer
.
allValues
=
{};
}
}
}
public
sourceIsUnavailable
(
source
:
Source
):
void
{
Object
.
keys
(
this
.
threads
).
forEach
(
key
=>
{
if
(
this
.
threads
[
key
].
getCachedCallStack
())
{
this
.
threads
[
key
].
getCachedCallStack
().
forEach
(
stackFrame
=>
{
if
(
stackFrame
.
source
.
uri
.
toString
()
===
source
.
uri
.
toString
())
{
stackFrame
.
source
.
available
=
false
;
}
});
}
});
}
}
export
class
Model
implements
debug
.
IModel
{
private
sessions
:
DebugSession
[];
private
threads
:
{
[
reference
:
number
]:
debug
.
IThread
;
};
private
toDispose
:
lifecycle
.
IDisposable
[];
private
replElements
:
debug
.
ITreeElement
[];
private
_onDidChangeBreakpoints
:
Emitter
<
void
>
;
...
...
@@ -481,7 +558,6 @@ export class Model implements debug.IModel {
this
.
sessions
=
[];
this
.
replElements
=
[];
this
.
toDispose
=
[];
this
.
threads
=
{};
this
.
_onDidChangeBreakpoints
=
new
Emitter
<
void
>
();
this
.
_onDidChangeCallStack
=
new
Emitter
<
void
>
();
this
.
_onDidChangeWatchExpressions
=
new
Emitter
<
debug
.
IExpression
>
();
...
...
@@ -492,12 +568,12 @@ export class Model implements debug.IModel {
return
'
root
'
;
}
public
getSession
(
id
:
string
):
debug
.
IRawDebugSession
{
return
this
.
sessions
.
filter
(
s
=>
s
.
id
===
id
).
map
(
s
=>
s
.
raw
).
pop
(
);
public
getSession
s
():
debug
.
IRawDebugSession
[]
{
return
this
.
sessions
.
map
(
s
=>
s
.
raw
);
}
public
removeSession
(
id
:
string
):
void
{
this
.
sessions
=
this
.
sessions
.
filter
(
s
=>
s
.
id
!==
id
);
this
.
sessions
=
this
.
sessions
.
filter
(
s
=>
s
.
getId
()
!==
id
);
this
.
_onDidChangeCallStack
.
fire
();
}
...
...
@@ -517,37 +593,34 @@ export class Model implements debug.IModel {
return
this
.
_onDidChangeREPLElements
.
event
;
}
public
getThreads
():
{
[
reference
:
number
]:
debug
.
IThread
;
}
{
return
this
.
threads
;
}
public
clearThreads
(
removeThreads
:
boolean
,
reference
:
number
=
undefined
):
void
{
if
(
reference
)
{
if
(
this
.
threads
[
reference
])
{
this
.
threads
[
reference
].
clearCallStack
();
this
.
threads
[
reference
].
stoppedDetails
=
undefined
;
this
.
threads
[
reference
].
stopped
=
false
;
public
getThreads
(
sessionId
:
string
):
{
[
reference
:
number
]:
debug
.
IThread
;
}
{
const
session
=
this
.
sessions
.
filter
(
s
=>
s
.
getId
()
===
sessionId
).
pop
();
if
(
!
session
)
{
return
{};
}
if
(
removeThreads
)
{
delete
this
.
threads
[
reference
];
}
}
}
else
{
Object
.
keys
(
this
.
threads
).
forEach
(
ref
=>
{
this
.
threads
[
ref
].
clearCallStack
();
this
.
threads
[
ref
].
stoppedDetails
=
undefined
;
this
.
threads
[
ref
].
stopped
=
false
;
});
return
session
.
threads
;
}
if
(
removeThreads
)
{
this
.
threads
=
{};
ExpressionContainer
.
allValues
=
{};
}
public
rawUpdate
(
data
:
debug
.
IRawModelUpdate
):
void
{
let
session
=
this
.
sessions
.
filter
(
s
=>
s
.
getId
()
===
data
.
rawSession
.
getId
()).
pop
();
if
(
!
session
)
{
session
=
new
DebugSession
(
data
.
rawSession
);
this
.
sessions
.
push
(
session
);
}
session
.
rawUpdate
(
data
);
this
.
_onDidChangeCallStack
.
fire
();
}
public
clearThreads
(
sessionId
:
string
,
removeThreads
:
boolean
,
reference
:
number
=
undefined
):
void
{
const
session
=
this
.
sessions
.
filter
(
s
=>
s
.
getId
()
===
sessionId
).
pop
();
if
(
session
)
{
session
.
clearThreads
(
removeThreads
,
reference
);
this
.
_onDidChangeCallStack
.
fire
();
}
}
public
getBreakpoints
():
debug
.
IBreakpoint
[]
{
return
this
.
breakpoints
;
}
...
...
@@ -787,45 +860,7 @@ export class Model implements debug.IModel {
}
public
sourceIsUnavailable
(
source
:
Source
):
void
{
Object
.
keys
(
this
.
threads
).
forEach
(
key
=>
{
if
(
this
.
threads
[
key
].
getCachedCallStack
())
{
this
.
threads
[
key
].
getCachedCallStack
().
forEach
(
stackFrame
=>
{
if
(
stackFrame
.
source
.
uri
.
toString
()
===
source
.
uri
.
toString
())
{
stackFrame
.
source
.
available
=
false
;
}
});
}
});
this
.
_onDidChangeCallStack
.
fire
();
}
public
rawUpdate
(
data
:
debug
.
IRawModelUpdate
):
void
{
if
(
data
.
thread
&&
!
this
.
threads
[
data
.
threadId
])
{
// A new thread came in, initialize it.
this
.
threads
[
data
.
threadId
]
=
new
Thread
(
data
.
sessionId
,
data
.
thread
.
name
,
data
.
thread
.
id
);
}
if
(
data
.
stoppedDetails
)
{
// Set the availability of the threads' callstacks depending on
// whether the thread is stopped or not
if
(
data
.
allThreadsStopped
)
{
Object
.
keys
(
this
.
threads
).
forEach
(
ref
=>
{
// Only update the details if all the threads are stopped
// because we don't want to overwrite the details of other
// threads that have stopped for a different reason
this
.
threads
[
ref
].
stoppedDetails
=
objects
.
clone
(
data
.
stoppedDetails
);
this
.
threads
[
ref
].
stopped
=
true
;
this
.
threads
[
ref
].
clearCallStack
();
});
}
else
{
// One thread is stopped, only update that thread.
this
.
threads
[
data
.
threadId
].
stoppedDetails
=
data
.
stoppedDetails
;
this
.
threads
[
data
.
threadId
].
clearCallStack
();
this
.
threads
[
data
.
threadId
].
stopped
=
true
;
}
}
this
.
sessions
.
forEach
(
s
=>
s
.
sourceIsUnavailable
(
source
));
this
.
_onDidChangeCallStack
.
fire
();
}
...
...
src/vs/workbench/parts/debug/common/debugSource.ts
浏览文件 @
33bed406
...
...
@@ -38,12 +38,15 @@ export class Source {
public
static
toRawSource
(
uri
:
uri
,
model
:
IModel
):
DebugProtocol
.
Source
{
if
(
model
)
{
// first try to find the raw source amongst the stack frames - since that represenation has more data (source reference),
const
threads
=
model
.
getThreads
();
for
(
let
threadId
in
threads
)
{
if
(
threads
.
hasOwnProperty
(
threadId
)
&&
threads
[
threadId
].
getCachedCallStack
())
{
const
found
=
threads
[
threadId
].
getCachedCallStack
().
filter
(
sf
=>
sf
.
source
.
uri
.
toString
()
===
uri
.
toString
()).
pop
();
if
(
found
)
{
return
found
.
source
.
raw
;
const
sessions
=
model
.
getSessions
();
for
(
let
i
=
0
;
i
<
sessions
.
length
;
i
++
)
{
const
threads
=
model
.
getThreads
(
sessions
[
i
].
getId
());
for
(
let
threadId
in
threads
)
{
if
(
threads
.
hasOwnProperty
(
threadId
)
&&
threads
[
threadId
].
getCachedCallStack
())
{
const
found
=
threads
[
threadId
].
getCachedCallStack
().
filter
(
sf
=>
sf
.
source
.
uri
.
toString
()
===
uri
.
toString
()).
pop
();
if
(
found
)
{
return
found
.
source
.
raw
;
}
}
}
}
...
...
src/vs/workbench/parts/debug/common/debugViewModel.ts
浏览文件 @
33bed406
...
...
@@ -48,8 +48,8 @@ export class ViewModel implements debug.IViewModel {
return
this
.
_onDidFocusStackFrame
.
event
;
}
public
getFocusedThread
Id
():
number
{
return
this
.
focusedThread
?
this
.
focusedThread
.
threadId
:
0
;
public
getFocusedThread
():
debug
.
IThread
{
return
this
.
focusedThread
;
}
public
getSelectedExpression
():
debug
.
IExpression
{
...
...
src/vs/workbench/parts/debug/electron-browser/debugService.ts
浏览文件 @
33bed406
...
...
@@ -68,7 +68,6 @@ export class DebugService implements debug.IDebugService {
private
_state
:
debug
.
State
;
private
_onDidChangeState
:
Emitter
<
debug
.
State
>
;
private
session
:
RawDebugSession
;
private
model
:
model
.
Model
;
private
viewModel
:
viewmodel
.
ViewModel
;
private
configurationManager
:
ConfigurationManager
;
...
...
@@ -103,7 +102,6 @@ export class DebugService implements debug.IDebugService {
)
{
this
.
toDispose
=
[];
this
.
toDisposeOnSessionEnd
=
[];
this
.
session
=
null
;
this
.
breakpointsToSendOnResourceSaved
=
{};
this
.
_state
=
debug
.
State
.
Inactive
;
this
.
_onDidChangeState
=
new
Emitter
<
debug
.
State
>
();
...
...
@@ -145,6 +143,10 @@ export class DebugService implements debug.IDebugService {
this
.
toDispose
.
push
(
this
.
windowService
.
onBroadcast
(
this
.
onBroadcast
,
this
));
}
private
get
session
():
RawDebugSession
{
return
<
RawDebugSession
>
this
.
viewModel
.
activeSession
;
}
private
onBroadcast
(
broadcast
:
IBroadcast
):
void
{
// attach: PH is ready to be attached to
...
...
@@ -261,24 +263,24 @@ export class DebugService implements debug.IDebugService {
this
.
getThreadData
(
session
).
done
(()
=>
{
this
.
model
.
rawUpdate
({
sessionId
:
session
.
getId
()
,
rawSession
:
session
,
threadId
,
stoppedDetails
:
event
.
body
,
allThreadsStopped
:
event
.
body
.
allThreadsStopped
});
const
thread
=
this
.
model
.
getThreads
()[
threadId
];
thread
.
getCallStack
(
this
).
then
(
callStack
=>
{
const
thread
=
this
.
model
.
getThreads
(
session
.
getId
()
)[
threadId
];
thread
.
getCallStack
().
then
(
callStack
=>
{
if
(
callStack
.
length
>
0
)
{
// focus first stack frame from top that has source location
const
stackFrameToFocus
=
arrays
.
first
(
callStack
,
sf
=>
sf
.
source
&&
sf
.
source
.
available
,
callStack
[
0
]);
this
.
setFocusedStackFrameAndEvaluate
(
stackFrameToFocus
,
thread
).
done
(
null
,
errors
.
onUnexpectedError
);
this
.
setFocusedStackFrameAndEvaluate
(
stackFrameToFocus
).
done
(
null
,
errors
.
onUnexpectedError
);
this
.
windowService
.
getWindow
().
focus
();
aria
.
alert
(
nls
.
localize
(
'
debuggingPaused
'
,
"
Debugging paused, reason {0}, {1} {2}
"
,
event
.
body
.
reason
,
stackFrameToFocus
.
source
?
stackFrameToFocus
.
source
.
name
:
''
,
stackFrameToFocus
.
lineNumber
));
return
this
.
openOrRevealSource
(
stackFrameToFocus
.
source
,
stackFrameToFocus
.
lineNumber
,
false
,
false
);
}
else
{
this
.
setFocusedStackFrameAndEvaluate
(
null
,
thread
).
done
(
null
,
errors
.
onUnexpectedError
);
this
.
setFocusedStackFrameAndEvaluate
(
null
).
done
(
null
,
errors
.
onUnexpectedError
);
}
});
},
errors
.
onUnexpectedError
);
...
...
@@ -288,7 +290,7 @@ export class DebugService implements debug.IDebugService {
if
(
event
.
body
.
reason
===
'
started
'
)
{
this
.
getThreadData
(
session
).
done
(
null
,
errors
.
onUnexpectedError
);
}
else
if
(
event
.
body
.
reason
===
'
exited
'
)
{
this
.
model
.
clearThreads
(
true
,
event
.
body
.
threadId
);
this
.
model
.
clearThreads
(
session
.
getId
(),
true
,
event
.
body
.
threadId
);
}
}));
...
...
@@ -304,7 +306,7 @@ export class DebugService implements debug.IDebugService {
}));
this
.
toDisposeOnSessionEnd
.
push
(
session
.
onDidContinued
(
event
=>
{
this
.
lazyTransitionToRunningState
(
event
.
body
.
allThreadsContinued
?
undefined
:
event
.
body
.
threadId
);
this
.
lazyTransitionToRunningState
(
session
,
event
.
body
.
allThreadsContinued
?
undefined
:
event
.
body
.
threadId
);
}));
this
.
toDisposeOnSessionEnd
.
push
(
session
.
onDidOutput
(
event
=>
{
...
...
@@ -351,7 +353,7 @@ export class DebugService implements debug.IDebugService {
private
getThreadData
(
session
:
RawDebugSession
):
TPromise
<
void
>
{
return
session
.
threads
().
then
(
response
=>
{
if
(
response
&&
response
.
body
&&
response
.
body
.
threads
)
{
response
.
body
.
threads
.
forEach
(
thread
=>
this
.
model
.
rawUpdate
({
sessionId
:
session
.
getId
()
,
threadId
:
thread
.
id
,
thread
}));
response
.
body
.
threads
.
forEach
(
thread
=>
this
.
model
.
rawUpdate
({
rawSession
:
session
,
threadId
:
thread
.
id
,
thread
}));
}
});
}
...
...
@@ -418,11 +420,13 @@ export class DebugService implements debug.IDebugService {
return
!!
this
.
contextService
.
getWorkspace
();
}
public
setFocusedStackFrameAndEvaluate
(
focusedStackFrame
:
debug
.
IStackFrame
,
thread
?:
debug
.
IThread
):
TPromise
<
void
>
{
if
(
!
thread
&&
focusedStackFrame
)
{
thread
=
this
.
model
.
getThreads
()[
focusedStackFrame
.
threadId
];
public
setFocusedStackFrameAndEvaluate
(
focusedStackFrame
:
debug
.
IStackFrame
):
TPromise
<
void
>
{
let
thread
:
debug
.
IThread
=
null
;
let
session
:
debug
.
IRawDebugSession
=
null
;
if
(
focusedStackFrame
)
{
session
=
this
.
model
.
getSessions
().
filter
(
s
=>
s
.
getId
()
===
focusedStackFrame
.
sessionId
).
pop
();
thread
=
this
.
model
.
getThreads
(
focusedStackFrame
.
sessionId
)[
focusedStackFrame
.
threadId
];
}
const
session
=
this
.
model
.
getSession
(
thread
.
sessionId
);
this
.
viewModel
.
setFocusedStackFrame
(
focusedStackFrame
,
thread
,
session
);
if
(
focusedStackFrame
)
{
...
...
@@ -631,7 +635,6 @@ export class DebugService implements debug.IDebugService {
}
const
session
=
this
.
instantiationService
.
createInstance
(
RawDebugSession
,
configuration
.
debugServer
,
this
.
configurationManager
.
adapter
,
this
.
customTelemetryService
);
this
.
session
=
session
;
this
.
registerSessionListeners
(
session
);
return
session
.
initialize
({
...
...
@@ -643,14 +646,14 @@ export class DebugService implements debug.IDebugService {
supportsVariablePaging
:
true
,
// #9537
supportsRunInTerminalRequest
:
true
// #10574
}).
then
((
result
:
DebugProtocol
.
InitializeResponse
)
=>
{
if
(
!
this
.
session
)
{
if
(
session
.
disconnected
)
{
return
TPromise
.
wrapError
(
new
Error
(
nls
.
localize
(
'
debugAdapterCrash
'
,
"
Debug adapter process has terminated unexpectedly
"
)));
}
this
.
model
.
setExceptionBreakpoints
(
session
.
configuration
.
capabilities
.
exceptionBreakpointFilters
);
return
configuration
.
request
===
'
attach
'
?
session
.
attach
(
configuration
)
:
session
.
launch
(
configuration
);
}).
then
((
result
:
DebugProtocol
.
Response
)
=>
{
if
(
!
this
.
session
)
{
if
(
session
.
disconnected
)
{
return
TPromise
.
as
(
null
);
}
...
...
@@ -670,7 +673,7 @@ export class DebugService implements debug.IDebugService {
}
this
.
extensionService
.
activateByEvent
(
`onDebug:
${
configuration
.
type
}
`
).
done
(
null
,
errors
.
onUnexpectedError
);
this
.
inDebugMode
.
set
(
true
);
this
.
lazyTransitionToRunningState
();
this
.
lazyTransitionToRunningState
(
session
);
this
.
telemetryService
.
publicLog
(
'
debugSessionStart
'
,
{
type
:
configuration
.
type
,
...
...
@@ -688,8 +691,8 @@ export class DebugService implements debug.IDebugService {
this
.
telemetryService
.
publicLog
(
'
debugMisconfiguration
'
,
{
type
:
configuration
?
configuration
.
type
:
undefined
});
this
.
setStateAndEmit
(
debug
.
State
.
Inactive
);
if
(
this
.
session
)
{
this
.
session
.
disconnect
().
done
(
null
,
errors
.
onUnexpectedError
);
if
(
!
session
.
disconnected
)
{
session
.
disconnect
().
done
(
null
,
errors
.
onUnexpectedError
);
}
// Show the repl if some error got logged there #5870
if
(
this
.
model
.
getReplElements
().
length
>
0
)
{
...
...
@@ -790,7 +793,6 @@ export class DebugService implements debug.IDebugService {
});
}
this
.
session
=
null
;
try
{
this
.
toDisposeOnSessionEnd
=
lifecycle
.
dispose
(
this
.
toDisposeOnSessionEnd
);
}
catch
(
e
)
{
...
...
@@ -799,7 +801,7 @@ export class DebugService implements debug.IDebugService {
this
.
partService
.
removeClass
(
'
debugging
'
);
this
.
model
.
clearThreads
(
true
);
this
.
model
.
removeSession
(
session
.
getId
()
);
this
.
setFocusedStackFrameAndEvaluate
(
null
).
done
(
null
,
errors
.
onUnexpectedError
);
this
.
setStateAndEmit
(
debug
.
State
.
Inactive
);
...
...
@@ -899,7 +901,7 @@ export class DebugService implements debug.IDebugService {
}
return
this
.
session
.
next
({
threadId
}).
then
(()
=>
{
this
.
lazyTransitionToRunningState
(
threadId
);
this
.
lazyTransitionToRunningState
(
th
is
.
session
,
th
readId
);
});
}
...
...
@@ -909,7 +911,7 @@ export class DebugService implements debug.IDebugService {
}
return
this
.
session
.
stepIn
({
threadId
}).
then
(()
=>
{
this
.
lazyTransitionToRunningState
(
threadId
);
this
.
lazyTransitionToRunningState
(
th
is
.
session
,
th
readId
);
});
}
...
...
@@ -919,7 +921,7 @@ export class DebugService implements debug.IDebugService {
}
return
this
.
session
.
stepOut
({
threadId
}).
then
(()
=>
{
this
.
lazyTransitionToRunningState
(
threadId
);
this
.
lazyTransitionToRunningState
(
th
is
.
session
,
th
readId
);
});
}
...
...
@@ -929,7 +931,7 @@ export class DebugService implements debug.IDebugService {
}
return
this
.
session
.
stepBack
({
threadId
}).
then
(()
=>
{
this
.
lazyTransitionToRunningState
(
threadId
);
this
.
lazyTransitionToRunningState
(
th
is
.
session
,
th
readId
);
});
}
...
...
@@ -940,7 +942,7 @@ export class DebugService implements debug.IDebugService {
return
this
.
session
.
continue
({
threadId
}).
then
(
response
=>
{
const
allThreadsContinued
=
response
&&
response
.
body
?
response
.
body
.
allThreadsContinued
!==
false
:
true
;
this
.
lazyTransitionToRunningState
(
allThreadsContinued
?
undefined
:
threadId
);
this
.
lazyTransitionToRunningState
(
this
.
session
,
allThreadsContinued
?
undefined
:
threadId
);
});
}
...
...
@@ -980,19 +982,19 @@ export class DebugService implements debug.IDebugService {
},
err
=>
[]);
}
private
lazyTransitionToRunningState
(
threadId
?:
number
):
void
{
private
lazyTransitionToRunningState
(
session
:
RawDebugSession
,
threadId
?:
number
):
void
{
let
setNewFocusedStackFrameScheduler
:
RunOnceScheduler
;
const
toDispose
=
this
.
session
.
onDidStop
(
e
=>
{
const
toDispose
=
session
.
onDidStop
(
e
=>
{
if
(
e
.
body
.
threadId
===
threadId
||
e
.
body
.
allThreadsStopped
||
!
threadId
)
{
setNewFocusedStackFrameScheduler
.
cancel
();
}
});
this
.
model
.
clearThreads
(
false
,
threadId
);
this
.
model
.
clearThreads
(
session
.
getId
(),
false
,
threadId
);
// Get a top stack frame of a stopped thread if there is any.
const
threads
=
this
.
model
.
getThreads
();
const
threads
=
this
.
model
.
getThreads
(
session
.
getId
()
);
const
stoppedReference
=
Object
.
keys
(
threads
).
filter
(
ref
=>
threads
[
ref
].
stopped
).
pop
();
const
stoppedThread
=
stoppedReference
?
threads
[
parseInt
(
stoppedReference
)]
:
null
;
const
callStack
=
stoppedThread
?
stoppedThread
.
getCachedCallStack
()
:
null
;
...
...
src/vs/workbench/parts/debug/electron-browser/debugViewer.ts
浏览文件 @
33bed406
...
...
@@ -212,10 +212,14 @@ export class BaseDebugController extends treedefaults.DefaultController {
// call stack
class
ThreadAndSessionId
{
constructor
(
public
sessionId
:
string
,
public
threadId
:
number
)
{
}
}
export
class
CallStackController
extends
BaseDebugController
{
protected
onLeftClick
(
tree
:
tree
.
ITree
,
element
:
any
,
event
:
IMouseEvent
):
boolean
{
if
(
typeof
element
===
'
number
'
)
{
if
(
element
instanceof
ThreadAndSessionId
)
{
return
this
.
showMoreStackFrames
(
tree
,
element
);
}
if
(
element
instanceof
model
.
StackFrame
)
{
...
...
@@ -227,7 +231,7 @@ export class CallStackController extends BaseDebugController {
protected
onEnter
(
tree
:
tree
.
ITree
,
event
:
IKeyboardEvent
):
boolean
{
const
element
=
tree
.
getFocus
();
if
(
typeof
element
===
'
number
'
)
{
if
(
element
instanceof
ThreadAndSessionId
)
{
return
this
.
showMoreStackFrames
(
tree
,
element
);
}
if
(
element
instanceof
model
.
StackFrame
)
{
...
...
@@ -266,10 +270,10 @@ export class CallStackController extends BaseDebugController {
}
// user clicked / pressed on 'Load More Stack Frames', get those stack frames and refresh the tree.
private
showMoreStackFrames
(
tree
:
tree
.
ITree
,
thread
Id
:
number
):
boolean
{
const
thread
=
this
.
debugService
.
getModel
().
getThreads
(
)[
threadId
];
private
showMoreStackFrames
(
tree
:
tree
.
ITree
,
thread
AndSessionId
:
ThreadAndSessionId
):
boolean
{
const
thread
=
this
.
debugService
.
getModel
().
getThreads
(
threadAndSessionId
.
sessionId
)[
threadAndSessionId
.
threadId
];
if
(
thread
)
{
thread
.
getCallStack
(
t
his
.
debugService
,
t
rue
)
thread
.
getCallStack
(
true
)
.
done
(()
=>
tree
.
refresh
(),
errors
.
onUnexpectedError
);
}
...
...
@@ -358,17 +362,23 @@ export class CallStackDataSource implements tree.IDataSource {
return
this
.
getThreadChildren
(
element
);
}
const
threads
=
(
<
model
.
Model
>
element
).
getThreads
();
// TODO@Isidor FIX THIS
const
session
=
this
.
debugService
.
getViewModel
().
activeSession
;
if
(
!
session
)
{
return
TPromise
.
as
([]);
}
const
threads
=
(
<
model
.
Model
>
element
).
getThreads
(
session
.
getId
());
return
TPromise
.
as
(
Object
.
keys
(
threads
).
map
(
ref
=>
threads
[
ref
]));
}
private
getThreadChildren
(
thread
:
debug
.
IThread
):
TPromise
<
any
>
{
return
thread
.
getCallStack
(
this
.
debugService
).
then
((
callStack
:
any
[])
=>
{
return
thread
.
getCallStack
().
then
((
callStack
:
any
[])
=>
{
if
(
thread
.
stoppedDetails
&&
thread
.
stoppedDetails
.
framesErrorMessage
)
{
return
callStack
.
concat
([
thread
.
stoppedDetails
.
framesErrorMessage
]);
}
if
(
thread
.
stoppedDetails
&&
thread
.
stoppedDetails
.
totalFrames
>
callStack
.
length
)
{
return
callStack
.
concat
([
thread
.
threadId
]);
return
callStack
.
concat
([
new
ThreadAndSessionId
(
thread
.
sessionId
,
thread
.
threadId
)
]);
}
return
callStack
;
...
...
src/vs/workbench/parts/debug/electron-browser/debugViews.ts
浏览文件 @
33bed406
...
...
@@ -265,7 +265,7 @@ export class CallStackView extends viewlet.CollapsibleViewletView {
const
model
=
this
.
debugService
.
getModel
();
this
.
toDispose
.
push
(
this
.
debugService
.
getViewModel
().
onDidFocusStackFrame
(()
=>
{
const
focussedThread
=
model
.
getThreads
()[
this
.
debugService
.
getViewModel
().
getFocusedThreadId
()]
;
const
focussedThread
=
this
.
debugService
.
getViewModel
().
getFocusedThread
()
;
if
(
!
focussedThread
)
{
this
.
pauseMessage
.
hide
();
return
;
...
...
@@ -290,7 +290,8 @@ export class CallStackView extends viewlet.CollapsibleViewletView {
}));
this
.
toDispose
.
push
(
model
.
onDidChangeCallStack
(()
=>
{
const
threads
=
model
.
getThreads
();
const
session
=
this
.
debugService
.
getViewModel
().
activeSession
;
const
threads
=
session
?
model
.
getThreads
(
session
.
getId
())
:
Object
.
create
(
null
);
const
threadsArray
=
Object
.
keys
(
threads
).
map
(
ref
=>
threads
[
ref
]);
// Only show the threads in the call stack if there is more than 1 thread.
const
newTreeInput
=
threadsArray
.
length
===
1
?
threadsArray
[
0
]
:
model
;
...
...
src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts
浏览文件 @
33bed406
...
...
@@ -54,7 +54,7 @@ export class RawDebugSession extends v8.V8Protocol implements debug.IRawDebugSes
private
socket
:
net
.
Socket
=
null
;
private
cachedInitServer
:
TPromise
<
void
>
;
private
startTime
:
number
;
p
rivate
stopServerPending
:
boolean
;
p
ublic
disconnected
:
boolean
;
private
sentPromises
:
TPromise
<
DebugProtocol
.
Response
>
[];
private
capabilities
:
DebugProtocol
.
Capabilities
;
...
...
@@ -284,7 +284,7 @@ export class RawDebugSession extends v8.V8Protocol implements debug.IRawDebugSes
}
public
disconnect
(
restart
=
false
,
force
=
false
):
TPromise
<
DebugProtocol
.
DisconnectResponse
>
{
if
(
this
.
stopServerPending
&&
force
)
{
if
(
this
.
disconnected
&&
force
)
{
return
this
.
stopServer
();
}
...
...
@@ -295,9 +295,9 @@ export class RawDebugSession extends v8.V8Protocol implements debug.IRawDebugSes
this
.
sentPromises
=
[];
},
1000
);
if
((
this
.
serverProcess
||
this
.
socket
)
&&
!
this
.
stopServerPending
)
{
if
((
this
.
serverProcess
||
this
.
socket
)
&&
!
this
.
disconnected
)
{
// point of no return: from now on don't report any errors
this
.
stopServerPending
=
true
;
this
.
disconnected
=
true
;
this
.
restarted
=
restart
;
return
this
.
send
(
'
disconnect
'
,
{
restart
:
restart
},
false
).
then
(()
=>
this
.
stopServer
(),
()
=>
this
.
stopServer
());
}
...
...
@@ -436,7 +436,7 @@ export class RawDebugSession extends v8.V8Protocol implements debug.IRawDebugSes
return
TPromise
.
as
(
null
);
}
this
.
stopServerPending
=
true
;
this
.
disconnected
=
true
;
let
ret
:
TPromise
<
void
>
;
// when killing a process in windows its child
...
...
@@ -492,7 +492,7 @@ export class RawDebugSession extends v8.V8Protocol implements debug.IRawDebugSes
private
onServerExit
():
void
{
this
.
serverProcess
=
null
;
this
.
cachedInitServer
=
null
;
if
(
!
this
.
stopServerPending
)
{
if
(
!
this
.
disconnected
)
{
this
.
messageService
.
show
(
severity
.
Error
,
nls
.
localize
(
'
debugAdapterCrash
'
,
"
Debug adapter process has terminated unexpectedly
"
));
}
this
.
onEvent
({
event
:
'
exit
'
,
type
:
'
event
'
,
seq
:
0
});
...
...
src/vs/workbench/parts/debug/test/common/debugViewModel.test.ts
浏览文件 @
33bed406
...
...
@@ -6,6 +6,7 @@
import
assert
=
require
(
'
assert
'
);
import
{
ViewModel
}
from
'
vs/workbench/parts/debug/common/debugViewModel
'
;
import
{
StackFrame
,
Expression
,
Thread
}
from
'
vs/workbench/parts/debug/common/debugModel
'
;
import
{
MockRawSession
}
from
'
vs/workbench/parts/debug/test/common/mockDebugService
'
;
suite
(
'
Debug - View Model
'
,
()
=>
{
var
model
:
ViewModel
;
...
...
@@ -20,12 +21,12 @@ suite('Debug - View Model', () => {
test
(
'
focused stack frame
'
,
()
=>
{
assert
.
equal
(
model
.
getFocusedStackFrame
(),
null
);
assert
.
equal
(
model
.
getFocusedThread
Id
(),
0
);
const
frame
=
new
StackFrame
(
1
,
1
,
null
,
'
app.js
'
,
1
,
1
);
model
.
setFocusedStackFrame
(
frame
,
new
Thread
(
'
sessionid
'
,
'
myThread
'
,
1
),
null
);
assert
.
equal
(
model
.
getFocusedThread
(),
null
);
const
frame
=
new
StackFrame
(
'
mockrawsession
'
,
1
,
1
,
null
,
'
app.js
'
,
1
,
1
);
model
.
setFocusedStackFrame
(
frame
,
new
Thread
(
new
MockRawSession
()
,
'
myThread
'
,
1
),
null
);
assert
.
equal
(
model
.
getFocusedStackFrame
(),
frame
);
assert
.
equal
(
model
.
getFocusedThread
Id
()
,
1
);
assert
.
equal
(
model
.
getFocusedThread
().
threadId
,
1
);
});
test
(
'
selected expression
'
,
()
=>
{
...
...
src/vs/workbench/parts/debug/test/common/mockDebugService.ts
浏览文件 @
33bed406
...
...
@@ -143,7 +143,7 @@ export class MockDebugService implements debug.IDebugService {
}
class
MockRawSession
implements
debug
.
IRawDebugSession
{
export
class
MockRawSession
implements
debug
.
IRawDebugSession
{
public
get
configuration
():
{
type
:
string
,
capabilities
:
DebugProtocol
.
Capabilities
}
{
return
{
...
...
@@ -152,6 +152,10 @@ class MockRawSession implements debug.IRawDebugSession {
};
}
public
getId
()
{
return
'
mockrawsession
'
;
}
public
get
onDidEvent
():
Event
<
DebugProtocol
.
Event
>
{
return
null
;
}
...
...
src/vs/workbench/parts/debug/test/node/debugModel.test.ts
浏览文件 @
33bed406
...
...
@@ -8,13 +8,15 @@ import uri from 'vs/base/common/uri';
import
severity
from
'
vs/base/common/severity
'
;
import
debugmodel
=
require
(
'
vs/workbench/parts/debug/common/debugModel
'
);
import
*
as
sinon
from
'
sinon
'
;
import
{
Mock
DebugService
}
from
'
vs/workbench/parts/debug/test/common/mockDebugService
'
;
import
{
Mock
RawSession
}
from
'
vs/workbench/parts/debug/test/common/mockDebugService
'
;
suite
(
'
Debug - Model
'
,
()
=>
{
var
model
:
debugmodel
.
Model
;
let
model
:
debugmodel
.
Model
;
let
rawSession
:
MockRawSession
;
setup
(()
=>
{
model
=
new
debugmodel
.
Model
([],
true
,
[],
[],
[]);
rawSession
=
new
MockRawSession
();
});
teardown
(()
=>
{
...
...
@@ -78,8 +80,9 @@ suite('Debug - Model', () => {
test
(
'
threads simple
'
,
()
=>
{
var
threadId
=
1
;
var
threadName
=
'
firstThread
'
;
model
.
rawUpdate
({
sessionId
:
'
sessionid
'
,
rawSession
,
threadId
:
threadId
,
thread
:
{
id
:
threadId
,
...
...
@@ -87,16 +90,15 @@ suite('Debug - Model', () => {
}
});
var
threads
=
model
.
getThreads
();
var
threads
=
model
.
getThreads
(
rawSession
.
getId
()
);
assert
.
equal
(
threads
[
threadId
].
name
,
threadName
);
model
.
clearThreads
(
true
);
model
.
clearThreads
(
rawSession
.
getId
(),
true
);
assert
.
equal
(
model
.
getThreads
[
threadId
],
null
);
});
test
(
'
threads multiple wtih allThreadsStopped
'
,
()
=>
{
const
mockDebugService
=
new
MockDebugService
();
const
sessionStub
=
sinon
.
spy
(
mockDebugService
.
activeSession
,
'
stackTrace
'
);
const
sessionStub
=
sinon
.
spy
(
rawSession
,
'
stackTrace
'
);
const
threadId1
=
1
;
const
threadName1
=
'
firstThread
'
;
...
...
@@ -106,7 +108,7 @@ suite('Debug - Model', () => {
// Add the threads
model
.
rawUpdate
({
sessionId
:
'
sessionid
'
,
rawSession
,
threadId
:
threadId1
,
thread
:
{
id
:
threadId1
,
...
...
@@ -115,7 +117,7 @@ suite('Debug - Model', () => {
});
model
.
rawUpdate
({
sessionId
:
'
sessionid
'
,
rawSession
,
threadId
:
threadId2
,
thread
:
{
id
:
threadId2
,
...
...
@@ -125,7 +127,7 @@ suite('Debug - Model', () => {
// Stopped event with all threads stopped
model
.
rawUpdate
({
sessionId
:
'
sessionid
'
,
rawSession
,
threadId
:
threadId1
,
stoppedDetails
:
{
reason
:
stoppedReason
,
...
...
@@ -134,8 +136,8 @@ suite('Debug - Model', () => {
allThreadsStopped
:
true
});
const
thread1
=
model
.
getThreads
()[
threadId1
];
const
thread2
=
model
.
getThreads
()[
threadId2
];
const
thread1
=
model
.
getThreads
(
rawSession
.
getId
()
)[
threadId1
];
const
thread2
=
model
.
getThreads
(
rawSession
.
getId
()
)[
threadId2
];
// at the beginning, callstacks are obtainable but not available
assert
.
equal
(
thread1
.
name
,
threadName1
);
...
...
@@ -149,13 +151,13 @@ suite('Debug - Model', () => {
// after calling getCallStack, the callstack becomes available
// and results in a request for the callstack in the debug adapter
thread1
.
getCallStack
(
mockDebugService
).
then
(()
=>
{
thread1
.
getCallStack
().
then
(()
=>
{
assert
.
notEqual
(
thread1
.
getCachedCallStack
(),
undefined
);
assert
.
equal
(
thread2
.
getCachedCallStack
(),
undefined
);
assert
.
equal
(
sessionStub
.
callCount
,
1
);
});
thread2
.
getCallStack
(
mockDebugService
).
then
(()
=>
{
thread2
.
getCallStack
().
then
(()
=>
{
assert
.
notEqual
(
thread1
.
getCachedCallStack
(),
undefined
);
assert
.
notEqual
(
thread2
.
getCachedCallStack
(),
undefined
);
assert
.
equal
(
sessionStub
.
callCount
,
2
);
...
...
@@ -163,8 +165,8 @@ suite('Debug - Model', () => {
// calling multiple times getCallStack doesn't result in multiple calls
// to the debug adapter
thread1
.
getCallStack
(
mockDebugService
).
then
(()
=>
{
return
thread2
.
getCallStack
(
mockDebugService
);
thread1
.
getCallStack
().
then
(()
=>
{
return
thread2
.
getCallStack
();
}).
then
(()
=>
{
assert
.
equal
(
sessionStub
.
callCount
,
2
);
});
...
...
@@ -178,14 +180,13 @@ suite('Debug - Model', () => {
assert
.
equal
(
thread2
.
stopped
,
true
);
assert
.
equal
(
thread2
.
getCachedCallStack
(),
undefined
);
model
.
clearThreads
(
true
);
model
.
clearThreads
(
rawSession
.
getId
(),
true
);
assert
.
equal
(
model
.
getThreads
[
threadId1
],
null
);
assert
.
equal
(
model
.
getThreads
[
threadId2
],
null
);
});
test
(
'
threads mutltiple without allThreadsStopped
'
,
()
=>
{
const
mockDebugService
=
new
MockDebugService
();
const
sessionStub
=
sinon
.
spy
(
mockDebugService
.
activeSession
,
'
stackTrace
'
);
const
sessionStub
=
sinon
.
spy
(
rawSession
,
'
stackTrace
'
);
const
stoppedThreadId
=
1
;
const
stoppedThreadName
=
'
stoppedThread
'
;
...
...
@@ -195,7 +196,7 @@ suite('Debug - Model', () => {
// Add the threads
model
.
rawUpdate
({
sessionId
:
'
sessionid
'
,
rawSession
,
threadId
:
stoppedThreadId
,
thread
:
{
id
:
stoppedThreadId
,
...
...
@@ -204,7 +205,7 @@ suite('Debug - Model', () => {
});
model
.
rawUpdate
({
sessionId
:
'
sessionid
'
,
rawSession
,
threadId
:
runningThreadId
,
thread
:
{
id
:
runningThreadId
,
...
...
@@ -214,7 +215,7 @@ suite('Debug - Model', () => {
// Stopped event with only one thread stopped
model
.
rawUpdate
({
sessionId
:
'
sessionid
'
,
rawSession
,
threadId
:
stoppedThreadId
,
stoppedDetails
:
{
reason
:
stoppedReason
,
...
...
@@ -223,8 +224,8 @@ suite('Debug - Model', () => {
allThreadsStopped
:
false
});
const
stoppedThread
=
model
.
getThreads
()[
stoppedThreadId
];
const
runningThread
=
model
.
getThreads
()[
runningThreadId
];
const
stoppedThread
=
model
.
getThreads
(
rawSession
.
getId
()
)[
stoppedThreadId
];
const
runningThread
=
model
.
getThreads
(
rawSession
.
getId
()
)[
runningThreadId
];
// the callstack for the stopped thread is obtainable but not available
// the callstack for the running thread is not obtainable nor available
...
...
@@ -239,7 +240,7 @@ suite('Debug - Model', () => {
// after calling getCallStack, the callstack becomes available
// and results in a request for the callstack in the debug adapter
stoppedThread
.
getCallStack
(
mockDebugService
).
then
(()
=>
{
stoppedThread
.
getCallStack
().
then
(()
=>
{
assert
.
notEqual
(
stoppedThread
.
getCachedCallStack
(),
undefined
);
assert
.
equal
(
runningThread
.
getCachedCallStack
(),
undefined
);
assert
.
equal
(
sessionStub
.
callCount
,
1
);
...
...
@@ -248,14 +249,14 @@ suite('Debug - Model', () => {
// calling getCallStack on the running thread returns empty array
// and does not return in a request for the callstack in the debug
// adapter
runningThread
.
getCallStack
(
mockDebugService
).
then
(
callStack
=>
{
runningThread
.
getCallStack
().
then
(
callStack
=>
{
assert
.
deepEqual
(
callStack
,
[]);
assert
.
equal
(
sessionStub
.
callCount
,
1
);
});
// calling multiple times getCallStack doesn't result in multiple calls
// to the debug adapter
stoppedThread
.
getCallStack
(
mockDebugService
).
then
(()
=>
{
stoppedThread
.
getCallStack
().
then
(()
=>
{
assert
.
equal
(
sessionStub
.
callCount
,
1
);
});
...
...
@@ -264,7 +265,7 @@ suite('Debug - Model', () => {
assert
.
equal
(
stoppedThread
.
stopped
,
true
);
assert
.
equal
(
stoppedThread
.
getCachedCallStack
(),
undefined
);
model
.
clearThreads
(
true
);
model
.
clearThreads
(
rawSession
.
getId
(),
true
);
assert
.
equal
(
model
.
getThreads
[
stoppedThreadId
],
null
);
assert
.
equal
(
model
.
getThreads
[
runningThreadId
],
null
);
});
...
...
@@ -282,7 +283,7 @@ suite('Debug - Model', () => {
test
(
'
watch expressions
'
,
()
=>
{
assert
.
equal
(
model
.
getWatchExpressions
().
length
,
0
);
const
stackFrame
=
new
debugmodel
.
StackFrame
(
1
,
1
,
null
,
'
app.js
'
,
1
,
1
);
const
stackFrame
=
new
debugmodel
.
StackFrame
(
rawSession
.
getId
(),
1
,
1
,
null
,
'
app.js
'
,
1
,
1
);
model
.
addWatchExpression
(
null
,
stackFrame
,
'
console
'
).
done
();
model
.
addWatchExpression
(
null
,
stackFrame
,
'
console
'
).
done
();
const
watchExpressions
=
model
.
getWatchExpressions
();
...
...
@@ -301,7 +302,7 @@ suite('Debug - Model', () => {
test
(
'
repl expressions
'
,
()
=>
{
assert
.
equal
(
model
.
getReplElements
().
length
,
0
);
const
stackFrame
=
new
debugmodel
.
StackFrame
(
1
,
1
,
null
,
'
app.js
'
,
1
,
1
);
const
stackFrame
=
new
debugmodel
.
StackFrame
(
rawSession
.
getId
(),
1
,
1
,
null
,
'
app.js
'
,
1
,
1
);
model
.
addReplExpression
(
null
,
stackFrame
,
'
myVariable
'
).
done
();
model
.
addReplExpression
(
null
,
stackFrame
,
'
myVariable
'
).
done
();
model
.
addReplExpression
(
null
,
stackFrame
,
'
myVariable
'
).
done
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录