Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
67e8f781
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,发现更多精彩内容 >>
提交
67e8f781
编写于
12月 11, 2017
作者:
S
Sandeep Somavarapu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix #37268
上级
f7765c1c
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
83 addition
and
93 deletion
+83
-93
src/vs/platform/extensionManagement/common/extensionManagementUtil.ts
...orm/extensionManagement/common/extensionManagementUtil.ts
+21
-0
src/vs/platform/extensionManagement/node/extensionManagementService.ts
...rm/extensionManagement/node/extensionManagementService.ts
+50
-83
src/vs/workbench/services/extensions/electron-browser/extensionPoints.ts
...h/services/extensions/electron-browser/extensionPoints.ts
+12
-10
未找到文件。
src/vs/platform/extensionManagement/common/extensionManagementUtil.ts
浏览文件 @
67e8f781
...
...
@@ -39,6 +39,27 @@ export function adoptToGalleryExtensionId(id: string): string {
return
id
.
replace
(
EXTENSION_IDENTIFIER_REGEX
,
(
match
,
publisher
:
string
,
name
:
string
)
=>
getGalleryExtensionId
(
publisher
,
name
));
}
export
function
groupByExtension
<
T
>
(
extensions
:
T
[],
getExtensionIdentifier
:
(
t
:
T
)
=>
IExtensionIdentifier
):
T
[][]
{
const
byExtension
:
T
[][]
=
[];
const
findGroup
=
extension
=>
{
for
(
const
group
of
byExtension
)
{
if
(
group
.
some
(
e
=>
areSameExtensions
(
getExtensionIdentifier
(
e
),
getExtensionIdentifier
(
extension
))))
{
return
group
;
}
}
return
null
;
};
for
(
const
extension
of
extensions
)
{
const
group
=
findGroup
(
extension
);
if
(
group
)
{
group
.
push
(
extension
);
}
else
{
byExtension
.
push
([
extension
]);
}
}
return
byExtension
;
}
export
function
getLocalExtensionTelemetryData
(
extension
:
ILocalExtension
):
any
{
return
{
id
:
getGalleryExtensionIdFromLocal
(
extension
),
...
...
src/vs/platform/extensionManagement/node/extensionManagementService.ts
浏览文件 @
67e8f781
...
...
@@ -21,14 +21,12 @@ import {
StatisticType
,
IExtensionIdentifier
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
import
{
getGalleryExtensionIdFromLocal
,
adoptToGalleryExtensionId
,
areSameExtensions
,
getGalleryExtensionId
}
from
'
vs/platform/extensionManagement/common/extensionManagementUtil
'
;
import
{
getIdAndVersionFromLocalExtensionId
}
from
'
vs/platform/extensionManagement/node/extensionManagementUtil
'
;
import
{
getGalleryExtensionIdFromLocal
,
adoptToGalleryExtensionId
,
areSameExtensions
,
getGalleryExtensionId
,
groupByExtension
}
from
'
vs/platform/extensionManagement/common/extensionManagementUtil
'
;
import
{
localizeManifest
}
from
'
../common/extensionNls
'
;
import
{
IEnvironmentService
}
from
'
vs/platform/environment/common/environment
'
;
import
{
Limiter
}
from
'
vs/base/common/async
'
;
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
import
*
as
semver
from
'
semver
'
;
import
{
groupBy
,
values
}
from
'
vs/base/common/collections
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
IChoiceService
,
Severity
}
from
'
vs/platform/message/common/message
'
;
import
pkg
from
'
vs/platform/node/package
'
;
...
...
@@ -92,7 +90,6 @@ interface InstallableExtension {
zipPath
:
string
;
id
:
string
;
metadata
?:
IGalleryMetadata
;
current
?:
ILocalExtension
;
}
export
class
ExtensionManagementService
implements
IExtensionManagementService
{
...
...
@@ -202,7 +199,7 @@ export class ExtensionManagementService implements IExtensionManagementService {
return
this
.
getDependenciesToInstall
(
local
.
manifest
.
extensionDependencies
)
.
then
(
dependenciesToInstall
=>
this
.
downloadAndInstallExtensions
(
metadata
?
dependenciesToInstall
.
filter
(
d
=>
d
.
identifier
.
uuid
!==
metadata
.
id
)
:
dependenciesToInstall
))
.
then
(()
=>
local
,
error
=>
{
this
.
uninstallExtension
(
local
.
identifier
);
this
.
uninstallExtension
(
local
);
return
TPromise
.
wrapError
(
error
);
});
}
...
...
@@ -247,17 +244,12 @@ export class ExtensionManagementService implements IExtensionManagementService {
}
private
downloadAndInstallExtensions
(
extensions
:
IGalleryExtension
[]):
TPromise
<
ILocalExtension
[]
>
{
return
this
.
getInstalled
(
LocalExtensionType
.
User
)
.
then
(
installed
=>
TPromise
.
join
(
extensions
.
map
(
extensionToInstall
=>
this
.
downloadInstallableExtension
(
extensionToInstall
,
installed
)
.
then
(
installableExtension
=>
this
.
installExtension
(
installableExtension
))
)).
then
(
null
,
errors
=>
this
.
rollback
(
extensions
).
then
(()
=>
TPromise
.
wrapError
(
errors
),
()
=>
TPromise
.
wrapError
(
errors
))),
error
=>
TPromise
.
wrapError
<
ILocalExtension
[]
>
(
new
ExtensionManagementError
(
this
.
joinErrors
(
error
).
message
,
INSTALL_ERROR_LOCAL
)));
return
TPromise
.
join
(
extensions
.
map
(
extensionToInstall
=>
this
.
downloadInstallableExtension
(
extensionToInstall
)
.
then
(
installableExtension
=>
this
.
installExtension
(
installableExtension
))
)).
then
(
null
,
errors
=>
this
.
rollback
(
extensions
).
then
(()
=>
TPromise
.
wrapError
(
errors
),
()
=>
TPromise
.
wrapError
(
errors
)));
}
private
downloadInstallableExtension
(
extension
:
IGalleryExtension
,
installed
:
ILocalExtension
[]):
TPromise
<
InstallableExtension
>
{
const
current
=
installed
.
filter
(
i
=>
i
.
identifier
.
uuid
===
extension
.
identifier
.
uuid
)[
0
];
private
downloadInstallableExtension
(
extension
:
IGalleryExtension
):
TPromise
<
InstallableExtension
>
{
const
id
=
getLocalExtensionIdFromGallery
(
extension
,
extension
.
version
);
const
metadata
=
<
IGalleryMetadata
>
{
id
:
extension
.
identifier
.
uuid
,
...
...
@@ -273,7 +265,7 @@ export class ExtensionManagementService implements IExtensionManagementService {
.
then
(
zipPath
=>
validateLocalExtension
(
zipPath
)
.
then
(
()
=>
(
<
InstallableExtension
>
{
zipPath
,
id
,
metadata
,
current
}),
()
=>
(
<
InstallableExtension
>
{
zipPath
,
id
,
metadata
}),
error
=>
TPromise
.
wrapError
(
new
ExtensionManagementError
(
this
.
joinErrors
(
error
).
message
,
INSTALL_ERROR_VALIDATING
))
),
error
=>
TPromise
.
wrapError
(
new
ExtensionManagementError
(
this
.
joinErrors
(
error
).
message
,
INSTALL_ERROR_DOWNLOADING
)));
...
...
@@ -286,7 +278,7 @@ export class ExtensionManagementService implements IExtensionManagementService {
private
rollback
(
extensions
:
IGalleryExtension
[]):
TPromise
<
void
>
{
return
this
.
filterOutUninstalled
(
extensions
)
.
then
(
installed
=>
TPromise
.
join
(
installed
.
map
(
local
=>
this
.
uninstallExtension
(
local
.
identifier
))))
.
then
(
installed
=>
TPromise
.
join
(
installed
.
map
(
local
=>
this
.
uninstallExtension
(
local
))))
.
then
(()
=>
null
,
()
=>
null
);
}
...
...
@@ -366,7 +358,7 @@ export class ExtensionManagementService implements IExtensionManagementService {
});
}
private
extractAndInstall
({
zipPath
,
id
,
metadata
,
current
}:
InstallableExtension
):
TPromise
<
ILocalExtension
>
{
private
extractAndInstall
({
zipPath
,
id
,
metadata
}:
InstallableExtension
):
TPromise
<
ILocalExtension
>
{
const
extensionPath
=
path
.
join
(
this
.
extensionsPath
,
id
);
return
pfs
.
rimraf
(
extensionPath
)
.
then
(()
=>
{
...
...
@@ -386,7 +378,6 @@ export class ExtensionManagementService implements IExtensionManagementService {
const
local
:
ILocalExtension
=
{
type
,
identifier
,
manifest
,
metadata
,
path
:
extensionPath
,
readmeUrl
,
changelogUrl
};
return
this
.
saveMetadataForLocalExtension
(
local
)
.
then
(()
=>
this
.
checkForRename
(
current
,
local
))
.
then
(()
=>
local
,
e
=>
TPromise
.
wrapError
(
new
ExtensionManagementError
(
this
.
joinErrors
(
e
).
message
,
INSTALL_ERROR_LOCAL
)));
});
},
e
=>
TPromise
.
wrapError
(
new
ExtensionManagementError
(
this
.
joinErrors
(
e
).
message
,
INSTALL_ERROR_DELETING
)));
...
...
@@ -395,16 +386,13 @@ export class ExtensionManagementService implements IExtensionManagementService {
uninstall
(
extension
:
ILocalExtension
,
force
=
false
):
TPromise
<
void
>
{
this
.
deleteExtensionsManifestCache
();
return
this
.
removeOutdatedExtensions
()
.
then
(()
=>
this
.
scanUserExtensions
()
.
then
(
installed
=>
{
const
promises
=
installed
.
filter
(
e
=>
e
.
manifest
.
publisher
===
extension
.
manifest
.
publisher
&&
e
.
manifest
.
name
===
extension
.
manifest
.
name
)
.
map
(
e
=>
this
.
checkForDependenciesAndUninstall
(
e
,
installed
,
force
));
return
TPromise
.
join
(
promises
).
then
(
null
,
error
=>
TPromise
.
wrapError
(
this
.
joinErrors
(
error
)));
}))
.
then
(()
=>
{
/* drop resolved value */
});
return
this
.
getInstalled
(
LocalExtensionType
.
User
)
.
then
(
installed
=>
{
const
promises
=
installed
.
filter
(
e
=>
e
.
manifest
.
publisher
===
extension
.
manifest
.
publisher
&&
e
.
manifest
.
name
===
extension
.
manifest
.
name
)
.
map
(
e
=>
this
.
checkForDependenciesAndUninstall
(
e
,
installed
,
force
));
return
TPromise
.
join
(
promises
).
then
(()
=>
null
,
error
=>
TPromise
.
wrapError
(
this
.
joinErrors
(
error
)));
});
}
updateMetadata
(
local
:
ILocalExtension
,
metadata
:
IGalleryMetadata
):
TPromise
<
ILocalExtension
>
{
...
...
@@ -434,14 +422,6 @@ export class ExtensionManagementService implements IExtensionManagementService {
});
}
private
checkForRename
(
currentExtension
:
ILocalExtension
,
newExtension
:
ILocalExtension
):
TPromise
<
void
>
{
// Check if the gallery id for current and new exensions are same, if not, remove the current one.
if
(
currentExtension
&&
getGalleryExtensionIdFromLocal
(
currentExtension
)
!==
getGalleryExtensionIdFromLocal
(
newExtension
))
{
return
this
.
markUninstalled
(
currentExtension
.
identifier
.
id
);
}
return
TPromise
.
as
(
null
);
}
private
joinErrors
(
errorOrErrors
:
(
Error
|
string
)
|
((
Error
|
string
)[])):
Error
{
const
errors
=
Array
.
isArray
(
errorOrErrors
)
?
errorOrErrors
:
[
errorOrErrors
];
if
(
errors
.
length
===
1
)
{
...
...
@@ -519,7 +499,7 @@ export class ExtensionManagementService implements IExtensionManagementService {
if
(
dependents
.
length
)
{
return
TPromise
.
wrapError
<
void
>
(
new
Error
(
this
.
getDependentsErrorMessage
(
extension
,
dependents
)));
}
return
TPromise
.
join
([
this
.
uninstallExtension
(
extension
.
identifier
),
...
dependenciesToUninstall
.
map
(
d
=>
this
.
doUninstall
(
d
))]).
then
(()
=>
null
);
return
TPromise
.
join
([
this
.
uninstallExtension
(
extension
),
...
dependenciesToUninstall
.
map
(
d
=>
this
.
doUninstall
(
d
))]).
then
(()
=>
null
);
}
private
getDependentsErrorMessage
(
extension
:
ILocalExtension
,
dependents
:
ILocalExtension
[]):
string
{
...
...
@@ -570,7 +550,7 @@ export class ExtensionManagementService implements IExtensionManagementService {
private
doUninstall
(
extension
:
ILocalExtension
):
TPromise
<
void
>
{
return
this
.
preUninstallExtension
(
extension
)
.
then
(()
=>
this
.
uninstallExtension
(
extension
.
identifier
))
.
then
(()
=>
this
.
uninstallExtension
(
extension
))
.
then
(()
=>
this
.
postUninstallExtension
(
extension
),
error
=>
{
this
.
postUninstallExtension
(
extension
,
INSTALL_ERROR_LOCAL
);
...
...
@@ -585,8 +565,11 @@ export class ExtensionManagementService implements IExtensionManagementService {
.
then
(()
=>
this
.
_onUninstallExtension
.
fire
(
extension
.
identifier
));
}
private
uninstallExtension
({
id
}:
IExtensionIdentifier
):
TPromise
<
void
>
{
return
this
.
markUninstalled
(
id
);
private
uninstallExtension
(
local
:
ILocalExtension
):
TPromise
<
void
>
{
const
identifier
=
{
id
:
getGalleryExtensionIdFromLocal
(
local
),
uuid
:
local
.
identifier
.
uuid
};
return
this
.
scanUserExtensions
(
false
)
// Uninstall all extensions which are same as requested
.
then
(
extensions
=>
extensions
.
filter
(
i
=>
areSameExtensions
({
id
:
getGalleryExtensionIdFromLocal
(
i
),
uuid
:
i
.
identifier
.
uuid
},
identifier
)))
.
then
(
uninstalled
=>
this
.
setUninstalled
(...
uninstalled
.
map
(
u
=>
u
.
identifier
.
id
)));
}
private
async
postUninstallExtension
(
extension
:
ILocalExtension
,
error
?:
string
):
TPromise
<
void
>
{
...
...
@@ -608,7 +591,7 @@ export class ExtensionManagementService implements IExtensionManagementService {
}
if
(
type
===
null
||
type
===
LocalExtensionType
.
User
)
{
promises
.
push
(
this
.
scanUserExtensions
());
promises
.
push
(
this
.
scanUserExtensions
(
true
));
}
return
TPromise
.
join
<
ILocalExtension
[]
>
(
promises
).
then
(
flatten
);
...
...
@@ -618,11 +601,15 @@ export class ExtensionManagementService implements IExtensionManagementService {
return
this
.
scanExtensions
(
SystemExtensionsRoot
,
LocalExtensionType
.
System
);
}
private
scanUserExtensions
():
TPromise
<
ILocalExtension
[]
>
{
return
this
.
scanExtensions
(
this
.
extensionsPath
,
LocalExtensionType
.
User
).
then
(
extensions
=>
{
const
byId
=
values
(
groupBy
(
extensions
,
p
=>
getGalleryExtensionIdFromLocal
(
p
)));
return
byId
.
map
(
p
=>
p
.
sort
((
a
,
b
)
=>
semver
.
rcompare
(
a
.
manifest
.
version
,
b
.
manifest
.
version
))[
0
]);
});
private
scanUserExtensions
(
excludeOutdated
:
boolean
):
TPromise
<
ILocalExtension
[]
>
{
return
this
.
scanExtensions
(
this
.
extensionsPath
,
LocalExtensionType
.
User
)
.
then
(
extensions
=>
{
if
(
excludeOutdated
)
{
const
byExtension
:
ILocalExtension
[][]
=
groupByExtension
(
extensions
,
e
=>
({
id
:
getGalleryExtensionIdFromLocal
(
e
),
uuid
:
e
.
identifier
.
uuid
}));
return
byExtension
.
map
(
p
=>
p
.
sort
((
a
,
b
)
=>
semver
.
rcompare
(
a
.
manifest
.
version
,
b
.
manifest
.
version
))[
0
]);
}
return
extensions
;
});
}
private
scanExtensions
(
root
:
string
,
type
:
LocalExtensionType
):
TPromise
<
ILocalExtension
[]
>
{
...
...
@@ -659,42 +646,22 @@ export class ExtensionManagementService implements IExtensionManagementService {
}
removeDeprecatedExtensions
():
TPromise
<
any
>
{
return
TPromise
.
join
([
// Remove obsolte extensions first to avoid removing installed older extension. See #38609.
this
.
removeUninstalledExtensions
(),
this
.
removeOutdatedExtensions
()
]);
}
private
removeOutdatedExtensions
():
TPromise
<
any
>
{
return
this
.
getOutdatedExtensionIds
()
.
then
(
extensionIds
=>
this
.
removeExtensions
(
extensionIds
));
}
private
removeUninstalledExtensions
():
TPromise
<
any
>
{
return
this
.
getUninstalledExtensions
()
.
then
(
uninstalled
=>
Object
.
keys
(
uninstalled
))
.
then
(
extensionIds
=>
this
.
removeExtensions
(
extensionIds
));
}
private
removeExtensions
(
extensionsIds
:
string
[]):
TPromise
<
any
>
{
return
TPromise
.
join
(
extensionsIds
.
map
(
id
=>
{
return
pfs
.
rimraf
(
path
.
join
(
this
.
extensionsPath
,
id
))
.
then
(()
=>
this
.
withUninstalledExtensions
(
uninstalled
=>
delete
uninstalled
[
id
]));
}));
}
private
getOutdatedExtensionIds
():
TPromise
<
string
[]
>
{
return
this
.
scanExtensionFolders
(
this
.
extensionsPath
)
.
then
(
folders
=>
{
const
galleryFolders
=
folders
.
map
(
folder
=>
(
assign
({
folder
},
getIdAndVersionFromLocalExtensionId
(
folder
))))
.
filter
(({
id
,
version
})
=>
!!
id
&&
!!
version
);
const
byId
=
values
(
groupBy
(
galleryFolders
,
p
=>
p
.
id
));
return
flatten
(
byId
.
map
(
p
=>
p
.
sort
((
a
,
b
)
=>
semver
.
rcompare
(
a
.
version
,
b
.
version
)).
slice
(
1
)))
.
map
(
a
=>
a
.
folder
);
.
then
(
uninstalled
=>
{
const
unInstalledExtensionIds
=
Object
.
keys
(
uninstalled
);
return
this
.
scanUserExtensions
(
false
)
.
then
(
extensions
=>
{
// Exclude uninstalled extensions
extensions
=
extensions
.
filter
(
e
=>
unInstalledExtensionIds
.
indexOf
(
e
.
identifier
.
id
)
===
-
1
);
const
byExtension
:
ILocalExtension
[][]
=
groupByExtension
(
extensions
,
e
=>
({
id
:
getGalleryExtensionIdFromLocal
(
e
),
uuid
:
e
.
identifier
.
uuid
}));
const
outDatedExtensionIds
=
flatten
(
byExtension
.
map
(
p
=>
p
.
sort
((
a
,
b
)
=>
semver
.
rcompare
(
a
.
manifest
.
version
,
b
.
manifest
.
version
)).
slice
(
1
)))
.
map
(
a
=>
a
.
identifier
.
id
);
return
TPromise
.
join
([...
unInstalledExtensionIds
,
...
outDatedExtensionIds
].
map
(
id
=>
{
return
pfs
.
rimraf
(
path
.
join
(
this
.
extensionsPath
,
id
))
.
then
(()
=>
this
.
withUninstalledExtensions
(
uninstalled
=>
delete
uninstalled
[
id
]));
}));
});
});
}
...
...
@@ -714,8 +681,8 @@ export class ExtensionManagementService implements IExtensionManagementService {
});
}
private
markUninstalled
(
id
:
string
):
TPromise
<
void
>
{
return
this
.
withUninstalledExtensions
(
uninstalled
=>
assign
(
uninstalled
,
{
[
id
]:
true
}
));
private
setUninstalled
(...
ids
:
string
[]
):
TPromise
<
void
>
{
return
this
.
withUninstalledExtensions
(
uninstalled
=>
assign
(
uninstalled
,
ids
.
reduce
((
result
,
id
)
=>
{
result
[
id
]
=
true
;
return
result
;
},
{})
));
}
private
unsetUninstalled
(
id
:
string
):
TPromise
<
void
>
{
...
...
src/vs/workbench/services/extensions/electron-browser/extensionPoints.ts
浏览文件 @
67e8f781
...
...
@@ -9,7 +9,6 @@ import * as nls from 'vs/nls';
import
*
as
pfs
from
'
vs/base/node/pfs
'
;
import
{
IExtensionDescription
}
from
'
vs/platform/extensions/common/extensions
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
groupBy
,
values
}
from
'
vs/base/common/collections
'
;
import
{
join
,
normalize
,
extname
}
from
'
path
'
;
import
*
as
json
from
'
vs/base/common/json
'
;
import
*
as
types
from
'
vs/base/common/types
'
;
...
...
@@ -17,6 +16,7 @@ import { isValidExtensionDescription } from 'vs/platform/extensions/node/extensi
import
*
as
semver
from
'
semver
'
;
import
{
getIdAndVersionFromLocalExtensionId
}
from
'
vs/platform/extensionManagement/node/extensionManagementUtil
'
;
import
{
getParseErrorMessage
}
from
'
vs/base/common/jsonErrorMessages
'
;
import
{
groupByExtension
}
from
'
vs/platform/extensionManagement/common/extensionManagementUtil
'
;
const
MANIFEST_FILE
=
'
package.json
'
;
...
...
@@ -340,7 +340,7 @@ export class ExtensionScanner {
}
else
{
// TODO: align with extensionsService
const
nonGallery
:
string
[]
=
[];
const
gallery
:
{
folder
:
string
;
id
:
string
;
version
:
string
;
}
[]
=
[];
const
gallery
:
string
[]
=
[];
rawFolders
.
forEach
(
folder
=>
{
if
(
obsolete
[
folder
])
{
...
...
@@ -351,22 +351,24 @@ export class ExtensionScanner {
if
(
!
id
||
!
version
)
{
nonGallery
.
push
(
folder
);
return
;
}
else
{
gallery
.
push
(
folder
);
}
gallery
.
push
({
folder
,
id
,
version
});
});
const
byId
=
values
(
groupBy
(
gallery
,
p
=>
p
.
id
));
const
latest
=
byId
.
map
(
p
=>
p
.
sort
((
a
,
b
)
=>
semver
.
rcompare
(
a
.
version
,
b
.
version
))[
0
])
.
map
(
a
=>
a
.
folder
);
folders
=
[...
nonGallery
,
...
latest
];
folders
=
[...
nonGallery
,
...
gallery
];
}
const
nlsConfig
=
ExtensionScannerInput
.
createNLSConfig
(
input
);
let
extensionDescriptions
=
await
TPromise
.
join
(
folders
.
map
(
f
=>
this
.
scanExtension
(
input
.
ourVersion
,
log
,
join
(
absoluteFolderPath
,
f
),
isBuiltin
,
nlsConfig
)));
extensionDescriptions
=
extensionDescriptions
.
filter
(
item
=>
item
!==
null
);
if
(
!
isBuiltin
)
{
// Filter out outdated extensions
const
byExtension
:
IExtensionDescription
[][]
=
groupByExtension
(
extensionDescriptions
,
e
=>
({
id
:
e
.
id
,
uuid
:
e
.
uuid
}));
extensionDescriptions
=
byExtension
.
map
(
p
=>
p
.
sort
((
a
,
b
)
=>
semver
.
rcompare
(
a
.
version
,
b
.
version
))[
0
]);
}
extensionDescriptions
.
sort
((
a
,
b
)
=>
{
if
(
a
.
extensionFolderPath
<
b
.
extensionFolderPath
)
{
return
-
1
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录