@@ -9,12 +9,13 @@ import URI from 'vs/base/common/uri';
99import Event , { Emitter } from 'vs/base/common/event' ;
1010import * as vscode from 'vscode' ;
1111import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace' ;
12- import { ExtHostConfigurationShape , MainThreadConfigurationShape , IWorkspaceConfigurationChangeEventData } from './extHost.protocol' ;
12+ import { ExtHostConfigurationShape , MainThreadConfigurationShape , IWorkspaceConfigurationChangeEventData , IConfigurationInitData } from './extHost.protocol' ;
1313import { ConfigurationTarget as ExtHostConfigurationTarget } from './extHostTypes' ;
1414import { IConfigurationData , ConfigurationTarget } from 'vs/platform/configuration/common/configuration' ;
1515import { Configuration , ConfigurationModel , ConfigurationChangeEvent } from 'vs/platform/configuration/common/configurationModels' ;
1616import { WorkspaceConfigurationChangeEvent } from 'vs/workbench/services/configuration/common/configurationModels' ;
1717import { StrictResourceMap } from 'vs/base/common/map' ;
18+ import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry' ;
1819
1920function lookUp ( tree : any , key : string ) {
2021 if ( key ) {
@@ -40,12 +41,14 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
4041 private readonly _onDidChangeConfiguration = new Emitter < vscode . ConfigurationChangeEvent > ( ) ;
4142 private readonly _proxy : MainThreadConfigurationShape ;
4243 private readonly _extHostWorkspace : ExtHostWorkspace ;
44+ private _configurationScopes : Map < string , ConfigurationScope > ;
4345 private _configuration : Configuration ;
4446
45- constructor ( proxy : MainThreadConfigurationShape , extHostWorkspace : ExtHostWorkspace , data : IConfigurationData ) {
47+ constructor ( proxy : MainThreadConfigurationShape , extHostWorkspace : ExtHostWorkspace , data : IConfigurationInitData ) {
4648 this . _proxy = proxy ;
4749 this . _extHostWorkspace = extHostWorkspace ;
4850 this . _configuration = Configuration . parse ( data ) ;
51+ this . _readConfigurationScopes ( data . configurationScopes ) ;
4952 }
5053
5154 get onDidChangeConfiguration ( ) : Event < vscode . ConfigurationChangeEvent > {
@@ -54,14 +57,18 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
5457
5558 $acceptConfigurationChanged ( data : IConfigurationData , eventData : IWorkspaceConfigurationChangeEventData ) {
5659 this . _configuration = Configuration . parse ( data ) ;
57- this . _onDidChangeConfiguration . fire ( this . toConfigurationChangeEvent ( eventData ) ) ;
60+ this . _onDidChangeConfiguration . fire ( this . _toConfigurationChangeEvent ( eventData ) ) ;
5861 }
5962
60- getConfiguration ( section ?: string , resource ?: URI ) : vscode . WorkspaceConfiguration {
63+ getConfiguration ( section ?: string , resource ?: URI , extensionId ?: string ) : vscode . WorkspaceConfiguration {
6164 const config = section
6265 ? lookUp ( this . _configuration . getSection ( null , { resource } , this . _extHostWorkspace . workspace ) , section )
6366 : this . _configuration . getSection ( null , { resource } , this . _extHostWorkspace . workspace ) ;
6467
68+ if ( section ) {
69+ this . _validateConfigurationAccess ( section , resource , extensionId ) ;
70+ }
71+
6572 function parseConfigurationTarget ( arg : boolean | ExtHostConfigurationTarget ) : ConfigurationTarget {
6673 if ( arg === void 0 || arg === null ) {
6774 return null ;
@@ -81,7 +88,8 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
8188 has ( key : string ) : boolean {
8289 return typeof lookUp ( config , key ) !== 'undefined' ;
8390 } ,
84- get < T > ( key : string , defaultValue ?: T ) : T {
91+ get : < T > ( key : string , defaultValue ?: T ) => {
92+ this . _validateConfigurationAccess ( section ? `${ section } .${ key } ` : key , resource , extensionId ) ;
8593 let result = lookUp ( config , key ) ;
8694 if ( typeof result === 'undefined' ) {
8795 result = defaultValue ;
@@ -90,6 +98,7 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
9098 } ,
9199 update : ( key : string , value : any , arg : ExtHostConfigurationTarget | boolean ) => {
92100 key = section ? `${ section } .${ key } ` : key ;
101+ this . _validateConfigurationAccess ( key , resource , extensionId ) ;
93102 const target = parseConfigurationTarget ( arg ) ;
94103 if ( value !== void 0 ) {
95104 return this . _proxy . $updateConfigurationOption ( target , key , value , resource ) ;
@@ -120,7 +129,36 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
120129 return < vscode . WorkspaceConfiguration > Object . freeze ( result ) ;
121130 }
122131
123- private toConfigurationChangeEvent ( data : IWorkspaceConfigurationChangeEventData ) : vscode . ConfigurationChangeEvent {
132+ private _validateConfigurationAccess ( key : string , resource : URI , extensionId : string ) : void {
133+ const scope = this . _configurationScopes . get ( key ) ;
134+ const extensionIdText = extensionId ? `[${ extensionId } ] ` : '' ;
135+ if ( ConfigurationScope . RESOURCE === scope ) {
136+ if ( ! resource ) {
137+ console . warn ( `${ extensionIdText } Accessing a resource scoped configuration without providing a resource is not expected. To get the effective value for '${ key } ', provide the resource for which the value is needed. If you would like to look up all values, use 'inspect' method instead.` ) ;
138+ }
139+ return ;
140+ }
141+ if ( ConfigurationScope . WINDOW === scope ) {
142+ if ( resource ) {
143+ console . warn ( `${ extensionIdText } Accessing a window scoped configuration for a resource is not expected. To associate '${ key } ' to a resource, define its scope to 'resource' in configuration contributions in 'package.json'.` ) ;
144+ }
145+ return ;
146+ }
147+ }
148+
149+ private _readConfigurationScopes ( scopes : ConfigurationScope [ ] ) : void {
150+ this . _configurationScopes = new Map < string , ConfigurationScope > ( ) ;
151+ if ( scopes . length ) {
152+ const defaultKeys = this . _configuration . keys ( this . _extHostWorkspace . workspace ) . default ;
153+ if ( defaultKeys . length === scopes . length ) {
154+ for ( let i = 0 ; i < defaultKeys . length ; i ++ ) {
155+ this . _configurationScopes . set ( defaultKeys [ i ] , scopes [ i ] ) ;
156+ }
157+ }
158+ }
159+ }
160+
161+ private _toConfigurationChangeEvent ( data : IWorkspaceConfigurationChangeEventData ) : vscode . ConfigurationChangeEvent {
124162 const changedConfiguration = new ConfigurationModel ( data . changedConfiguration . contents , data . changedConfiguration . keys , data . changedConfiguration . overrides ) ;
125163 const changedConfigurationByResource : StrictResourceMap < ConfigurationModel > = new StrictResourceMap < ConfigurationModel > ( ) ;
126164 for ( const key of Object . keys ( data . changedConfigurationByResource ) ) {
0 commit comments