Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
772bc18a
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,发现更多精彩内容 >>
提交
772bc18a
编写于
11月 21, 2019
作者:
I
isidor
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
debug config manager: more asyn await
fixes #83334
上级
15b09b95
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
103 addition
and
94 deletion
+103
-94
src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts
...kbench/contrib/debug/browser/debugConfigurationManager.ts
+103
-94
未找到文件。
src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts
浏览文件 @
772bc18a
...
...
@@ -13,7 +13,6 @@ import * as resources from 'vs/base/common/resources';
import
{
IJSONSchema
}
from
'
vs/base/common/jsonSchema
'
;
import
{
ITextModel
}
from
'
vs/editor/common/model
'
;
import
{
IEditor
}
from
'
vs/workbench/common/editor
'
;
import
{
ILifecycleService
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
import
{
IStorageService
,
StorageScope
}
from
'
vs/platform/storage/common/storage
'
;
import
{
IExtensionService
}
from
'
vs/workbench/services/extensions/common/extensions
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
...
...
@@ -35,6 +34,7 @@ import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/c
import
{
ITextFileService
}
from
'
vs/workbench/services/textfile/common/textfiles
'
;
import
{
CancellationToken
}
from
'
vs/base/common/cancellation
'
;
import
{
withUndefinedAsNull
}
from
'
vs/base/common/types
'
;
import
{
sequence
}
from
'
vs/base/common/async
'
;
import
{
IHistoryService
}
from
'
vs/workbench/services/history/common/history
'
;
import
{
first
}
from
'
vs/base/common/arrays
'
;
...
...
@@ -65,7 +65,6 @@ export class ConfigurationManager implements IConfigurationManager {
@
IInstantiationService
private
readonly
instantiationService
:
IInstantiationService
,
@
ICommandService
private
readonly
commandService
:
ICommandService
,
@
IStorageService
private
readonly
storageService
:
IStorageService
,
@
ILifecycleService
lifecycleService
:
ILifecycleService
,
@
IExtensionService
private
readonly
extensionService
:
IExtensionService
,
@
IContextKeyService
contextKeyService
:
IContextKeyService
,
@
IHistoryService
historyService
:
IHistoryService
...
...
@@ -75,7 +74,7 @@ export class ConfigurationManager implements IConfigurationManager {
this
.
debuggers
=
[];
this
.
toDispose
=
[];
this
.
initLaunches
();
this
.
registerListeners
(
lifecycleService
);
this
.
registerListeners
();
const
previousSelectedRoot
=
this
.
storageService
.
get
(
DEBUG_SELECTED_ROOT
,
StorageScope
.
WORKSPACE
);
const
previousSelectedLaunch
=
this
.
launches
.
filter
(
l
=>
l
.
uri
.
toString
()
===
previousSelectedRoot
).
pop
();
this
.
debugConfigurationTypeContext
=
CONTEXT_DEBUG_CONFIGURATION_TYPE
.
bindTo
(
contextKeyService
);
...
...
@@ -191,31 +190,31 @@ export class ConfigurationManager implements IConfigurationManager {
return
providers
.
length
>
0
;
}
resolveConfigurationByProviders
(
folderUri
:
uri
|
undefined
,
type
:
string
|
undefined
,
debugConfiguration
:
IConfig
,
token
:
CancellationToken
):
Promise
<
IConfig
|
null
|
undefined
>
{
return
this
.
activateDebuggers
(
'
onDebugResolve
'
,
type
).
then
(()
=>
{
// pipe the config through the promises sequentially. Append at the end the '*' types
const
providers
=
this
.
configProviders
.
filter
(
p
=>
p
.
type
===
type
&&
p
.
resolveDebugConfiguration
)
.
concat
(
this
.
configProviders
.
filter
(
p
=>
p
.
type
===
'
*
'
&&
p
.
resolveDebugConfiguration
));
async
resolveConfigurationByProviders
(
folderUri
:
uri
|
undefined
,
type
:
string
|
undefined
,
config
:
IConfig
,
token
:
CancellationToken
):
Promise
<
IConfig
|
null
|
undefined
>
{
await
this
.
activateDebuggers
(
'
onDebugResolve
'
,
type
);
// pipe the config through the promises sequentially. Append at the end the '*' types
const
providers
=
this
.
configProviders
.
filter
(
p
=>
p
.
type
===
type
&&
p
.
resolveDebugConfiguration
)
.
concat
(
this
.
configProviders
.
filter
(
p
=>
p
.
type
===
'
*
'
&&
p
.
resolveDebugConfiguration
));
return
providers
.
reduce
((
promise
,
provider
)
=>
{
return
promise
.
then
(
config
=>
{
if
(
config
)
{
return
provider
.
resolveDebugConfiguration
!
(
folderUri
,
config
,
token
);
}
else
{
return
Promise
.
resolve
(
config
);
}
});
},
Promise
.
resolve
(
debugConfiguration
));
});
let
result
:
IConfig
|
null
|
undefined
=
config
;
await
sequence
(
providers
.
map
(
provider
=>
async
()
=>
{
// If any provider returned undefined or null make sure to respect that and do not pass the result to more resolver
if
(
result
)
{
result
=
await
provider
.
resolveDebugConfiguration
!
(
folderUri
,
result
,
token
);
}
}));
return
result
;
}
provideDebugConfigurations
(
folderUri
:
uri
|
undefined
,
type
:
string
,
token
:
CancellationToken
):
Promise
<
any
[]
>
{
return
this
.
activateDebuggers
(
'
onDebugInitialConfigurations
'
)
.
then
(()
=>
Promise
.
all
(
this
.
configProviders
.
filter
(
p
=>
p
.
type
===
type
&&
p
.
provideDebugConfigurations
).
map
(
p
=>
p
.
provideDebugConfigurations
!
(
folderUri
,
token
)))
.
then
(
results
=>
results
.
reduce
((
first
,
second
)
=>
first
.
concat
(
second
),
[])));
async
provideDebugConfigurations
(
folderUri
:
uri
|
undefined
,
type
:
string
,
token
:
CancellationToken
):
Promise
<
any
[]
>
{
await
this
.
activateDebuggers
(
'
onDebugInitialConfigurations
'
);
const
results
=
await
Promise
.
all
(
this
.
configProviders
.
filter
(
p
=>
p
.
type
===
type
&&
p
.
provideDebugConfigurations
).
map
(
p
=>
p
.
provideDebugConfigurations
!
(
folderUri
,
token
)));
return
results
.
reduce
((
first
,
second
)
=>
first
.
concat
(
second
),
[]);
}
private
registerListeners
(
lifecycleService
:
ILifecycleService
):
void
{
private
registerListeners
():
void
{
debuggersExtPoint
.
setHandler
((
extensions
,
delta
)
=>
{
delta
.
added
.
forEach
(
added
=>
{
added
.
value
.
forEach
(
rawAdapter
=>
{
...
...
@@ -389,57 +388,54 @@ export class ConfigurationManager implements IConfigurationManager {
return
this
.
debuggers
.
filter
(
dbg
=>
strings
.
equalsIgnoreCase
(
dbg
.
type
,
type
)).
pop
();
}
guessDebugger
(
type
?:
string
):
Promise
<
Debugger
|
undefined
>
{
async
guessDebugger
(
type
?:
string
):
Promise
<
Debugger
|
undefined
>
{
if
(
type
)
{
const
adapter
=
this
.
getDebugger
(
type
);
return
Promise
.
resolve
(
adapter
);
}
const
activeTextEditorWidget
=
this
.
editorService
.
activeTextEditorWidget
;
let
candidates
:
Promise
<
Debugger
[]
>
|
undefined
;
let
candidates
:
Debugger
[]
|
undefined
;
if
(
isCodeEditor
(
activeTextEditorWidget
))
{
const
model
=
activeTextEditorWidget
.
getModel
();
const
language
=
model
?
model
.
getLanguageIdentifier
().
language
:
undefined
;
const
adapters
=
this
.
debuggers
.
filter
(
a
=>
language
&&
a
.
languages
&&
a
.
languages
.
indexOf
(
language
)
>=
0
);
if
(
adapters
.
length
===
1
)
{
return
Promise
.
resolve
(
adapters
[
0
])
;
return
adapters
[
0
]
;
}
if
(
adapters
.
length
>
1
)
{
candidates
=
Promise
.
resolve
(
adapters
)
;
candidates
=
adapters
;
}
}
if
(
!
candidates
)
{
candidates
=
this
.
activateDebuggers
(
'
onDebugInitialConfigurations
'
).
then
(()
=>
this
.
debuggers
.
filter
(
dbg
=>
dbg
.
hasInitialConfiguration
()
||
dbg
.
hasConfigurationProvider
()));
await
this
.
activateDebuggers
(
'
onDebugInitialConfigurations
'
);
candidates
=
this
.
debuggers
.
filter
(
dbg
=>
dbg
.
hasInitialConfiguration
()
||
dbg
.
hasConfigurationProvider
());
}
return
candidates
.
then
(
debuggers
=>
{
debuggers
.
sort
((
first
,
second
)
=>
first
.
label
.
localeCompare
(
second
.
label
));
const
picks
=
debuggers
.
map
(
c
=>
({
label
:
c
.
label
,
debugger
:
c
}));
return
this
.
quickInputService
.
pick
<
{
label
:
string
,
debugger
:
Debugger
|
undefined
}
>
([...
picks
,
{
type
:
'
separator
'
},
{
label
:
nls
.
localize
(
'
more
'
,
"
More...
"
),
debugger
:
undefined
}],
{
placeHolder
:
nls
.
localize
(
'
selectDebug
'
,
"
Select Environment
"
)
})
.
then
(
picked
=>
{
if
(
picked
&&
picked
.
debugger
)
{
return
picked
.
debugger
;
}
if
(
picked
)
{
this
.
commandService
.
executeCommand
(
'
debug.installAdditionalDebuggers
'
);
}
return
undefined
;
});
});
candidates
.
sort
((
first
,
second
)
=>
first
.
label
.
localeCompare
(
second
.
label
));
const
picks
=
candidates
.
map
(
c
=>
({
label
:
c
.
label
,
debugger
:
c
}));
return
this
.
quickInputService
.
pick
<
{
label
:
string
,
debugger
:
Debugger
|
undefined
}
>
([...
picks
,
{
type
:
'
separator
'
},
{
label
:
nls
.
localize
(
'
more
'
,
"
More...
"
),
debugger
:
undefined
}],
{
placeHolder
:
nls
.
localize
(
'
selectDebug
'
,
"
Select Environment
"
)
})
.
then
(
picked
=>
{
if
(
picked
&&
picked
.
debugger
)
{
return
picked
.
debugger
;
}
if
(
picked
)
{
this
.
commandService
.
executeCommand
(
'
debug.installAdditionalDebuggers
'
);
}
return
undefined
;
});
}
activateDebuggers
(
activationEvent
:
string
,
debugType
?:
string
):
Promise
<
void
>
{
const
thenabl
es
:
Promise
<
any
>
[]
=
[
a
sync
a
ctivateDebuggers
(
activationEvent
:
string
,
debugType
?:
string
):
Promise
<
void
>
{
const
promis
es
:
Promise
<
any
>
[]
=
[
this
.
extensionService
.
activateByEvent
(
activationEvent
),
this
.
extensionService
.
activateByEvent
(
'
onDebug
'
)
];
if
(
debugType
)
{
thenabl
es
.
push
(
this
.
extensionService
.
activateByEvent
(
`
${
activationEvent
}
:
${
debugType
}
`
));
promis
es
.
push
(
this
.
extensionService
.
activateByEvent
(
`
${
activationEvent
}
:
${
debugType
}
`
));
}
return
Promise
.
all
(
thenables
).
then
(
_
=>
{
return
undefined
;
});
await
Promise
.
all
(
promises
);
}
private
setSelectedLaunchName
(
selectedName
:
string
|
undefined
):
void
{
...
...
@@ -536,54 +532,57 @@ class Launch extends AbstractLaunch implements ILaunch {
return
this
.
configurationService
.
inspect
<
IGlobalConfig
>
(
'
launch
'
,
{
resource
:
this
.
workspace
.
uri
}).
workspaceFolder
;
}
openConfigFile
(
sideBySide
:
boolean
,
preserveFocus
:
boolean
,
type
?:
string
,
token
?:
CancellationToken
):
Promise
<
{
editor
:
IEditor
|
null
,
created
:
boolean
}
>
{
async
openConfigFile
(
sideBySide
:
boolean
,
preserveFocus
:
boolean
,
type
?:
string
,
token
?:
CancellationToken
):
Promise
<
{
editor
:
IEditor
|
null
,
created
:
boolean
}
>
{
const
resource
=
this
.
uri
;
let
created
=
false
;
return
this
.
fileService
.
readFile
(
resource
).
then
(
content
=>
content
.
value
,
err
=>
{
let
content
=
''
;
try
{
const
fileContent
=
await
this
.
fileService
.
readFile
(
resource
);
content
=
fileContent
.
value
.
toString
();
}
catch
{
// launch.json not found: create one by collecting launch configs from debugConfigProviders
return
this
.
configurationManager
.
guessDebugger
(
type
).
then
(
adapter
=>
{
if
(
adapter
)
{
return
this
.
configurationManager
.
provideDebugConfigurations
(
this
.
workspace
.
uri
,
adapter
.
type
,
token
||
CancellationToken
.
None
).
then
(
initialConfigs
=>
{
return
adapter
.
getInitialConfigurationContent
(
initialConfigs
);
});
}
else
{
return
''
;
}
}).
then
(
content
=>
{
if
(
!
content
)
{
return
''
;
}
const
adapter
=
await
this
.
configurationManager
.
guessDebugger
(
type
);
created
=
true
;
// pin only if config file is created #8727
return
this
.
textFileService
.
write
(
resource
,
content
).
then
(()
=>
content
);
});
}).
then
(
content
=>
{
if
(
!
content
)
{
return
{
editor
:
null
,
created
:
false
};
if
(
adapter
)
{
const
initialConfigs
=
await
this
.
configurationManager
.
provideDebugConfigurations
(
this
.
workspace
.
uri
,
adapter
.
type
,
token
||
CancellationToken
.
None
);
content
=
await
adapter
.
getInitialConfigurationContent
(
initialConfigs
);
}
const
contentValue
=
content
.
toString
();
const
index
=
contentValue
.
indexOf
(
`"
${
this
.
configurationManager
.
selectedConfiguration
.
name
}
"`
);
let
startLineNumber
=
1
;
for
(
let
i
=
0
;
i
<
index
;
i
++
)
{
if
(
contentValue
.
charAt
(
i
)
===
'
\n
'
)
{
startLineNumber
++
;
if
(
content
)
{
created
=
true
;
// pin only if config file is created #8727
try
{
await
this
.
textFileService
.
write
(
resource
,
content
);
}
catch
(
error
)
{
throw
new
Error
(
nls
.
localize
(
'
DebugConfig.failed
'
,
"
Unable to create 'launch.json' file inside the '.vscode' folder ({0}).
"
,
error
.
message
))
;
}
}
const
selection
=
startLineNumber
>
1
?
{
startLineNumber
,
startColumn
:
4
}
:
undefined
;
return
Promise
.
resolve
(
this
.
editorService
.
openEditor
({
resource
,
options
:
{
selection
,
preserveFocus
,
pinned
:
created
,
revealIfVisible
:
true
},
},
sideBySide
?
SIDE_GROUP
:
ACTIVE_GROUP
).
then
(
editor
=>
({
editor
:
withUndefinedAsNull
(
editor
),
created
})));
},
(
error
:
Error
)
=>
{
throw
new
Error
(
nls
.
localize
(
'
DebugConfig.failed
'
,
"
Unable to create 'launch.json' file inside the '.vscode' folder ({0}).
"
,
error
.
message
));
}
if
(
content
===
''
)
{
return
{
editor
:
null
,
created
:
false
};
}
const
index
=
content
.
indexOf
(
`"
${
this
.
configurationManager
.
selectedConfiguration
.
name
}
"`
);
let
startLineNumber
=
1
;
for
(
let
i
=
0
;
i
<
index
;
i
++
)
{
if
(
content
.
charAt
(
i
)
===
'
\n
'
)
{
startLineNumber
++
;
}
}
const
selection
=
startLineNumber
>
1
?
{
startLineNumber
,
startColumn
:
4
}
:
undefined
;
const
editor
=
await
this
.
editorService
.
openEditor
({
resource
,
options
:
{
selection
,
preserveFocus
,
pinned
:
created
,
revealIfVisible
:
true
},
},
sideBySide
?
SIDE_GROUP
:
ACTIVE_GROUP
);
return
({
editor
:
withUndefinedAsNull
(
editor
),
created
});
}
}
...
...
@@ -613,11 +612,17 @@ class WorkspaceLaunch extends AbstractLaunch implements ILaunch {
return
this
.
configurationService
.
inspect
<
IGlobalConfig
>
(
'
launch
'
).
workspace
;
}
openConfigFile
(
sideBySide
:
boolean
,
preserveFocus
:
boolean
,
type
?:
string
):
Promise
<
{
editor
:
IEditor
|
null
,
created
:
boolean
}
>
{
return
this
.
editorService
.
openEditor
({
async
openConfigFile
(
sideBySide
:
boolean
,
preserveFocus
:
boolean
):
Promise
<
{
editor
:
IEditor
|
null
,
created
:
boolean
}
>
{
const
editor
=
await
this
.
editorService
.
openEditor
({
resource
:
this
.
contextService
.
getWorkspace
().
configuration
!
,
options
:
{
preserveFocus
}
},
sideBySide
?
SIDE_GROUP
:
ACTIVE_GROUP
).
then
(
editor
=>
({
editor
:
withUndefinedAsNull
(
editor
),
created
:
false
}));
},
sideBySide
?
SIDE_GROUP
:
ACTIVE_GROUP
);
return
({
editor
:
withUndefinedAsNull
(
editor
),
created
:
false
});
}
}
...
...
@@ -650,7 +655,11 @@ class UserLaunch extends AbstractLaunch implements ILaunch {
return
this
.
configurationService
.
inspect
<
IGlobalConfig
>
(
'
launch
'
).
user
;
}
openConfigFile
(
sideBySide
:
boolean
,
preserveFocus
:
boolean
,
type
?:
string
):
Promise
<
{
editor
:
IEditor
|
null
,
created
:
boolean
}
>
{
return
this
.
preferencesService
.
openGlobalSettings
(
false
,
{
preserveFocus
}).
then
(
editor
=>
({
editor
:
withUndefinedAsNull
(
editor
),
created
:
false
}));
async
openConfigFile
(
_
:
boolean
,
preserveFocus
:
boolean
):
Promise
<
{
editor
:
IEditor
|
null
,
created
:
boolean
}
>
{
const
editor
=
await
this
.
preferencesService
.
openGlobalSettings
(
false
,
{
preserveFocus
});
return
({
editor
:
withUndefinedAsNull
(
editor
),
created
:
false
});
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录