Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
79282cda
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,发现更多精彩内容 >>
提交
79282cda
编写于
6月 14, 2017
作者:
S
Sandeep Somavarapu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
#28538 Create a configuration model that can retrieve and merge contents
上级
850c8391
变更
7
显示空白变更内容
内联
并排
Showing
7 changed file
with
222 addition
and
173 deletion
+222
-173
src/vs/platform/configuration/common/configuration.ts
src/vs/platform/configuration/common/configuration.ts
+70
-9
src/vs/platform/configuration/common/model.ts
src/vs/platform/configuration/common/model.ts
+21
-96
src/vs/platform/configuration/node/configurationService.ts
src/vs/platform/configuration/node/configurationService.ts
+13
-13
src/vs/platform/configuration/test/common/configuration.test.ts
.../platform/configuration/test/common/configuration.test.ts
+79
-0
src/vs/platform/configuration/test/common/model.test.ts
src/vs/platform/configuration/test/common/model.test.ts
+23
-38
src/vs/workbench/services/configuration/common/configurationModels.ts
...ench/services/configuration/common/configurationModels.ts
+4
-4
src/vs/workbench/services/configuration/node/configuration.ts
...vs/workbench/services/configuration/node/configuration.ts
+12
-13
未找到文件。
src/vs/platform/configuration/common/configuration.ts
浏览文件 @
79282cda
...
...
@@ -4,6 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
*
as
arrays
from
'
vs/base/common/arrays
'
;
import
*
as
types
from
'
vs/base/common/types
'
;
import
*
as
objects
from
'
vs/base/common/objects
'
;
import
{
createDecorator
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
Event
from
'
vs/base/common/event
'
;
...
...
@@ -101,18 +104,76 @@ export function getConfigurationValue<T>(config: any, settingPath: string, defau
return
typeof
result
===
'
undefined
'
?
defaultValue
:
result
;
}
export
interface
IConfigModel
<
T
>
{
contents
:
T
;
overrides
:
IOverrides
<
T
>
[];
keys
:
string
[];
errors
:
any
[];
merge
(
other
:
IConfigModel
<
T
>
,
overwrite
?:
boolean
):
IConfigModel
<
T
>
;
getContentsFor
<
V
>
(
section
:
string
):
V
;
configWithOverrides
<
V
>
(
identifier
:
string
,
section
?:
string
):
IConfigModel
<
V
>
;
export
function
merge
(
base
:
any
,
add
:
any
,
overwrite
:
boolean
):
void
{
Object
.
keys
(
add
).
forEach
(
key
=>
{
if
(
key
in
base
)
{
if
(
types
.
isObject
(
base
[
key
])
&&
types
.
isObject
(
add
[
key
]))
{
merge
(
base
[
key
],
add
[
key
],
overwrite
);
}
else
if
(
overwrite
)
{
base
[
key
]
=
add
[
key
];
}
}
else
{
base
[
key
]
=
add
[
key
];
}
});
}
export
interface
IOverrides
<
T
>
{
contents
:
T
;
identifiers
:
string
[];
}
export
class
Configuration
<
T
>
{
protected
_keys
:
string
[]
=
[];
constructor
(
protected
_contents
:
T
=
<
T
>
{},
protected
_overrides
:
IOverrides
<
T
>
[]
=
[])
{
}
public
get
contents
():
T
{
return
this
.
_contents
;
}
public
get
keys
():
string
[]
{
return
this
.
_keys
;
}
public
getContentsFor
<
V
>
(
section
:
string
):
V
{
return
objects
.
clone
(
this
.
contents
[
section
]);
}
public
override
<
V
>
(
identifier
:
string
):
Configuration
<
V
>
{
const
result
=
new
Configuration
<
V
>
();
const
contents
=
objects
.
clone
<
any
>
(
this
.
contents
);
if
(
this
.
_overrides
)
{
for
(
const
override
of
this
.
_overrides
)
{
if
(
override
.
identifiers
.
indexOf
(
identifier
)
!==
-
1
)
{
merge
(
contents
,
override
.
contents
,
true
);
}
}
}
result
.
_contents
=
contents
;
return
result
;
}
public
merge
(
other
:
Configuration
<
T
>
,
overwrite
:
boolean
=
true
):
Configuration
<
T
>
{
const
mergedModel
=
new
Configuration
<
T
>
();
this
.
doMerge
(
mergedModel
,
this
,
overwrite
);
this
.
doMerge
(
mergedModel
,
other
,
overwrite
);
return
mergedModel
;
}
protected
doMerge
(
source
:
Configuration
<
T
>
,
target
:
Configuration
<
T
>
,
overwrite
:
boolean
=
true
)
{
merge
(
source
.
contents
,
objects
.
clone
(
target
.
contents
),
overwrite
);
const
overrides
=
objects
.
clone
(
source
.
_overrides
);
for
(
const
override
of
target
.
_overrides
)
{
const
[
sourceOverride
]
=
overrides
.
filter
(
o
=>
arrays
.
equals
(
o
.
identifiers
,
override
.
identifiers
));
if
(
sourceOverride
)
{
merge
(
sourceOverride
.
contents
,
override
.
contents
,
overwrite
);
}
else
{
overrides
.
push
(
override
);
}
}
source
.
_overrides
=
overrides
;
}
}
\ No newline at end of file
src/vs/platform/configuration/common/model.ts
浏览文件 @
79282cda
...
...
@@ -5,12 +5,9 @@
'
use strict
'
;
import
{
Registry
}
from
'
vs/platform/platform
'
;
import
*
as
types
from
'
vs/base/common/types
'
;
import
*
as
json
from
'
vs/base/common/json
'
;
import
*
as
objects
from
'
vs/base/common/objects
'
;
import
*
as
arrays
from
'
vs/base/common/arrays
'
;
import
{
IConfigurationRegistry
,
Extensions
,
OVERRIDE_PROPERTY_PATTERN
}
from
'
vs/platform/configuration/common/configurationRegistry
'
;
import
{
IConfigModel
,
IOverrides
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
Configuration
,
IOverrides
}
from
'
vs/platform/configuration/common/configuration
'
;
export
function
getDefaultValues
():
any
{
const
valueTreeRoot
:
any
=
Object
.
create
(
null
);
...
...
@@ -68,92 +65,45 @@ export function getConfigurationKeys(): string[] {
return
Object
.
keys
(
properties
);
}
export
function
merge
(
base
:
any
,
add
:
any
,
overwrite
:
boolean
):
void
{
Object
.
keys
(
add
).
forEach
(
key
=>
{
if
(
key
in
base
)
{
if
(
types
.
isObject
(
base
[
key
])
&&
types
.
isObject
(
add
[
key
]))
{
merge
(
base
[
key
],
add
[
key
],
overwrite
);
}
else
if
(
overwrite
)
{
base
[
key
]
=
add
[
key
];
export
class
DefaultConfiguration
<
T
>
extends
Configuration
<
T
>
{
constructor
()
{
super
(
getDefaultValues
());
this
.
_keys
=
getConfigurationKeys
();
this
.
_overrides
=
Object
.
keys
(
this
.
_contents
)
.
filter
(
key
=>
OVERRIDE_PROPERTY_PATTERN
.
test
(
key
))
.
map
(
key
=>
{
return
<
IOverrides
<
any
>>
{
identifiers
:
[
overrideIdentifierFromKey
(
key
).
trim
()],
contents
:
toValuesTree
(
this
.
_contents
[
key
],
message
=>
console
.
error
(
`Conflict in default settings file:
${
message
}
`
))
};
});
}
}
else
{
base
[
key
]
=
add
[
key
];
public
get
keys
():
string
[]
{
return
this
.
_keys
;
}
});
}
interface
Overrides
<
T
>
extends
IOverrides
<
T
>
{
raw
:
any
;
}
export
class
C
onfigModel
<
T
>
implements
IConfigModel
<
T
>
{
export
class
C
ustomConfiguration
<
T
>
extends
Configuration
<
T
>
{
protected
_contents
:
T
=
<
T
>
{};
protected
_overrides
:
IOverrides
<
T
>
[]
=
[];
protected
_keys
:
string
[]
=
[];
protected
_parseErrors
:
any
[]
=
[];
constructor
(
content
:
string
=
''
,
private
name
:
string
=
''
)
{
super
();
if
(
content
)
{
this
.
update
(
content
);
}
}
public
get
contents
():
T
{
return
this
.
_contents
;
}
public
get
overrides
():
IOverrides
<
T
>
[]
{
return
this
.
_overrides
;
}
public
get
keys
():
string
[]
{
return
this
.
_keys
;
}
public
get
errors
():
any
[]
{
return
this
.
_parseErrors
;
}
public
merge
(
other
:
IConfigModel
<
T
>
,
overwrite
:
boolean
=
true
):
ConfigModel
<
T
>
{
const
mergedModel
=
new
ConfigModel
<
T
>
(
null
);
this
.
doMerge
(
mergedModel
,
this
,
overwrite
);
this
.
doMerge
(
mergedModel
,
other
,
overwrite
);
return
mergedModel
;
}
protected
doMerge
(
source
:
ConfigModel
<
T
>
,
target
:
IConfigModel
<
T
>
,
overwrite
:
boolean
=
true
)
{
merge
(
source
.
contents
,
objects
.
clone
(
target
.
contents
),
overwrite
);
const
overrides
=
objects
.
clone
(
source
.
overrides
);
for
(
const
override
of
target
.
overrides
)
{
const
[
sourceOverride
]
=
overrides
.
filter
(
o
=>
arrays
.
equals
(
o
.
identifiers
,
override
.
identifiers
));
if
(
sourceOverride
)
{
merge
(
sourceOverride
.
contents
,
override
.
contents
,
overwrite
);
}
else
{
overrides
.
push
(
override
);
}
}
source
.
_overrides
=
overrides
;
}
public
getContentsFor
<
V
>
(
section
:
string
):
V
{
return
objects
.
clone
(
this
.
contents
[
section
]);
}
public
configWithOverrides
<
V
>
(
identifier
:
string
):
ConfigModel
<
V
>
{
const
result
=
new
ConfigModel
<
V
>
(
null
);
const
contents
=
objects
.
clone
<
any
>
(
this
.
contents
);
if
(
this
.
overrides
)
{
for
(
const
override
of
this
.
overrides
)
{
if
(
override
.
identifiers
.
indexOf
(
identifier
)
!==
-
1
)
{
merge
(
contents
,
override
.
contents
,
true
);
}
}
}
result
.
_contents
=
contents
;
return
result
;
}
public
update
(
content
:
string
):
void
{
let
parsed
:
T
=
<
T
>
{};
let
overrides
:
Overrides
<
T
>
[]
=
[];
...
...
@@ -243,31 +193,6 @@ export class ConfigModel<T> implements IConfigModel<T> {
}
}
export
class
DefaultConfigModel
<
T
>
extends
ConfigModel
<
T
>
{
constructor
()
{
super
(
null
);
this
.
update
();
}
public
get
keys
():
string
[]
{
return
this
.
_keys
;
}
public
update
():
void
{
this
.
_contents
=
getDefaultValues
();
// defaults coming from contributions to registries
this
.
_keys
=
getConfigurationKeys
();
this
.
_overrides
=
Object
.
keys
(
this
.
_contents
)
.
filter
(
key
=>
OVERRIDE_PROPERTY_PATTERN
.
test
(
key
))
.
map
(
key
=>
{
return
<
IOverrides
<
any
>>
{
identifiers
:
[
overrideIdentifierFromKey
(
key
).
trim
()],
contents
:
toValuesTree
(
this
.
_contents
[
key
],
message
=>
console
.
error
(
`Conflict in default settings file:
${
message
}
`
))
};
});
}
}
export
function
overrideIdentifierFromKey
(
key
:
string
):
string
{
return
key
.
substring
(
1
,
key
.
length
-
1
);
}
...
...
src/vs/platform/configuration/node/configurationService.ts
浏览文件 @
79282cda
...
...
@@ -10,15 +10,15 @@ import { ConfigWatcher } from 'vs/base/node/config';
import
{
Registry
}
from
'
vs/platform/platform
'
;
import
{
IConfigurationRegistry
,
Extensions
}
from
'
vs/platform/configuration/common/configurationRegistry
'
;
import
{
IDisposable
,
toDisposable
,
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
ConfigurationSource
,
IConfigurationService
,
IConfigurationServiceEvent
,
IConfigurationValue
,
getConfigurationValue
,
IConfigurationKeys
,
IConfigModel
,
IConfigurationOptions
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
C
onfigModel
,
DefaultConfigModel
}
from
'
vs/platform/configuration/common/model
'
;
import
{
ConfigurationSource
,
IConfigurationService
,
IConfigurationServiceEvent
,
IConfigurationValue
,
getConfigurationValue
,
IConfigurationKeys
,
Configuration
,
IConfigurationOptions
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
C
ustomConfiguration
,
DefaultConfiguration
}
from
'
vs/platform/configuration/common/model
'
;
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
IEnvironmentService
}
from
'
vs/platform/environment/common/environment
'
;
export
interface
ICache
<
T
>
{
defaults
:
IConfigModel
<
T
>
;
user
:
IConfigModel
<
T
>
;
consolidated
:
IConfigModel
<
any
>
;
defaults
:
Configuration
<
T
>
;
user
:
Configuration
<
T
>
;
consolidated
:
Configuration
<
any
>
;
}
export
class
ConfigurationService
<
T
>
extends
Disposable
implements
IConfigurationService
,
IDisposable
{
...
...
@@ -26,7 +26,7 @@ export class ConfigurationService<T> extends Disposable implements IConfiguratio
_serviceBrand
:
any
;
private
cache
:
ICache
<
T
>
;
private
userConfigModelWatcher
:
ConfigWatcher
<
IConfigModel
<
T
>>
;
private
userConfigModelWatcher
:
ConfigWatcher
<
Configuration
<
T
>>
;
private
_onDidUpdateConfiguration
:
Emitter
<
IConfigurationServiceEvent
>
=
this
.
_register
(
new
Emitter
<
IConfigurationServiceEvent
>
());
public
readonly
onDidUpdateConfiguration
:
Event
<
IConfigurationServiceEvent
>
=
this
.
_onDidUpdateConfiguration
.
event
;
...
...
@@ -37,8 +37,8 @@ export class ConfigurationService<T> extends Disposable implements IConfiguratio
super
();
this
.
userConfigModelWatcher
=
new
ConfigWatcher
(
environmentService
.
appSettingsPath
,
{
changeBufferDelay
:
300
,
defaultConfig
:
new
C
onfigModel
<
T
>
(
null
,
environmentService
.
appSettingsPath
),
parse
:
(
content
:
string
,
parseErrors
:
any
[])
=>
{
const
userConfigModel
=
new
C
onfigModel
<
T
>
(
content
,
environmentService
.
appSettingsPath
);
changeBufferDelay
:
300
,
defaultConfig
:
new
C
ustomConfiguration
<
T
>
(
null
,
environmentService
.
appSettingsPath
),
parse
:
(
content
:
string
,
parseErrors
:
any
[])
=>
{
const
userConfigModel
=
new
C
ustomConfiguration
<
T
>
(
content
,
environmentService
.
appSettingsPath
);
parseErrors
=
[...
userConfigModel
.
errors
];
return
userConfigModel
;
}
...
...
@@ -77,7 +77,7 @@ export class ConfigurationService<T> extends Disposable implements IConfiguratio
public
getConfiguration
<
C
>
(
arg
?:
any
):
C
{
const
options
=
this
.
toOptions
(
arg
);
const
cache
=
this
.
getCache
();
const
configModel
=
options
.
overrideIdentifier
?
cache
.
consolidated
.
configWithOverrides
<
C
>
(
options
.
overrideIdentifier
)
:
cache
.
consolidated
;
const
configModel
=
options
.
overrideIdentifier
?
cache
.
consolidated
.
override
<
C
>
(
options
.
overrideIdentifier
)
:
cache
.
consolidated
;
return
options
.
section
?
configModel
.
getContentsFor
<
C
>
(
options
.
section
)
:
configModel
.
contents
;
}
...
...
@@ -86,9 +86,9 @@ export class ConfigurationService<T> extends Disposable implements IConfiguratio
// make sure to clone the configuration so that the receiver does not tamper with the values
return
{
default
:
objects
.
clone
(
getConfigurationValue
<
C
>
(
overrideIdentifier
?
cache
.
defaults
.
configWithOverrides
(
overrideIdentifier
).
contents
:
cache
.
defaults
.
contents
,
key
)),
user
:
objects
.
clone
(
getConfigurationValue
<
C
>
(
overrideIdentifier
?
cache
.
user
.
configWithOverrides
(
overrideIdentifier
).
contents
:
cache
.
user
.
contents
,
key
)),
value
:
objects
.
clone
(
getConfigurationValue
<
C
>
(
overrideIdentifier
?
cache
.
consolidated
.
configWithOverrides
(
overrideIdentifier
).
contents
:
cache
.
consolidated
.
contents
,
key
))
default
:
objects
.
clone
(
getConfigurationValue
<
C
>
(
overrideIdentifier
?
cache
.
defaults
.
override
(
overrideIdentifier
).
contents
:
cache
.
defaults
.
contents
,
key
)),
user
:
objects
.
clone
(
getConfigurationValue
<
C
>
(
overrideIdentifier
?
cache
.
user
.
override
(
overrideIdentifier
).
contents
:
cache
.
user
.
contents
,
key
)),
value
:
objects
.
clone
(
getConfigurationValue
<
C
>
(
overrideIdentifier
?
cache
.
consolidated
.
override
(
overrideIdentifier
).
contents
:
cache
.
consolidated
.
contents
,
key
))
};
}
...
...
@@ -116,7 +116,7 @@ export class ConfigurationService<T> extends Disposable implements IConfiguratio
}
private
consolidateConfigurations
():
ICache
<
T
>
{
const
defaults
=
new
DefaultConfig
Model
<
T
>
();
const
defaults
=
new
DefaultConfig
uration
<
T
>
();
const
user
=
this
.
userConfigModelWatcher
.
getConfig
();
const
consolidated
=
defaults
.
merge
(
user
);
return
{
defaults
,
user
,
consolidated
};
...
...
src/vs/platform/configuration/test/common/configuration.test.ts
0 → 100644
浏览文件 @
79282cda
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
*
as
assert
from
'
assert
'
;
import
{
Configuration
,
merge
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
Extensions
,
IConfigurationRegistry
}
from
'
vs/platform/configuration/common/configurationRegistry
'
;
import
{
Registry
}
from
'
vs/platform/platform
'
;
suite
(
'
Configuration
'
,
()
=>
{
suiteSetup
(()
=>
{
Registry
.
as
<
IConfigurationRegistry
>
(
Extensions
.
Configuration
).
registerConfiguration
({
'
id
'
:
'
a
'
,
'
order
'
:
1
,
'
title
'
:
'
a
'
,
'
type
'
:
'
object
'
,
'
properties
'
:
{
'
a
'
:
{
'
description
'
:
'
a
'
,
'
type
'
:
'
boolean
'
,
'
default
'
:
true
,
'
overridable
'
:
true
}
}
});
});
test
(
'
simple merge
'
,
()
=>
{
let
base
=
{
'
a
'
:
1
,
'
b
'
:
2
};
merge
(
base
,
{
'
a
'
:
3
,
'
c
'
:
4
},
true
);
assert
.
deepEqual
(
base
,
{
'
a
'
:
3
,
'
b
'
:
2
,
'
c
'
:
4
});
base
=
{
'
a
'
:
1
,
'
b
'
:
2
};
merge
(
base
,
{
'
a
'
:
3
,
'
c
'
:
4
},
false
);
assert
.
deepEqual
(
base
,
{
'
a
'
:
1
,
'
b
'
:
2
,
'
c
'
:
4
});
});
test
(
'
Recursive merge
'
,
()
=>
{
const
base
=
{
'
a
'
:
{
'
b
'
:
1
}
};
merge
(
base
,
{
'
a
'
:
{
'
b
'
:
2
}
},
true
);
assert
.
deepEqual
(
base
,
{
'
a
'
:
{
'
b
'
:
2
}
});
});
test
(
'
simple merge using configuration
'
,
()
=>
{
let
base
=
new
Configuration
<
any
>
({
'
a
'
:
1
,
'
b
'
:
2
});
let
add
=
new
Configuration
<
any
>
({
'
a
'
:
3
,
'
c
'
:
4
});
let
result
=
base
.
merge
(
add
);
assert
.
deepEqual
(
result
.
contents
,
{
'
a
'
:
3
,
'
b
'
:
2
,
'
c
'
:
4
});
});
test
(
'
Recursive merge using config models
'
,
()
=>
{
let
base
=
new
Configuration
({
'
a
'
:
{
'
b
'
:
1
}
});
let
add
=
new
Configuration
({
'
a
'
:
{
'
b
'
:
2
}
});
let
result
=
base
.
merge
(
add
);
assert
.
deepEqual
(
result
.
contents
,
{
'
a
'
:
{
'
b
'
:
2
}
});
});
test
(
'
Test contents while getting an existing property
'
,
()
=>
{
let
testObject
=
new
Configuration
({
'
a
'
:
1
});
assert
.
deepEqual
(
testObject
.
getContentsFor
(
'
a
'
),
1
);
testObject
=
new
Configuration
<
any
>
({
'
a
'
:
{
'
b
'
:
1
}
});
assert
.
deepEqual
(
testObject
.
getContentsFor
(
'
a
'
),
{
'
b
'
:
1
});
});
test
(
'
Test contents are undefined for non existing properties
'
,
()
=>
{
const
testObject
=
new
Configuration
({
awesome
:
true
});
assert
.
deepEqual
(
testObject
.
getContentsFor
(
'
unknownproperty
'
),
undefined
);
});
test
(
'
Test override gives all content merged with overrides
'
,
()
=>
{
const
testObject
=
new
Configuration
<
any
>
({
'
a
'
:
1
,
'
c
'
:
1
},
[{
identifiers
:
[
'
b
'
],
contents
:
{
'
a
'
:
2
}
}]);
assert
.
deepEqual
(
testObject
.
override
(
'
b
'
).
contents
,
{
'
a
'
:
2
,
'
c
'
:
1
});
});
});
\ No newline at end of file
src/vs/platform/configuration/test/common/model.test.ts
浏览文件 @
79282cda
...
...
@@ -5,11 +5,11 @@
'
use strict
'
;
import
*
as
assert
from
'
assert
'
;
import
*
as
model
from
'
vs/platform/configuration/common/model
'
;
import
{
CustomConfiguration
,
DefaultConfiguration
}
from
'
vs/platform/configuration/common/model
'
;
import
{
Extensions
,
IConfigurationRegistry
}
from
'
vs/platform/configuration/common/configurationRegistry
'
;
import
{
Registry
}
from
'
vs/platform/platform
'
;
suite
(
'
Configuration
Service - Model
'
,
()
=>
{
suite
(
'
Configuration
'
,
()
=>
{
suiteSetup
(()
=>
{
Registry
.
as
<
IConfigurationRegistry
>
(
Extensions
.
Configuration
).
registerConfiguration
({
...
...
@@ -28,62 +28,47 @@ suite('ConfigurationService - Model', () => {
});
});
test
(
'
simple merge
'
,
()
=>
{
let
base
=
{
'
a
'
:
1
,
'
b
'
:
2
};
model
.
merge
(
base
,
{
'
a
'
:
3
,
'
c
'
:
4
},
true
);
assert
.
deepEqual
(
base
,
{
'
a
'
:
3
,
'
b
'
:
2
,
'
c
'
:
4
});
base
=
{
'
a
'
:
1
,
'
b
'
:
2
};
model
.
merge
(
base
,
{
'
a
'
:
3
,
'
c
'
:
4
},
false
);
assert
.
deepEqual
(
base
,
{
'
a
'
:
1
,
'
b
'
:
2
,
'
c
'
:
4
});
});
test
(
'
Recursive merge
'
,
()
=>
{
const
base
=
{
'
a
'
:
{
'
b
'
:
1
}
};
model
.
merge
(
base
,
{
'
a
'
:
{
'
b
'
:
2
}
},
true
);
assert
.
deepEqual
(
base
,
{
'
a
'
:
{
'
b
'
:
2
}
});
});
test
(
'
simple merge using models
'
,
()
=>
{
let
base
=
new
model
.
ConfigModel
(
JSON
.
stringify
({
'
a
'
:
1
,
'
b
'
:
2
}));
let
add
=
new
model
.
ConfigModel
(
JSON
.
stringify
({
'
a
'
:
3
,
'
c
'
:
4
}));
let
base
=
new
CustomConfiguration
(
JSON
.
stringify
({
'
a
'
:
1
,
'
b
'
:
2
}));
let
add
=
new
CustomConfiguration
(
JSON
.
stringify
({
'
a
'
:
3
,
'
c
'
:
4
}));
let
result
=
base
.
merge
(
add
);
assert
.
deepEqual
(
result
.
contents
,
{
'
a
'
:
3
,
'
b
'
:
2
,
'
c
'
:
4
});
});
test
(
'
simple merge with an undefined contents
'
,
()
=>
{
let
base
=
new
model
.
ConfigModel
(
JSON
.
stringify
({
'
a
'
:
1
,
'
b
'
:
2
}));
let
add
=
new
model
.
ConfigModel
(
null
);
let
base
=
new
CustomConfiguration
(
JSON
.
stringify
({
'
a
'
:
1
,
'
b
'
:
2
}));
let
add
=
new
CustomConfiguration
(
null
);
let
result
=
base
.
merge
(
add
);
assert
.
deepEqual
(
result
.
contents
,
{
'
a
'
:
1
,
'
b
'
:
2
});
base
=
new
model
.
ConfigModel
(
null
);
add
=
new
model
.
ConfigModel
(
JSON
.
stringify
({
'
a
'
:
1
,
'
b
'
:
2
}));
base
=
new
CustomConfiguration
(
null
);
add
=
new
CustomConfiguration
(
JSON
.
stringify
({
'
a
'
:
1
,
'
b
'
:
2
}));
result
=
base
.
merge
(
add
);
assert
.
deepEqual
(
result
.
contents
,
{
'
a
'
:
1
,
'
b
'
:
2
});
base
=
new
model
.
ConfigModel
(
null
);
add
=
new
model
.
ConfigModel
(
null
);
base
=
new
CustomConfiguration
(
null
);
add
=
new
CustomConfiguration
(
null
);
result
=
base
.
merge
(
add
);
assert
.
deepEqual
(
result
.
contents
,
{});
});
test
(
'
Recursive merge using config models
'
,
()
=>
{
let
base
=
new
model
.
ConfigModel
(
JSON
.
stringify
({
'
a
'
:
{
'
b
'
:
1
}
}));
let
add
=
new
model
.
ConfigModel
(
JSON
.
stringify
({
'
a
'
:
{
'
b
'
:
2
}
}));
let
base
=
new
CustomConfiguration
(
JSON
.
stringify
({
'
a
'
:
{
'
b
'
:
1
}
}));
let
add
=
new
CustomConfiguration
(
JSON
.
stringify
({
'
a
'
:
{
'
b
'
:
2
}
}));
let
result
=
base
.
merge
(
add
);
assert
.
deepEqual
(
result
.
contents
,
{
'
a
'
:
{
'
b
'
:
2
}
});
});
test
(
'
Test contents while getting an existing property
'
,
()
=>
{
let
testObject
=
new
model
.
ConfigModel
(
JSON
.
stringify
({
'
a
'
:
1
}));
let
testObject
=
new
CustomConfiguration
(
JSON
.
stringify
({
'
a
'
:
1
}));
assert
.
deepEqual
(
testObject
.
getContentsFor
(
'
a
'
),
1
);
testObject
=
new
model
.
ConfigModel
(
JSON
.
stringify
({
'
a
'
:
{
'
b
'
:
1
}
}));
testObject
=
new
CustomConfiguration
(
JSON
.
stringify
({
'
a
'
:
{
'
b
'
:
1
}
}));
assert
.
deepEqual
(
testObject
.
getContentsFor
(
'
a
'
),
{
'
b
'
:
1
});
});
test
(
'
Test contents are undefined for non existing properties
'
,
()
=>
{
const
testObject
=
new
model
.
ConfigModel
(
JSON
.
stringify
({
const
testObject
=
new
CustomConfiguration
(
JSON
.
stringify
({
awesome
:
true
}));
...
...
@@ -91,25 +76,25 @@ suite('ConfigurationService - Model', () => {
});
test
(
'
Test contents are undefined for undefined config
'
,
()
=>
{
const
testObject
=
new
model
.
ConfigModel
(
null
);
const
testObject
=
new
CustomConfiguration
(
null
);
assert
.
deepEqual
(
testObject
.
getContentsFor
(
'
unknownproperty
'
),
undefined
);
});
test
(
'
Test configWithOverrides gives all content merged with overrides
'
,
()
=>
{
const
testObject
=
new
model
.
ConfigModel
(
JSON
.
stringify
({
'
a
'
:
1
,
'
c
'
:
1
,
'
[b]
'
:
{
'
a
'
:
2
}
}));
const
testObject
=
new
CustomConfiguration
(
JSON
.
stringify
({
'
a
'
:
1
,
'
c
'
:
1
,
'
[b]
'
:
{
'
a
'
:
2
}
}));
assert
.
deepEqual
(
testObject
.
configWithOverrides
(
'
b
'
).
contents
,
{
'
a
'
:
2
,
'
c
'
:
1
,
'
[b]
'
:
{
'
a
'
:
2
}
});
assert
.
deepEqual
(
testObject
.
override
(
'
b
'
).
contents
,
{
'
a
'
:
2
,
'
c
'
:
1
,
'
[b]
'
:
{
'
a
'
:
2
}
});
});
test
(
'
Test configWithOverrides gives empty contents
'
,
()
=>
{
const
testObject
=
new
model
.
ConfigModel
(
null
);
const
testObject
=
new
CustomConfiguration
(
null
);
assert
.
deepEqual
(
testObject
.
configWithOverrides
(
'
b
'
).
contents
,
{});
assert
.
deepEqual
(
testObject
.
override
(
'
b
'
).
contents
,
{});
});
test
(
'
Test update with empty data
'
,
()
=>
{
const
testObject
=
new
model
.
ConfigModel
();
const
testObject
=
new
CustomConfiguration
();
testObject
.
update
(
''
);
assert
.
deepEqual
(
testObject
.
contents
,
{});
...
...
@@ -140,7 +125,7 @@ suite('ConfigurationService - Model', () => {
}
}
});
assert
.
equal
(
true
,
new
model
.
DefaultConfigModel
().
getContentsFor
(
'
a
'
));
assert
.
equal
(
true
,
new
DefaultConfiguration
().
getContentsFor
(
'
a
'
));
});
test
(
'
Test registering the language property
'
,
()
=>
{
...
...
@@ -157,7 +142,7 @@ suite('ConfigurationService - Model', () => {
}
}
});
assert
.
equal
(
undefined
,
new
model
.
DefaultConfigModel
().
getContentsFor
(
'
[a]
'
));
assert
.
equal
(
undefined
,
new
DefaultConfiguration
().
getContentsFor
(
'
[a]
'
));
});
});
\ No newline at end of file
src/vs/workbench/services/configuration/common/configurationModels.ts
浏览文件 @
79282cda
...
...
@@ -4,12 +4,12 @@
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
C
onfigModel
}
from
'
vs/platform/configuration/common/model
'
;
import
{
C
ustomConfiguration
}
from
'
vs/platform/configuration/common/model
'
;
import
{
WORKSPACE_STANDALONE_CONFIGURATIONS
}
from
'
vs/workbench/services/configuration/common/configuration
'
;
import
{
Registry
}
from
'
vs/platform/platform
'
;
import
{
IConfigurationRegistry
,
IConfigurationPropertySchema
,
Extensions
}
from
'
vs/platform/configuration/common/configurationRegistry
'
;
export
class
ScopedConfigModel
<
T
>
extends
C
onfigModel
<
T
>
{
export
class
ScopedConfigModel
<
T
>
extends
C
ustomConfiguration
<
T
>
{
constructor
(
content
:
string
,
name
:
string
,
public
readonly
scope
:
string
)
{
super
(
null
,
name
);
...
...
@@ -25,7 +25,7 @@ export class ScopedConfigModel<T> extends ConfigModel<T> {
}
export
class
WorkspaceSettingsConfigModel
<
T
>
extends
C
onfigModel
<
T
>
{
export
class
WorkspaceSettingsConfigModel
<
T
>
extends
C
ustomConfiguration
<
T
>
{
private
_raw
:
T
;
private
_unsupportedKeys
:
string
[];
...
...
@@ -62,7 +62,7 @@ export class WorkspaceSettingsConfigModel<T> extends ConfigModel<T> {
}
}
export
class
WorkspaceConfigModel
<
T
>
extends
C
onfigModel
<
T
>
{
export
class
WorkspaceConfigModel
<
T
>
extends
C
ustomConfiguration
<
T
>
{
constructor
(
public
readonly
workspaceSettingsConfig
:
WorkspaceSettingsConfigModel
<
T
>
,
private
scopedConfigs
:
ScopedConfigModel
<
T
>
[])
{
super
();
...
...
src/vs/workbench/services/configuration/node/configuration.ts
浏览文件 @
79282cda
...
...
@@ -20,9 +20,8 @@ import * as extfs from 'vs/base/node/extfs';
import
{
IWorkspaceContextService
,
IWorkspace2
,
Workspace
as
SingleRootWorkspace
,
IWorkspace
}
from
"
vs/platform/workspace/common/workspace
"
;
import
{
IEnvironmentService
}
from
'
vs/platform/environment/common/environment
'
;
import
{
FileChangeType
,
FileChangesEvent
,
isEqual
}
from
'
vs/platform/files/common/files
'
;
import
{
ConfigModel
}
from
'
vs/platform/configuration/common/model
'
;
import
{
ScopedConfigModel
,
WorkspaceConfigModel
,
WorkspaceSettingsConfigModel
}
from
'
vs/workbench/services/configuration/common/configurationModels
'
;
import
{
IConfigurationServiceEvent
,
ConfigurationSource
,
getConfigurationValue
,
IConfig
Model
,
IConfigurationOptions
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
IConfigurationServiceEvent
,
ConfigurationSource
,
getConfigurationValue
,
IConfig
urationOptions
,
Configuration
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
IWorkspaceConfigurationValues
,
IWorkspaceConfigurationService
,
IWorkspaceConfigurationValue
,
WORKSPACE_CONFIG_FOLDER_DEFAULT_NAME
,
WORKSPACE_STANDALONE_CONFIGURATIONS
,
WORKSPACE_CONFIG_DEFAULT_PATH
}
from
'
vs/workbench/services/configuration/common/configuration
'
;
import
{
ConfigurationService
as
GlobalConfigurationService
}
from
'
vs/platform/configuration/node/configurationService
'
;
...
...
@@ -68,11 +67,11 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
private
baseConfigurationService
:
GlobalConfigurationService
<
any
>
;
private
cachedConfig
:
Config
Model
<
any
>
;
private
cachedConfig
:
Config
uration
<
any
>
;
private
cachedWorkspaceConfig
:
WorkspaceConfigModel
<
any
>
;
private
bulkFetchFromWorkspacePromise
:
TPromise
<
any
>
;
private
workspaceFilePathToConfiguration
:
{
[
relativeWorkspacePath
:
string
]:
TPromise
<
IConfigModel
<
any
>>
};
private
workspaceFilePathToConfiguration
:
{
[
relativeWorkspacePath
:
string
]:
TPromise
<
Configuration
<
any
>>
};
private
reloadConfigurationScheduler
:
RunOnceScheduler
;
private
readonly
workspace
:
Workspace
;
...
...
@@ -83,7 +82,7 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
this
.
workspace
=
singleRootWorkspace
?
new
Workspace
(
singleRootWorkspace
.
resource
.
toString
(),
[
singleRootWorkspace
.
resource
])
:
null
;
this
.
workspaceFilePathToConfiguration
=
Object
.
create
(
null
);
this
.
cachedConfig
=
new
Config
Model
<
any
>
(
null
);
this
.
cachedConfig
=
new
Config
uration
<
any
>
(
);
this
.
cachedWorkspaceConfig
=
new
WorkspaceConfigModel
(
new
WorkspaceSettingsConfigModel
(
null
),
[]);
this
.
baseConfigurationService
=
this
.
_register
(
new
GlobalConfigurationService
(
environmentService
));
...
...
@@ -162,7 +161,7 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
}
// update cached config when base config changes
const
configModel
=
<
Config
Model
<
any
>>
this
.
baseConfigurationService
.
getCache
().
consolidated
// global/default values (do NOT modify)
const
configModel
=
<
Config
uration
<
any
>>
this
.
baseConfigurationService
.
getCache
().
consolidated
// global/default values (do NOT modify)
.
merge
(
this
.
cachedWorkspaceConfig
);
// workspace configured values
// emit this as update to listeners if changed
...
...
@@ -184,7 +183,7 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
public
getConfiguration
<
C
>
(
options
?:
IConfigurationOptions
):
C
public
getConfiguration
<
C
>
(
arg
?:
any
):
C
{
const
options
=
this
.
toOptions
(
arg
);
const
configModel
=
options
.
overrideIdentifier
?
this
.
cachedConfig
.
configWithOverrides
<
C
>
(
options
.
overrideIdentifier
)
:
this
.
cachedConfig
;
const
configModel
=
options
.
overrideIdentifier
?
this
.
cachedConfig
.
override
<
C
>
(
options
.
overrideIdentifier
)
:
this
.
cachedConfig
;
return
options
.
section
?
configModel
.
getContentsFor
<
C
>
(
options
.
section
)
:
configModel
.
contents
;
}
...
...
@@ -193,8 +192,8 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
return
{
default
:
configurationValue
.
default
,
user
:
configurationValue
.
user
,
workspace
:
objects
.
clone
(
getConfigurationValue
<
C
>
(
overrideIdentifier
?
this
.
cachedWorkspaceConfig
.
configWithOverrides
(
overrideIdentifier
).
contents
:
this
.
cachedWorkspaceConfig
.
contents
,
key
)),
value
:
objects
.
clone
(
getConfigurationValue
<
C
>
(
overrideIdentifier
?
this
.
cachedConfig
.
configWithOverrides
(
overrideIdentifier
).
contents
:
this
.
cachedConfig
.
contents
,
key
))
workspace
:
objects
.
clone
(
getConfigurationValue
<
C
>
(
overrideIdentifier
?
this
.
cachedWorkspaceConfig
.
override
(
overrideIdentifier
).
contents
:
this
.
cachedWorkspaceConfig
.
contents
,
key
)),
value
:
objects
.
clone
(
getConfigurationValue
<
C
>
(
overrideIdentifier
?
this
.
cachedConfig
.
override
(
overrideIdentifier
).
contents
:
this
.
cachedConfig
.
contents
,
key
))
};
}
...
...
@@ -268,7 +267,7 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
this
.
cachedWorkspaceConfig
=
new
WorkspaceConfigModel
<
T
>
(
workspaceSettingsConfig
,
otherConfigModels
);
// Override base (global < user) with workspace locals (global < user < workspace)
this
.
cachedConfig
=
<
Config
Model
<
any
>>
this
.
baseConfigurationService
.
getCache
().
consolidated
// global/default values (do NOT modify)
this
.
cachedConfig
=
<
Config
uration
<
any
>>
this
.
baseConfigurationService
.
getCache
().
consolidated
// global/default values (do NOT modify)
.
merge
(
this
.
cachedWorkspaceConfig
);
// workspace configured values
return
{
...
...
@@ -278,7 +277,7 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
});
}
private
loadWorkspaceConfigFiles
<
T
>
():
TPromise
<
{
[
relativeWorkspacePath
:
string
]:
IConfigModel
<
T
>
}
>
{
private
loadWorkspaceConfigFiles
<
T
>
():
TPromise
<
{
[
relativeWorkspacePath
:
string
]:
Configuration
<
T
>
}
>
{
// Return early if we don't have a workspace
if
(
!
this
.
workspace
)
{
...
...
@@ -363,7 +362,7 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
}
}
private
createConfigModel
<
T
>
(
content
:
IContent
):
IConfigModel
<
T
>
{
private
createConfigModel
<
T
>
(
content
:
IContent
):
Configuration
<
T
>
{
const
path
=
this
.
toWorkspaceRelativePath
(
content
.
resource
);
if
(
path
===
WORKSPACE_CONFIG_DEFAULT_PATH
)
{
return
new
WorkspaceSettingsConfigModel
<
T
>
(
content
.
value
,
content
.
resource
.
toString
());
...
...
@@ -374,7 +373,7 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
}
}
return
new
Config
Model
<
T
>
(
null
);
return
new
Config
uration
<
T
>
(
);
}
private
isWorkspaceConfigurationFile
(
workspaceRelativePath
:
string
):
boolean
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录