Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
cc126dfd
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,发现更多精彩内容 >>
提交
cc126dfd
编写于
5月 22, 2019
作者:
S
Sandeep Somavarapu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
reuse extension data for deps and pack tree.
上级
27819b39
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
65 addition
and
413 deletion
+65
-413
src/vs/workbench/contrib/extensions/browser/extensionsViewer.ts
.../workbench/contrib/extensions/browser/extensionsViewer.ts
+44
-0
src/vs/workbench/contrib/extensions/common/extensions.ts
src/vs/workbench/contrib/extensions/common/extensions.ts
+0
-9
src/vs/workbench/contrib/extensions/electron-browser/extensionEditor.ts
...ch/contrib/extensions/electron-browser/extensionEditor.ts
+20
-93
src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts
...nch/contrib/extensions/node/extensionsWorkbenchService.ts
+1
-69
src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts
.../test/electron-browser/extensionsWorkbenchService.test.ts
+0
-242
未找到文件。
src/vs/workbench/contrib/extensions/browser/extensionsViewer.ts
浏览文件 @
cc126dfd
...
...
@@ -19,6 +19,8 @@ import { IAccessibilityService } from 'vs/platform/accessibility/common/accessib
import
{
IAsyncDataSource
,
ITreeNode
}
from
'
vs/base/browser/ui/tree/tree
'
;
import
{
IListVirtualDelegate
,
IListRenderer
}
from
'
vs/base/browser/ui/list/list
'
;
import
{
IKeybindingService
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
CancellationToken
}
from
'
vs/base/common/cancellation
'
;
import
{
isNonEmptyArray
}
from
'
vs/base/common/arrays
'
;
export
interface
IExtensionTemplateData
{
icon
:
HTMLImageElement
;
...
...
@@ -217,4 +219,46 @@ export class ExtensionsTree extends WorkbenchAsyncDataTree<IExtensionData, IExte
}
}));
}
}
export
class
ExtensionData
implements
IExtensionData
{
readonly
extension
:
IExtension
;
readonly
parent
:
IExtensionData
|
null
;
private
readonly
getChildrenExtensionIds
:
(
extension
:
IExtension
)
=>
string
[];
private
readonly
childrenExtensionIds
:
string
[];
private
readonly
extensionsWorkbenchService
:
IExtensionsWorkbenchService
;
constructor
(
extension
:
IExtension
,
parent
:
IExtensionData
|
null
,
getChildrenExtensionIds
:
(
extension
:
IExtension
)
=>
string
[],
extensionsWorkbenchService
:
IExtensionsWorkbenchService
)
{
this
.
extension
=
extension
;
this
.
parent
=
parent
;
this
.
getChildrenExtensionIds
=
getChildrenExtensionIds
;
this
.
extensionsWorkbenchService
=
extensionsWorkbenchService
;
this
.
childrenExtensionIds
=
this
.
getChildrenExtensionIds
(
extension
);
}
get
hasChildren
():
boolean
{
return
isNonEmptyArray
(
this
.
childrenExtensionIds
);
}
async
getChildren
():
Promise
<
IExtensionData
[]
|
null
>
{
if
(
this
.
hasChildren
)
{
const
localById
=
this
.
extensionsWorkbenchService
.
local
.
reduce
((
result
,
e
)
=>
{
result
.
set
(
e
.
identifier
.
id
.
toLowerCase
(),
e
);
return
result
;
},
new
Map
<
string
,
IExtension
>
());
const
result
:
IExtension
[]
=
[];
const
toQuery
:
string
[]
=
[];
for
(
const
extensionId
of
this
.
childrenExtensionIds
)
{
const
id
=
extensionId
.
toLowerCase
();
const
local
=
localById
.
get
(
id
);
if
(
local
)
{
result
.
push
(
local
);
}
else
{
toQuery
.
push
(
id
);
}
}
const
galleryResult
=
await
this
.
extensionsWorkbenchService
.
queryGallery
({
names
:
this
.
childrenExtensionIds
,
pageSize
:
this
.
childrenExtensionIds
.
length
},
CancellationToken
.
None
);
result
.
push
(...
galleryResult
.
firstPage
);
return
result
.
map
(
extension
=>
new
ExtensionData
(
extension
,
this
,
this
.
getChildrenExtensionIds
,
this
.
extensionsWorkbenchService
));
}
return
null
;
}
}
\ No newline at end of file
src/vs/workbench/contrib/extensions/common/extensions.ts
浏览文件 @
cc126dfd
...
...
@@ -67,14 +67,6 @@ export interface IExtension {
readonly
isMalicious
:
boolean
;
}
export
interface
IExtensionDependencies
{
dependencies
:
IExtensionDependencies
[];
hasDependencies
:
boolean
;
identifier
:
string
;
extension
:
IExtension
;
dependent
:
IExtensionDependencies
|
null
;
}
export
const
SERVICE_ID
=
'
extensionsWorkbenchService
'
;
export
const
IExtensionsWorkbenchService
=
createDecorator
<
IExtensionsWorkbenchService
>
(
SERVICE_ID
);
...
...
@@ -95,7 +87,6 @@ export interface IExtensionsWorkbenchService {
installVersion
(
extension
:
IExtension
,
version
:
string
):
Promise
<
IExtension
>
;
reinstall
(
extension
:
IExtension
):
Promise
<
IExtension
>
;
setEnablement
(
extensions
:
IExtension
|
IExtension
[],
enablementState
:
EnablementState
):
Promise
<
void
>
;
loadDependencies
(
extension
:
IExtension
,
token
:
CancellationToken
):
Promise
<
IExtensionDependencies
|
null
>
;
open
(
extension
:
IExtension
,
sideByside
?:
boolean
):
Promise
<
any
>
;
checkForUpdates
():
Promise
<
void
>
;
allowedBadgeProviders
:
string
[];
...
...
src/vs/workbench/contrib/extensions/electron-browser/extensionEditor.ts
浏览文件 @
cc126dfd
...
...
@@ -24,7 +24,7 @@ import { IExtensionTipsService } from 'vs/platform/extensionManagement/common/ex
import
{
IExtensionManifest
,
IKeyBinding
,
IView
,
IViewContainer
,
ExtensionType
}
from
'
vs/platform/extensions/common/extensions
'
;
import
{
ResolvedKeybinding
,
KeyMod
,
KeyCode
}
from
'
vs/base/common/keyCodes
'
;
import
{
ExtensionsInput
}
from
'
vs/workbench/contrib/extensions/common/extensionsInput
'
;
import
{
IExtensionsWorkbenchService
,
IExtensionsViewlet
,
VIEWLET_ID
,
IExtension
,
IExtensionDependencies
,
ExtensionContainers
}
from
'
vs/workbench/contrib/extensions/common/extensions
'
;
import
{
IExtensionsWorkbenchService
,
IExtensionsViewlet
,
VIEWLET_ID
,
IExtension
,
ExtensionContainers
}
from
'
vs/workbench/contrib/extensions/common/extensions
'
;
import
{
RatingsWidget
,
InstallCountWidget
,
RemoteBadgeWidget
}
from
'
vs/workbench/contrib/extensions/electron-browser/extensionsWidgets
'
;
import
{
EditorOptions
}
from
'
vs/workbench/common/editor
'
;
import
{
ActionBar
}
from
'
vs/base/browser/ui/actionbar/actionbar
'
;
...
...
@@ -43,13 +43,13 @@ import { Color } from 'vs/base/common/color';
import
{
assign
}
from
'
vs/base/common/objects
'
;
import
{
INotificationService
}
from
'
vs/platform/notification/common/notification
'
;
import
{
CancellationToken
}
from
'
vs/base/common/cancellation
'
;
import
{
ExtensionsTree
,
I
ExtensionData
}
from
'
vs/workbench/contrib/extensions/browser/extensionsViewer
'
;
import
{
ExtensionsTree
,
ExtensionData
}
from
'
vs/workbench/contrib/extensions/browser/extensionsViewer
'
;
import
{
ShowCurrentReleaseNotesAction
}
from
'
vs/workbench/contrib/update/electron-browser/update
'
;
import
{
KeybindingParser
}
from
'
vs/base/common/keybindingParser
'
;
import
{
IStorageService
}
from
'
vs/platform/storage/common/storage
'
;
import
{
IExtensionService
}
from
'
vs/workbench/services/extensions/common/extensions
'
;
import
{
getDefaultValue
}
from
'
vs/platform/configuration/common/configurationRegistry
'
;
import
{
isUndefined
,
withUndefinedAsNull
}
from
'
vs/base/common/types
'
;
import
{
isUndefined
}
from
'
vs/base/common/types
'
;
import
{
IWorkbenchThemeService
}
from
'
vs/workbench/services/themes/common/workbenchThemeService
'
;
function
renderBody
(
body
:
string
):
string
{
...
...
@@ -177,7 +177,6 @@ export class ExtensionEditor extends BaseEditor {
private
extensionReadme
:
Cache
<
string
>
|
null
;
private
extensionChangelog
:
Cache
<
string
>
|
null
;
private
extensionManifest
:
Cache
<
IExtensionManifest
|
null
>
|
null
;
private
extensionDependencies
:
Cache
<
IExtensionDependencies
|
null
>
|
null
;
private
layoutParticipants
:
ILayoutParticipant
[]
=
[];
private
contentDisposables
:
IDisposable
[]
=
[];
...
...
@@ -206,7 +205,6 @@ export class ExtensionEditor extends BaseEditor {
this
.
extensionReadme
=
null
;
this
.
extensionChangelog
=
null
;
this
.
extensionManifest
=
null
;
this
.
extensionDependencies
=
null
;
}
createEditor
(
parent
:
HTMLElement
):
void
{
...
...
@@ -294,7 +292,6 @@ export class ExtensionEditor extends BaseEditor {
this
.
extensionReadme
=
new
Cache
(()
=>
createCancelablePromise
(
token
=>
extension
.
getReadme
(
token
)));
this
.
extensionChangelog
=
new
Cache
(()
=>
createCancelablePromise
(
token
=>
extension
.
getChangelog
(
token
)));
this
.
extensionManifest
=
new
Cache
(()
=>
createCancelablePromise
(
token
=>
extension
.
getManifest
(
token
)));
this
.
extensionDependencies
=
new
Cache
(()
=>
createCancelablePromise
(
token
=>
this
.
extensionsWorkbenchService
.
loadDependencies
(
extension
,
token
)));
const
remoteBadge
=
this
.
instantiationService
.
createInstance
(
RemoteBadgeWidget
,
this
.
iconContainer
,
true
);
const
onError
=
Event
.
once
(
domEvent
(
this
.
icon
,
'
error
'
));
...
...
@@ -626,69 +623,28 @@ export class ExtensionEditor extends BaseEditor {
}
private
openDependencies
(
extension
:
IExtension
):
Promise
<
IActiveElement
>
{
if
(
extension
.
dependencies
.
length
===
0
)
{
if
(
arrays
.
isFalsyOrEmpty
(
extension
.
dependencies
)
)
{
append
(
this
.
content
,
$
(
'
p.nocontent
'
)).
textContent
=
localize
(
'
noDependencies
'
,
"
No Dependencies
"
);
return
Promise
.
resolve
(
this
.
content
);
}
return
this
.
loadContents
(()
=>
this
.
extensionDependencies
!
.
get
())
.
then
<
IActiveElement
,
IActiveElement
>
(
extensionDependencies
=>
{
if
(
extensionDependencies
)
{
const
content
=
$
(
'
div
'
,
{
class
:
'
subcontent
'
});
const
scrollableContent
=
new
DomScrollableElement
(
content
,
{});
append
(
this
.
content
,
scrollableContent
.
getDomNode
());
this
.
contentDisposables
.
push
(
scrollableContent
);
const
dependenciesTree
=
this
.
renderDependencies
(
content
,
extensionDependencies
);
const
layout
=
()
=>
{
scrollableContent
.
scanDomNode
();
const
scrollDimensions
=
scrollableContent
.
getScrollDimensions
();
dependenciesTree
.
layout
(
scrollDimensions
.
height
);
};
const
removeLayoutParticipant
=
arrays
.
insert
(
this
.
layoutParticipants
,
{
layout
});
this
.
contentDisposables
.
push
(
toDisposable
(
removeLayoutParticipant
));
this
.
contentDisposables
.
push
(
dependenciesTree
);
scrollableContent
.
scanDomNode
();
return
{
focus
()
{
dependenciesTree
.
domFocus
();
}
};
}
else
{
append
(
this
.
content
,
$
(
'
p.nocontent
'
)).
textContent
=
localize
(
'
noDependencies
'
,
"
No Dependencies
"
);
return
Promise
.
resolve
(
this
.
content
);
}
},
error
=>
{
append
(
this
.
content
,
$
(
'
p.nocontent
'
)).
textContent
=
error
;
this
.
notificationService
.
error
(
error
);
return
this
.
content
;
});
}
private
renderDependencies
(
container
:
HTMLElement
,
extensionDependencies
:
IExtensionDependencies
):
ExtensionsTree
{
class
ExtensionData
implements
IExtensionData
{
private
readonly
extensionDependencies
:
IExtensionDependencies
;
constructor
(
extensionDependencies
:
IExtensionDependencies
)
{
this
.
extensionDependencies
=
extensionDependencies
;
}
get
extension
():
IExtension
{
return
this
.
extensionDependencies
.
extension
;
}
get
parent
():
IExtensionData
|
null
{
return
this
.
extensionDependencies
.
dependent
?
new
ExtensionData
(
this
.
extensionDependencies
.
dependent
)
:
null
;
}
get
hasChildren
():
boolean
{
return
this
.
extensionDependencies
.
hasDependencies
;
}
const
content
=
$
(
'
div
'
,
{
class
:
'
subcontent
'
});
const
scrollableContent
=
new
DomScrollableElement
(
content
,
{});
append
(
this
.
content
,
scrollableContent
.
getDomNode
());
this
.
contentDisposables
.
push
(
scrollableContent
);
getChildren
():
Promise
<
IExtensionData
[]
|
null
>
{
return
this
.
extensionDependencies
.
dependencies
?
Promise
.
resolve
(
this
.
extensionDependencies
.
dependencies
.
map
(
d
=>
new
ExtensionData
(
d
)))
:
Promise
.
resolve
(
null
);
}
}
const
dependenciesTree
=
this
.
instantiationService
.
createInstance
(
ExtensionsTree
,
new
ExtensionData
(
extension
,
null
,
extension
=>
extension
.
dependencies
||
[],
this
.
extensionsWorkbenchService
),
content
);
const
layout
=
()
=>
{
scrollableContent
.
scanDomNode
();
const
scrollDimensions
=
scrollableContent
.
getScrollDimensions
();
dependenciesTree
.
layout
(
scrollDimensions
.
height
);
};
const
removeLayoutParticipant
=
arrays
.
insert
(
this
.
layoutParticipants
,
{
layout
});
this
.
contentDisposables
.
push
(
toDisposable
(
removeLayoutParticipant
));
return
this
.
instantiationService
.
createInstance
(
ExtensionsTree
,
new
ExtensionData
(
extensionDependencies
),
container
);
this
.
contentDisposables
.
push
(
dependenciesTree
);
scrollableContent
.
scanDomNode
();
return
Promise
.
resolve
({
focus
()
{
dependenciesTree
.
domFocus
();
}
});
}
private
openExtensionPack
(
extension
:
IExtension
):
Promise
<
IActiveElement
>
{
...
...
@@ -697,7 +653,7 @@ export class ExtensionEditor extends BaseEditor {
append
(
this
.
content
,
scrollableContent
.
getDomNode
());
this
.
contentDisposables
.
push
(
scrollableContent
);
const
extensionsPackTree
=
this
.
renderExtensionPack
(
content
,
extension
);
const
extensionsPackTree
=
this
.
instantiationService
.
createInstance
(
ExtensionsTree
,
new
ExtensionData
(
extension
,
null
,
extension
=>
extension
.
extensionPack
||
[],
this
.
extensionsWorkbenchService
),
content
);
const
layout
=
()
=>
{
scrollableContent
.
scanDomNode
();
const
scrollDimensions
=
scrollableContent
.
getScrollDimensions
();
...
...
@@ -711,35 +667,6 @@ export class ExtensionEditor extends BaseEditor {
return
Promise
.
resolve
({
focus
()
{
extensionsPackTree
.
domFocus
();
}
});
}
private
renderExtensionPack
(
container
:
HTMLElement
,
extension
:
IExtension
):
ExtensionsTree
{
const
extensionsWorkbenchService
=
this
.
extensionsWorkbenchService
;
class
ExtensionData
implements
IExtensionData
{
readonly
extension
:
IExtension
;
readonly
parent
:
IExtensionData
|
null
;
constructor
(
extension
:
IExtension
,
parent
?:
IExtensionData
)
{
this
.
extension
=
extension
;
this
.
parent
=
withUndefinedAsNull
(
parent
);
}
get
hasChildren
():
boolean
{
return
this
.
extension
.
extensionPack
.
length
>
0
;
}
getChildren
():
Promise
<
IExtensionData
[]
|
null
>
{
if
(
this
.
hasChildren
)
{
const
names
=
arrays
.
distinct
(
this
.
extension
.
extensionPack
,
e
=>
e
.
toLowerCase
());
return
extensionsWorkbenchService
.
queryGallery
({
names
,
pageSize
:
names
.
length
},
CancellationToken
.
None
)
.
then
(
result
=>
result
.
firstPage
.
map
(
extension
=>
new
ExtensionData
(
extension
,
this
)));
}
return
Promise
.
resolve
(
null
);
}
}
return
this
.
instantiationService
.
createInstance
(
ExtensionsTree
,
new
ExtensionData
(
extension
),
container
);
}
private
renderSettings
(
container
:
HTMLElement
,
manifest
:
IExtensionManifest
,
onDetailsToggle
:
Function
):
boolean
{
const
contributes
=
manifest
.
contributes
;
const
configuration
=
contributes
&&
contributes
.
configuration
;
...
...
src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts
浏览文件 @
cc126dfd
...
...
@@ -22,7 +22,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import
{
IWindowService
}
from
'
vs/platform/windows/common/windows
'
;
import
Severity
from
'
vs/base/common/severity
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
IExtension
,
IExtensionDependencies
,
ExtensionState
,
IExtensionsWorkbenchService
,
AutoUpdateConfigurationKey
,
AutoCheckUpdatesConfigurationKey
}
from
'
vs/workbench/contrib/extensions/common/extensions
'
;
import
{
IExtension
,
ExtensionState
,
IExtensionsWorkbenchService
,
AutoUpdateConfigurationKey
,
AutoCheckUpdatesConfigurationKey
}
from
'
vs/workbench/contrib/extensions/common/extensions
'
;
import
{
IEditorService
,
SIDE_GROUP
,
ACTIVE_GROUP
}
from
'
vs/workbench/services/editor/common/editorService
'
;
import
{
IURLService
,
IURLHandler
}
from
'
vs/platform/url/common/url
'
;
import
{
ExtensionsInput
}
from
'
vs/workbench/contrib/extensions/common/extensionsInput
'
;
...
...
@@ -303,53 +303,6 @@ ${this.description}
}
}
class
ExtensionDependencies
implements
IExtensionDependencies
{
private
_hasDependencies
:
boolean
|
null
=
null
;
constructor
(
private
_extension
:
IExtension
,
private
_identifier
:
string
,
private
_map
:
Map
<
string
,
IExtension
>
,
private
_dependent
:
IExtensionDependencies
|
null
=
null
)
{
}
get
hasDependencies
():
boolean
{
if
(
this
.
_hasDependencies
===
null
)
{
this
.
_hasDependencies
=
this
.
computeHasDependencies
();
}
return
this
.
_hasDependencies
;
}
get
extension
():
IExtension
{
return
this
.
_extension
;
}
get
identifier
():
string
{
return
this
.
_identifier
;
}
get
dependent
():
IExtensionDependencies
|
null
{
return
this
.
_dependent
;
}
get
dependencies
():
IExtensionDependencies
[]
{
if
(
!
this
.
hasDependencies
)
{
return
[];
}
return
this
.
_extension
.
dependencies
.
map
(
id
=>
new
ExtensionDependencies
(
this
.
_map
.
get
(
id
)
!
,
id
,
this
.
_map
,
this
));
}
private
computeHasDependencies
():
boolean
{
if
(
this
.
_extension
&&
this
.
_extension
.
dependencies
.
length
>
0
)
{
let
dependent
=
this
.
_dependent
;
while
(
dependent
!==
null
)
{
if
(
dependent
.
identifier
===
this
.
identifier
)
{
return
false
;
}
dependent
=
dependent
.
dependent
;
}
return
true
;
}
return
false
;
}
}
class
Extensions
extends
Disposable
{
private
readonly
_onChange
:
Emitter
<
Extension
|
undefined
>
=
new
Emitter
<
Extension
|
undefined
>
();
...
...
@@ -645,27 +598,6 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
});
}
loadDependencies
(
extension
:
IExtension
,
token
:
CancellationToken
):
Promise
<
IExtensionDependencies
|
null
>
{
if
(
!
extension
.
dependencies
.
length
)
{
return
Promise
.
resolve
(
null
);
}
return
this
.
extensionService
.
getExtensionsReport
()
.
then
(
report
=>
{
const
maliciousSet
=
getMaliciousExtensionsSet
(
report
);
return
this
.
galleryService
.
loadAllDependencies
((
<
Extension
>
extension
).
dependencies
.
map
(
id
=>
({
id
})),
token
)
.
then
(
galleryExtensions
=>
{
const
extensions
:
IExtension
[]
=
[...
this
.
local
,
...
galleryExtensions
.
map
(
galleryExtension
=>
this
.
fromGallery
(
galleryExtension
,
maliciousSet
))];
const
map
=
new
Map
<
string
,
IExtension
>
();
for
(
const
extension
of
extensions
)
{
map
.
set
(
extension
.
identifier
.
id
,
extension
);
}
return
new
ExtensionDependencies
(
extension
,
extension
.
identifier
.
id
,
map
);
});
});
}
open
(
extension
:
IExtension
,
sideByside
:
boolean
=
false
):
Promise
<
any
>
{
return
Promise
.
resolve
(
this
.
editorService
.
openEditor
(
this
.
instantiationService
.
createInstance
(
ExtensionsInput
,
extension
),
undefined
,
sideByside
?
SIDE_GROUP
:
ACTIVE_GROUP
));
}
...
...
src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts
浏览文件 @
cc126dfd
...
...
@@ -480,248 +480,6 @@ suite('ExtensionsWorkbenchServiceTest', () => {
assert
.
ok
(
target
.
calledOnce
);
});
test
(
'
test extension dependencies when empty
'
,
async
()
=>
{
testObject
=
await
aWorkbenchService
();
instantiationService
.
stubPromise
(
IExtensionGalleryService
,
'
query
'
,
aPage
(
aGalleryExtension
(
'
a
'
)));
return
testObject
.
queryGallery
(
CancellationToken
.
None
).
then
(
page
=>
{
return
testObject
.
loadDependencies
(
page
.
firstPage
[
0
],
CancellationToken
.
None
).
then
(
dependencies
=>
{
assert
.
equal
(
null
,
dependencies
);
});
});
});
test
(
'
test one level extension dependencies without cycle
'
,
async
()
=>
{
testObject
=
await
aWorkbenchService
();
instantiationService
.
stubPromise
(
IExtensionGalleryService
,
'
query
'
,
aPage
(
aGalleryExtension
(
'
a
'
,
{},
{
dependencies
:
[
'
pub.b
'
,
'
pub.c
'
,
'
pub.d
'
]
})));
instantiationService
.
stubPromise
(
IExtensionGalleryService
,
'
loadAllDependencies
'
,
[
aGalleryExtension
(
'
b
'
),
aGalleryExtension
(
'
c
'
),
aGalleryExtension
(
'
d
'
)]);
return
testObject
.
queryGallery
(
CancellationToken
.
None
).
then
(
page
=>
{
const
extension
=
page
.
firstPage
[
0
];
return
testObject
.
loadDependencies
(
extension
,
CancellationToken
.
None
).
then
(
actual
=>
{
assert
.
ok
(
actual
!
.
hasDependencies
);
assert
.
equal
(
extension
,
actual
!
.
extension
);
assert
.
equal
(
null
,
actual
!
.
dependent
);
assert
.
equal
(
3
,
actual
!
.
dependencies
.
length
);
assert
.
equal
(
'
pub.a
'
,
actual
!
.
identifier
);
let
dependent
=
actual
;
actual
=
dependent
!
.
dependencies
[
0
];
assert
.
ok
(
!
actual
.
hasDependencies
);
assert
.
equal
(
'
pub.b
'
,
actual
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.b
'
,
actual
.
identifier
);
assert
.
equal
(
dependent
,
actual
.
dependent
);
assert
.
equal
(
0
,
actual
.
dependencies
.
length
);
actual
=
dependent
!
.
dependencies
[
1
];
assert
.
ok
(
!
actual
.
hasDependencies
);
assert
.
equal
(
'
pub.c
'
,
actual
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.c
'
,
actual
.
identifier
);
assert
.
equal
(
dependent
,
actual
.
dependent
);
assert
.
equal
(
0
,
actual
.
dependencies
.
length
);
actual
=
dependent
!
.
dependencies
[
2
];
assert
.
ok
(
!
actual
.
hasDependencies
);
assert
.
equal
(
'
pub.d
'
,
actual
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.d
'
,
actual
.
identifier
);
assert
.
equal
(
dependent
,
actual
.
dependent
);
assert
.
equal
(
0
,
actual
.
dependencies
.
length
);
});
});
});
test
(
'
test one level extension dependencies with cycle
'
,
async
()
=>
{
testObject
=
await
aWorkbenchService
();
instantiationService
.
stubPromise
(
IExtensionGalleryService
,
'
query
'
,
aPage
(
aGalleryExtension
(
'
a
'
,
{},
{
dependencies
:
[
'
pub.b
'
,
'
pub.a
'
]
})));
instantiationService
.
stubPromise
(
IExtensionGalleryService
,
'
loadAllDependencies
'
,
[
aGalleryExtension
(
'
b
'
),
aGalleryExtension
(
'
a
'
)]);
return
testObject
.
queryGallery
(
CancellationToken
.
None
).
then
(
page
=>
{
const
extension
=
page
.
firstPage
[
0
];
return
testObject
.
loadDependencies
(
extension
,
CancellationToken
.
None
).
then
(
actual
=>
{
assert
.
ok
(
actual
!
.
hasDependencies
);
assert
.
equal
(
extension
,
actual
!
.
extension
);
assert
.
equal
(
null
,
actual
!
.
dependent
);
assert
.
equal
(
2
,
actual
!
.
dependencies
.
length
);
assert
.
equal
(
'
pub.a
'
,
actual
!
.
identifier
);
let
dependent
=
actual
;
actual
=
dependent
!
.
dependencies
[
0
]
!
;
assert
.
ok
(
!
actual
.
hasDependencies
);
assert
.
equal
(
'
pub.b
'
,
actual
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.b
'
,
actual
.
identifier
);
assert
.
equal
(
dependent
,
actual
.
dependent
);
assert
.
equal
(
0
,
actual
.
dependencies
.
length
);
actual
=
dependent
!
.
dependencies
[
1
]
!
;
assert
.
ok
(
!
actual
.
hasDependencies
);
assert
.
equal
(
'
pub.a
'
,
actual
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.a
'
,
actual
.
identifier
);
assert
.
equal
(
dependent
,
actual
.
dependent
);
assert
.
equal
(
0
,
actual
.
dependencies
.
length
);
});
});
});
test
(
'
test one level extension dependencies with missing dependencies
'
,
async
()
=>
{
testObject
=
await
aWorkbenchService
();
instantiationService
.
stubPromise
(
IExtensionGalleryService
,
'
query
'
,
aPage
(
aGalleryExtension
(
'
a
'
,
{},
{
dependencies
:
[
'
pub.b
'
,
'
pub.a
'
]
})));
instantiationService
.
stubPromise
(
IExtensionGalleryService
,
'
loadAllDependencies
'
,
[
aGalleryExtension
(
'
a
'
)]);
return
testObject
.
queryGallery
(
CancellationToken
.
None
).
then
(
page
=>
{
const
extension
=
page
.
firstPage
[
0
];
return
testObject
.
loadDependencies
(
extension
,
CancellationToken
.
None
).
then
(
actual
=>
{
assert
.
ok
(
actual
!
.
hasDependencies
);
assert
.
equal
(
extension
,
actual
!
.
extension
);
assert
.
equal
(
null
,
actual
!
.
dependent
);
assert
.
equal
(
2
,
actual
!
.
dependencies
.
length
);
assert
.
equal
(
'
pub.a
'
,
actual
!
.
identifier
);
let
dependent
=
actual
;
actual
=
dependent
!
.
dependencies
[
0
]
!
;
assert
.
ok
(
!
actual
.
hasDependencies
);
assert
.
equal
(
null
,
actual
.
extension
);
assert
.
equal
(
'
pub.b
'
,
actual
.
identifier
);
assert
.
equal
(
dependent
,
actual
.
dependent
);
assert
.
equal
(
0
,
actual
.
dependencies
.
length
);
actual
=
dependent
!
.
dependencies
[
1
]
!
;
assert
.
ok
(
!
actual
.
hasDependencies
);
assert
.
equal
(
'
pub.a
'
,
actual
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.a
'
,
actual
.
identifier
);
assert
.
equal
(
dependent
,
actual
.
dependent
);
assert
.
equal
(
0
,
actual
.
dependencies
.
length
);
});
});
});
test
(
'
test one level extension dependencies with in built dependencies
'
,
async
()
=>
{
const
local
=
aLocalExtension
(
'
inbuilt
'
,
{},
{
type
:
ExtensionType
.
System
});
instantiationService
.
stubPromise
(
IExtensionManagementService
,
'
getInstalled
'
,
[
local
]);
testObject
=
await
aWorkbenchService
();
instantiationService
.
stubPromise
(
IExtensionGalleryService
,
'
query
'
,
aPage
(
aGalleryExtension
(
'
a
'
,
{},
{
dependencies
:
[
'
pub.inbuilt
'
,
'
pub.a
'
]
})));
instantiationService
.
stubPromise
(
IExtensionGalleryService
,
'
loadAllDependencies
'
,
[
aGalleryExtension
(
'
a
'
)]);
return
testObject
.
queryGallery
(
CancellationToken
.
None
).
then
(
page
=>
{
const
extension
=
page
.
firstPage
[
0
];
return
testObject
.
loadDependencies
(
extension
,
CancellationToken
.
None
).
then
(
actual
=>
{
assert
.
ok
(
actual
!
.
hasDependencies
);
assert
.
equal
(
extension
,
actual
!
.
extension
);
assert
.
equal
(
null
,
actual
!
.
dependent
);
assert
.
equal
(
2
,
actual
!
.
dependencies
.
length
);
assert
.
equal
(
'
pub.a
'
,
actual
!
.
identifier
);
let
dependent
=
actual
;
actual
=
dependent
!
.
dependencies
[
0
]
!
;
assert
.
ok
(
!
actual
.
hasDependencies
);
assert
.
equal
(
'
pub.inbuilt
'
,
actual
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.inbuilt
'
,
actual
.
identifier
);
assert
.
equal
(
dependent
,
actual
.
dependent
);
assert
.
equal
(
0
,
actual
.
dependencies
.
length
);
actual
=
dependent
!
.
dependencies
[
1
]
!
;
assert
.
ok
(
!
actual
.
hasDependencies
);
assert
.
equal
(
'
pub.a
'
,
actual
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.a
'
,
actual
.
identifier
);
assert
.
equal
(
dependent
,
actual
.
dependent
);
assert
.
equal
(
0
,
actual
.
dependencies
.
length
);
});
});
});
test
(
'
test more than one level of extension dependencies
'
,
async
()
=>
{
const
local
=
aLocalExtension
(
'
c
'
,
{
extensionDependencies
:
[
'
pub.d
'
]
},
{
type
:
ExtensionType
.
System
});
instantiationService
.
stubPromise
(
IExtensionManagementService
,
'
getInstalled
'
,
[
local
]);
testObject
=
await
aWorkbenchService
();
instantiationService
.
stubPromise
(
IExtensionGalleryService
,
'
query
'
,
aPage
(
aGalleryExtension
(
'
a
'
,
{},
{
dependencies
:
[
'
pub.b
'
,
'
pub.c
'
]
})));
instantiationService
.
stubPromise
(
IExtensionGalleryService
,
'
loadAllDependencies
'
,
[
aGalleryExtension
(
'
b
'
,
{},
{
dependencies
:
[
'
pub.d
'
,
'
pub.e
'
]
}),
aGalleryExtension
(
'
d
'
,
{},
{
dependencies
:
[
'
pub.f
'
,
'
pub.c
'
]
}),
aGalleryExtension
(
'
e
'
)]);
return
testObject
.
queryGallery
(
CancellationToken
.
None
).
then
(
page
=>
{
const
extension
=
page
.
firstPage
[
0
];
return
testObject
.
loadDependencies
(
extension
,
CancellationToken
.
None
).
then
(
a
=>
{
assert
.
ok
(
a
!
.
hasDependencies
);
assert
.
equal
(
extension
,
a
!
.
extension
);
assert
.
equal
(
null
,
a
!
.
dependent
);
assert
.
equal
(
2
,
a
!
.
dependencies
.
length
);
assert
.
equal
(
'
pub.a
'
,
a
!
.
identifier
);
let
b
=
a
!
.
dependencies
[
0
];
assert
.
ok
(
b
.
hasDependencies
);
assert
.
equal
(
'
pub.b
'
,
b
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.b
'
,
b
.
identifier
);
assert
.
equal
(
a
,
b
.
dependent
);
assert
.
equal
(
2
,
b
.
dependencies
.
length
);
let
c
=
a
!
.
dependencies
[
1
];
assert
.
ok
(
c
.
hasDependencies
);
assert
.
equal
(
'
pub.c
'
,
c
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.c
'
,
c
.
identifier
);
assert
.
equal
(
a
,
c
.
dependent
);
assert
.
equal
(
1
,
c
.
dependencies
.
length
);
let
d
=
b
.
dependencies
[
0
];
assert
.
ok
(
d
.
hasDependencies
);
assert
.
equal
(
'
pub.d
'
,
d
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.d
'
,
d
.
identifier
);
assert
.
equal
(
b
,
d
.
dependent
);
assert
.
equal
(
2
,
d
.
dependencies
.
length
);
let
e
=
b
.
dependencies
[
1
];
assert
.
ok
(
!
e
.
hasDependencies
);
assert
.
equal
(
'
pub.e
'
,
e
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.e
'
,
e
.
identifier
);
assert
.
equal
(
b
,
e
.
dependent
);
assert
.
equal
(
0
,
e
.
dependencies
.
length
);
let
f
=
d
.
dependencies
[
0
];
assert
.
ok
(
!
f
.
hasDependencies
);
assert
.
equal
(
null
,
f
.
extension
);
assert
.
equal
(
'
pub.f
'
,
f
.
identifier
);
assert
.
equal
(
d
,
f
.
dependent
);
assert
.
equal
(
0
,
f
.
dependencies
.
length
);
c
=
d
.
dependencies
[
1
];
assert
.
ok
(
c
.
hasDependencies
);
assert
.
equal
(
'
pub.c
'
,
c
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.c
'
,
c
.
identifier
);
assert
.
equal
(
d
,
c
.
dependent
);
assert
.
equal
(
1
,
c
.
dependencies
.
length
);
d
=
c
.
dependencies
[
0
];
assert
.
ok
(
!
d
.
hasDependencies
);
assert
.
equal
(
'
pub.d
'
,
d
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.d
'
,
d
.
identifier
);
assert
.
equal
(
c
,
d
.
dependent
);
assert
.
equal
(
0
,
d
.
dependencies
.
length
);
c
=
a
!
.
dependencies
[
1
];
d
=
c
.
dependencies
[
0
];
assert
.
ok
(
d
.
hasDependencies
);
assert
.
equal
(
'
pub.d
'
,
d
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.d
'
,
d
.
identifier
);
assert
.
equal
(
c
,
d
.
dependent
);
assert
.
equal
(
2
,
d
.
dependencies
.
length
);
f
=
d
.
dependencies
[
0
];
assert
.
ok
(
!
f
.
hasDependencies
);
assert
.
equal
(
null
,
f
.
extension
);
assert
.
equal
(
'
pub.f
'
,
f
.
identifier
);
assert
.
equal
(
d
,
f
.
dependent
);
assert
.
equal
(
0
,
f
.
dependencies
.
length
);
c
=
d
.
dependencies
[
1
];
assert
.
ok
(
!
c
.
hasDependencies
);
assert
.
equal
(
'
pub.c
'
,
c
.
extension
.
identifier
.
id
);
assert
.
equal
(
'
pub.c
'
,
c
.
identifier
);
assert
.
equal
(
d
,
c
.
dependent
);
assert
.
equal
(
0
,
c
.
dependencies
.
length
);
});
});
});
test
(
'
test uninstalled extensions are always enabled
'
,
async
()
=>
{
return
instantiationService
.
get
(
IExtensionEnablementService
).
setEnablement
([
aLocalExtension
(
'
b
'
)],
EnablementState
.
Disabled
)
.
then
(()
=>
instantiationService
.
get
(
IExtensionEnablementService
).
setEnablement
([
aLocalExtension
(
'
c
'
)],
EnablementState
.
WorkspaceDisabled
))
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录