Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
09f672c9
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
09f672c9
编写于
3月 20, 2019
作者:
I
isidor
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
debug: Add support for sub-sessions
fixes #70695
上级
ae58c25e
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
80 addition
and
17 deletion
+80
-17
src/vs/workbench/contrib/debug/browser/callStackView.ts
src/vs/workbench/contrib/debug/browser/callStackView.ts
+9
-2
src/vs/workbench/contrib/debug/browser/debugActionItems.ts
src/vs/workbench/contrib/debug/browser/debugActionItems.ts
+9
-1
src/vs/workbench/contrib/debug/common/debug.ts
src/vs/workbench/contrib/debug/common/debug.ts
+1
-0
src/vs/workbench/contrib/debug/common/debugModel.ts
src/vs/workbench/contrib/debug/common/debugModel.ts
+12
-2
src/vs/workbench/contrib/debug/electron-browser/debugService.ts
.../workbench/contrib/debug/electron-browser/debugService.ts
+6
-6
src/vs/workbench/contrib/debug/electron-browser/debugSession.ts
.../workbench/contrib/debug/electron-browser/debugSession.ts
+5
-0
src/vs/workbench/contrib/debug/test/common/mockDebug.ts
src/vs/workbench/contrib/debug/test/common/mockDebug.ts
+5
-0
src/vs/workbench/contrib/debug/test/electron-browser/debugModel.test.ts
...ch/contrib/debug/test/electron-browser/debugModel.test.ts
+33
-6
未找到文件。
src/vs/workbench/contrib/debug/browser/callStackView.ts
浏览文件 @
09f672c9
...
...
@@ -97,7 +97,7 @@ export class CallStackView extends ViewletPanel {
dom
.
addClass
(
container
,
'
debug-call-stack
'
);
const
treeContainer
=
renderViewTree
(
container
);
this
.
dataSource
=
new
CallStackDataSource
();
this
.
dataSource
=
new
CallStackDataSource
(
this
.
debugService
);
this
.
tree
=
this
.
instantiationService
.
createInstance
(
WorkbenchAsyncDataTree
,
treeContainer
,
new
CallStackDelegate
(),
[
new
SessionsRenderer
(),
new
ThreadsRenderer
(),
...
...
@@ -562,6 +562,8 @@ function isDeemphasized(frame: IStackFrame): boolean {
class
CallStackDataSource
implements
IAsyncDataSource
<
IDebugModel
,
CallStackItem
>
{
deemphasizedStackFramesToShow
:
IStackFrame
[];
constructor
(
private
debugService
:
IDebugService
)
{
}
hasChildren
(
element
:
IDebugModel
|
CallStackItem
):
boolean
{
return
isDebugModel
(
element
)
||
isDebugSession
(
element
)
||
(
element
instanceof
Thread
&&
element
.
stopped
);
}
...
...
@@ -573,13 +575,18 @@ class CallStackDataSource implements IAsyncDataSource<IDebugModel, CallStackItem
return
Promise
.
resolve
([]);
}
if
(
sessions
.
length
>
1
)
{
return
Promise
.
resolve
(
sessions
);
return
Promise
.
resolve
(
sessions
.
filter
(
s
=>
!
s
.
parentSession
)
);
}
const
threads
=
sessions
[
0
].
getAllThreads
();
// Only show the threads in the call stack if there is more than 1 thread.
return
threads
.
length
===
1
?
this
.
getThreadChildren
(
<
Thread
>
threads
[
0
])
:
Promise
.
resolve
(
threads
);
}
else
if
(
isDebugSession
(
element
))
{
const
childSessions
=
this
.
debugService
.
getModel
().
getSessions
().
filter
(
s
=>
s
.
parentSession
===
element
);
if
(
childSessions
.
length
)
{
return
Promise
.
resolve
(
childSessions
);
}
return
Promise
.
resolve
(
element
.
getAllThreads
());
}
else
{
return
this
.
getThreadChildren
(
<
Thread
>
element
);
...
...
src/vs/workbench/contrib/debug/browser/debugActionItems.ts
浏览文件 @
09f672c9
...
...
@@ -217,7 +217,15 @@ export class FocusSessionActionItem extends SelectActionItem {
private
update
()
{
const
session
=
this
.
debugService
.
getViewModel
().
focusedSession
;
const
sessions
=
this
.
getSessions
();
const
names
=
sessions
.
map
(
s
=>
s
.
getLabel
());
const
names
=
sessions
.
map
(
s
=>
{
const
label
=
s
.
getLabel
();
if
(
s
.
parentSession
)
{
// Indent child sessions so they look like children
return
`\u00A0\u00A0
${
label
}
`
;
}
return
label
;
});
this
.
setOptions
(
names
.
map
(
data
=>
<
ISelectOptionItem
>
{
text
:
data
}),
session
?
sessions
.
indexOf
(
session
)
:
undefined
);
}
...
...
src/vs/workbench/contrib/debug/common/debug.ts
浏览文件 @
09f672c9
...
...
@@ -149,6 +149,7 @@ export interface IDebugSession extends ITreeElement {
readonly
unresolvedConfiguration
:
IConfig
|
undefined
;
readonly
state
:
State
;
readonly
root
:
IWorkspaceFolder
;
readonly
parentSession
:
IDebugSession
|
undefined
;
getLabel
():
string
;
...
...
src/vs/workbench/contrib/debug/common/debugModel.ts
浏览文件 @
09f672c9
...
...
@@ -12,7 +12,7 @@ import { generateUuid } from 'vs/base/common/uuid';
import
{
RunOnceScheduler
}
from
'
vs/base/common/async
'
;
import
severity
from
'
vs/base/common/severity
'
;
import
{
isObject
,
isString
,
isUndefinedOrNull
}
from
'
vs/base/common/types
'
;
import
{
distinct
}
from
'
vs/base/common/arrays
'
;
import
{
distinct
,
lastIndex
}
from
'
vs/base/common/arrays
'
;
import
{
Range
,
IRange
}
from
'
vs/editor/common/core/range
'
;
import
{
ITreeElement
,
IExpression
,
IExpressionContainer
,
IDebugSession
,
IStackFrame
,
IExceptionBreakpoint
,
IBreakpoint
,
IFunctionBreakpoint
,
IDebugModel
,
IReplElementSource
,
...
...
@@ -797,7 +797,17 @@ export class DebugModel implements IDebugModel {
return
true
;
});
this
.
sessions
.
push
(
session
);
let
index
=
-
1
;
if
(
session
.
parentSession
)
{
// Make sure that child sessions are placed after the parent session
index
=
lastIndex
(
this
.
sessions
,
s
=>
s
.
parentSession
===
session
.
parentSession
||
s
===
session
.
parentSession
);
}
if
(
index
>=
0
)
{
this
.
sessions
.
splice
(
index
+
1
,
0
,
session
);
}
else
{
this
.
sessions
.
push
(
session
);
}
this
.
_onDidChangeCallStack
.
fire
(
undefined
);
}
...
...
src/vs/workbench/contrib/debug/electron-browser/debugService.ts
浏览文件 @
09f672c9
...
...
@@ -315,7 +315,7 @@ export class DebugService implements IDebugService {
}
}
return
this
.
createSession
(
launchForName
,
launchForName
!
.
getConfiguration
(
name
),
noDebug
);
return
this
.
createSession
(
launchForName
,
launchForName
!
.
getConfiguration
(
name
),
noDebug
,
parentSession
);
})).
then
(
values
=>
values
.
every
(
success
=>
!!
success
));
// Compound launch is a success only if each configuration launched successfully
}
...
...
@@ -325,7 +325,7 @@ export class DebugService implements IDebugService {
return
Promise
.
reject
(
new
Error
(
message
));
}
return
this
.
createSession
(
launch
,
config
,
noDebug
);
return
this
.
createSession
(
launch
,
config
,
noDebug
,
parentSession
);
});
}));
}).
then
(
success
=>
{
...
...
@@ -341,7 +341,7 @@ export class DebugService implements IDebugService {
/**
* gets the debugger for the type, resolves configurations by providers, substitutes variables and runs prelaunch tasks
*/
private
createSession
(
launch
:
ILaunch
|
undefined
,
config
:
IConfig
|
undefined
,
noDebug
:
boolean
):
Promise
<
boolean
>
{
private
createSession
(
launch
:
ILaunch
|
undefined
,
config
:
IConfig
|
undefined
,
noDebug
:
boolean
,
parentSession
?:
IDebugSession
):
Promise
<
boolean
>
{
// We keep the debug type in a separate variable 'type' so that a no-folder config has no attributes.
// Storing the type in the config would break extensions that assume that the no-folder case is indicated by an empty config.
let
type
:
string
|
undefined
;
...
...
@@ -386,7 +386,7 @@ export class DebugService implements IDebugService {
const
workspace
=
launch
?
launch
.
workspace
:
undefined
;
return
this
.
runTaskAndCheckErrors
(
workspace
,
resolvedConfig
.
preLaunchTask
).
then
(
result
=>
{
if
(
result
===
TaskRunResult
.
Success
)
{
return
this
.
doCreateSession
(
workspace
,
{
resolved
:
resolvedConfig
,
unresolved
:
unresolvedConfig
});
return
this
.
doCreateSession
(
workspace
,
{
resolved
:
resolvedConfig
,
unresolved
:
unresolvedConfig
}
,
parentSession
);
}
return
false
;
});
...
...
@@ -415,9 +415,9 @@ export class DebugService implements IDebugService {
/**
* instantiates the new session, initializes the session, registers session listeners and reports telemetry
*/
private
doCreateSession
(
root
:
IWorkspaceFolder
|
undefined
,
configuration
:
{
resolved
:
IConfig
,
unresolved
:
IConfig
|
undefined
}):
Promise
<
boolean
>
{
private
doCreateSession
(
root
:
IWorkspaceFolder
|
undefined
,
configuration
:
{
resolved
:
IConfig
,
unresolved
:
IConfig
|
undefined
}
,
parentSession
?:
IDebugSession
):
Promise
<
boolean
>
{
const
session
=
this
.
instantiationService
.
createInstance
(
DebugSession
,
configuration
,
root
,
this
.
model
);
const
session
=
this
.
instantiationService
.
createInstance
(
DebugSession
,
configuration
,
root
,
this
.
model
,
parentSession
);
this
.
model
.
addSession
(
session
);
// register listeners as the very first thing!
this
.
registerSessionListeners
(
session
);
...
...
src/vs/workbench/contrib/debug/electron-browser/debugSession.ts
浏览文件 @
09f672c9
...
...
@@ -57,6 +57,7 @@ export class DebugSession implements IDebugSession {
private
_configuration
:
{
resolved
:
IConfig
,
unresolved
:
IConfig
|
undefined
},
public
root
:
IWorkspaceFolder
,
private
model
:
DebugModel
,
private
_parentSession
:
IDebugSession
|
undefined
,
@
IDebugService
private
readonly
debugService
:
IDebugService
,
@
ITelemetryService
private
readonly
telemetryService
:
ITelemetryService
,
@
IOutputService
private
readonly
outputService
:
IOutputService
,
...
...
@@ -83,6 +84,10 @@ export class DebugSession implements IDebugSession {
return
this
.
_configuration
.
unresolved
;
}
get
parentSession
():
IDebugSession
|
undefined
{
return
this
.
_parentSession
;
}
setConfiguration
(
configuration
:
{
resolved
:
IConfig
,
unresolved
:
IConfig
|
undefined
})
{
this
.
_configuration
=
configuration
;
}
...
...
src/vs/workbench/contrib/debug/test/common/mockDebug.ts
浏览文件 @
09f672c9
...
...
@@ -123,6 +123,11 @@ export class MockDebugService implements IDebugService {
}
export
class
MockSession
implements
IDebugSession
{
get
parentSession
():
IDebugSession
|
undefined
{
return
undefined
;
}
getReplElements
():
IReplElement
[]
{
return
[];
}
...
...
src/vs/workbench/contrib/debug/test/electron-browser/debugModel.test.ts
浏览文件 @
09f672c9
...
...
@@ -13,6 +13,10 @@ import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
import
{
DebugSession
}
from
'
vs/workbench/contrib/debug/electron-browser/debugSession
'
;
import
{
ReplModel
}
from
'
vs/workbench/contrib/debug/common/replModel
'
;
function
createMockSession
(
model
:
DebugModel
,
name
=
'
mockSession
'
,
parentSession
?:
DebugSession
|
undefined
):
DebugSession
{
return
new
DebugSession
({
resolved
:
{
name
,
type
:
'
node
'
,
request
:
'
launch
'
},
unresolved
:
undefined
},
undefined
!
,
model
,
parentSession
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
);
}
suite
(
'
Debug - Model
'
,
()
=>
{
let
model
:
DebugModel
;
let
rawSession
:
MockRawSession
;
...
...
@@ -109,7 +113,7 @@ suite('Debug - Model', () => {
test
(
'
threads simple
'
,
()
=>
{
const
threadId
=
1
;
const
threadName
=
'
firstThread
'
;
const
session
=
new
DebugSession
({
resolved
:
{
name
:
'
mockSession
'
,
type
:
'
node
'
,
request
:
'
launch
'
},
unresolved
:
undefined
},
undefined
!
,
model
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
);
const
session
=
createMockSession
(
model
);
model
.
addSession
(
session
);
assert
.
equal
(
model
.
getSessions
(
true
).
length
,
1
);
...
...
@@ -136,7 +140,7 @@ suite('Debug - Model', () => {
const
stoppedReason
=
'
breakpoint
'
;
// Add the threads
const
session
=
new
DebugSession
({
resolved
:
{
name
:
'
mockSession
'
,
type
:
'
node
'
,
request
:
'
launch
'
},
unresolved
:
undefined
},
undefined
!
,
model
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
);
const
session
=
createMockSession
(
model
);
model
.
addSession
(
session
);
session
[
'
raw
'
]
=
<
any
>
rawSession
;
...
...
@@ -224,7 +228,7 @@ suite('Debug - Model', () => {
const
runningThreadId
=
2
;
const
runningThreadName
=
'
runningThread
'
;
const
stoppedReason
=
'
breakpoint
'
;
const
session
=
new
DebugSession
({
resolved
:
{
name
:
'
mockSession
'
,
type
:
'
node
'
,
request
:
'
launch
'
},
unresolved
:
undefined
},
undefined
!
,
model
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
);
const
session
=
createMockSession
(
model
);
model
.
addSession
(
session
);
session
[
'
raw
'
]
=
<
any
>
rawSession
;
...
...
@@ -338,7 +342,7 @@ suite('Debug - Model', () => {
});
test
(
'
repl expressions
'
,
()
=>
{
const
session
=
new
DebugSession
({
resolved
:
{
name
:
'
mockSession
'
,
type
:
'
node
'
,
request
:
'
launch
'
},
unresolved
:
undefined
},
undefined
!
,
model
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
);
const
session
=
createMockSession
(
model
);
assert
.
equal
(
session
.
getReplElements
().
length
,
0
);
model
.
addSession
(
session
);
...
...
@@ -362,7 +366,7 @@ suite('Debug - Model', () => {
});
test
(
'
stack frame get specific source name
'
,
()
=>
{
const
session
=
new
DebugSession
({
resolved
:
{
name
:
'
mockSession
'
,
type
:
'
node
'
,
request
:
'
launch
'
},
unresolved
:
undefined
},
undefined
!
,
model
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
);
const
session
=
createMockSession
(
model
);
model
.
addSession
(
session
);
let
firstStackFrame
:
StackFrame
;
...
...
@@ -390,10 +394,33 @@ suite('Debug - Model', () => {
assert
.
equal
(
secondStackFrame
.
getSpecificSourceName
(),
'
.../x/c/d/internalModule.js
'
);
});
test
(
'
debug child sessions are added in correct order
'
,
()
=>
{
const
session
=
createMockSession
(
model
);
model
.
addSession
(
session
);
const
secondSession
=
createMockSession
(
model
,
'
mockSession2
'
);
model
.
addSession
(
secondSession
);
const
firstChild
=
createMockSession
(
model
,
'
firstChild
'
,
session
);
model
.
addSession
(
firstChild
);
const
secondChild
=
createMockSession
(
model
,
'
secondChild
'
,
session
);
model
.
addSession
(
secondChild
);
const
thirdSession
=
createMockSession
(
model
,
'
mockSession3
'
);
model
.
addSession
(
thirdSession
);
const
anotherChild
=
createMockSession
(
model
,
'
secondChild
'
,
secondSession
);
model
.
addSession
(
anotherChild
);
const
sessions
=
model
.
getSessions
();
assert
.
equal
(
sessions
[
0
].
getId
(),
session
.
getId
());
assert
.
equal
(
sessions
[
1
].
getId
(),
firstChild
.
getId
());
assert
.
equal
(
sessions
[
2
].
getId
(),
secondChild
.
getId
());
assert
.
equal
(
sessions
[
3
].
getId
(),
secondSession
.
getId
());
assert
.
equal
(
sessions
[
4
].
getId
(),
anotherChild
.
getId
());
assert
.
equal
(
sessions
[
5
].
getId
(),
thirdSession
.
getId
());
});
// Repl output
test
(
'
repl output
'
,
()
=>
{
const
session
=
new
DebugSession
({
resolved
:
{
name
:
'
mockSession
'
,
type
:
'
node
'
,
request
:
'
launch
'
},
unresolved
:
undefined
},
undefined
!
,
model
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
);
const
session
=
new
DebugSession
({
resolved
:
{
name
:
'
mockSession
'
,
type
:
'
node
'
,
request
:
'
launch
'
},
unresolved
:
undefined
},
undefined
!
,
model
,
undefined
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
,
undefined
!
);
const
repl
=
new
ReplModel
(
session
);
repl
.
appendToRepl
(
'
first line
\n
'
,
severity
.
Error
);
repl
.
appendToRepl
(
'
second line
'
,
severity
.
Error
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录