entering the lair of debt
This commit is contained in:
parent
32b4b8124e
commit
70d6ae4687
|
@ -28,7 +28,7 @@ import {IMessageService} from 'vs/platform/message/common/message';
|
|||
import {IProgressService} from 'vs/platform/progress/common/progress';
|
||||
import {IStorageService, NullStorageService} from 'vs/platform/storage/common/storage';
|
||||
import {ITelemetryService, NullTelemetryService} from 'vs/platform/telemetry/common/telemetry';
|
||||
import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/baseWorkspaceContextService';
|
||||
import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/workspaceContextService';
|
||||
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
|
||||
import {ICodeEditorService} from 'vs/editor/common/services/codeEditorService';
|
||||
import {IEditorWorkerService} from 'vs/editor/common/services/editorWorkerService';
|
||||
|
|
|
@ -39,7 +39,7 @@ export interface IConfigurationService {
|
|||
* Sets a user configuration. An the setting does not yet exist in the settings, it will be
|
||||
* added.
|
||||
*/
|
||||
setUserConfiguration(key: string | JSONPath, value: any) : Thenable<void>;
|
||||
setUserConfiguration(key: string | JSONPath, value: any): Thenable<void>;
|
||||
}
|
||||
|
||||
export interface IConfigurationServiceEvent {
|
||||
|
@ -55,12 +55,11 @@ export function getConfigurationValue<T>(config: any, settingPath: string, defau
|
|||
return undefined;
|
||||
}
|
||||
}
|
||||
return <T> current;
|
||||
return <T>current;
|
||||
}
|
||||
|
||||
let path = settingPath.split('.');
|
||||
let result = accessSetting(config, path);
|
||||
return typeof result === 'undefined'
|
||||
? defaultValue
|
||||
: result;
|
||||
const path = settingPath.split('.');
|
||||
const result = accessSetting(config, path);
|
||||
|
||||
return typeof result === 'undefined' ? defaultValue : result;
|
||||
}
|
|
@ -12,7 +12,6 @@ import objects = require('vs/base/common/objects');
|
|||
import {ExtensionsRegistry} from 'vs/platform/extensions/common/extensionsRegistry';
|
||||
import JSONContributionRegistry = require('vs/platform/jsonschemas/common/jsonContributionRegistry');
|
||||
|
||||
|
||||
export const Extensions = {
|
||||
Configuration: 'base.contributions.configuration'
|
||||
};
|
||||
|
@ -80,7 +79,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
}
|
||||
|
||||
private registerJSONConfiguration(configuration: IConfigurationNode) {
|
||||
let schema = <IJSONSchema>objects.clone(configuration);
|
||||
const schema = <IJSONSchema>objects.clone(configuration);
|
||||
this.configurationSchema.allOf.push(schema);
|
||||
contributionRegistry.registerSchema(schemaId, this.configurationSchema);
|
||||
}
|
||||
|
@ -89,7 +88,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
const configurationRegistry = new ConfigurationRegistry();
|
||||
platform.Registry.add(Extensions.Configuration, configurationRegistry);
|
||||
|
||||
let configurationExtPoint = ExtensionsRegistry.registerExtensionPoint<IConfigurationNode>('configuration', {
|
||||
const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint<IConfigurationNode>('configuration', {
|
||||
description: nls.localize('vscode.extension.contributes.configuration', 'Contributes configuration settings.'),
|
||||
type: 'object',
|
||||
defaultSnippets: [{ body: { title: '', properties: {} } }],
|
||||
|
@ -110,8 +109,8 @@ let configurationExtPoint = ExtensionsRegistry.registerExtensionPoint<IConfigura
|
|||
|
||||
configurationExtPoint.setHandler((extensions) => {
|
||||
for (let i = 0; i < extensions.length; i++) {
|
||||
let configuration = <IConfigurationNode>extensions[i].value;
|
||||
let collector = extensions[i].collector;
|
||||
const configuration = <IConfigurationNode>extensions[i].value;
|
||||
const collector = extensions[i].collector;
|
||||
|
||||
if (configuration.type && configuration.type !== 'object') {
|
||||
collector.warn(nls.localize('invalid.type', "if set, 'configuration.type' must be set to 'object"));
|
||||
|
@ -127,8 +126,8 @@ configurationExtPoint.setHandler((extensions) => {
|
|||
collector.error(nls.localize('invalid.properties', "'configuration.properties' must be an object"));
|
||||
return;
|
||||
}
|
||||
let clonedConfiguration = objects.clone(configuration);
|
||||
const clonedConfiguration = objects.clone(configuration);
|
||||
clonedConfiguration.id = extensions[i].description.id;
|
||||
configurationRegistry.registerConfiguration(clonedConfiguration);
|
||||
}
|
||||
});
|
||||
});
|
|
@ -79,8 +79,9 @@ export abstract class ConfigurationService implements IConfigurationService, IDi
|
|||
}
|
||||
|
||||
protected registerListeners(): void {
|
||||
let unbind = this.eventService.addListener2(EventType.FILE_CHANGES, (events) => this.handleFileEvents(events));
|
||||
let subscription = Registry.as<IConfigurationRegistry>(Extensions.Configuration).onDidRegisterConfiguration(() => this.onDidRegisterConfiguration());
|
||||
const unbind = this.eventService.addListener2(EventType.FILE_CHANGES, (events) => this.handleFileEvents(events));
|
||||
const subscription = Registry.as<IConfigurationRegistry>(Extensions.Configuration).onDidRegisterConfiguration(() => this.onDidRegisterConfiguration());
|
||||
|
||||
this.callOnDispose = {
|
||||
dispose: () => {
|
||||
unbind.dispose();
|
||||
|
@ -99,12 +100,12 @@ export abstract class ConfigurationService implements IConfigurationService, IDi
|
|||
|
||||
protected abstract resolveStat(resource: uri): TPromise<IStat>;
|
||||
|
||||
public abstract setUserConfiguration(key: string | JSONPath, value: any) : Thenable<void>;
|
||||
public abstract setUserConfiguration(key: string | JSONPath, value: any): Thenable<void>;
|
||||
|
||||
public getConfiguration<T>(section?: string): T {
|
||||
let result = section ? this.cachedConfig.config[section] : this.cachedConfig.config;
|
||||
|
||||
let parseErrors = this.cachedConfig.parseErrors;
|
||||
const parseErrors = this.cachedConfig.parseErrors;
|
||||
if (parseErrors && parseErrors.length > 0) {
|
||||
if (!result) {
|
||||
result = {};
|
||||
|
@ -134,10 +135,10 @@ export abstract class ConfigurationService implements IConfigurationService, IDi
|
|||
return this.loadWorkspaceConfiguration().then((values) => {
|
||||
|
||||
// Consolidate
|
||||
let consolidated = model.consolidate(values);
|
||||
const consolidated = model.consolidate(values);
|
||||
|
||||
// Override with workspace locals
|
||||
let merged = objects.mixin(
|
||||
const merged = objects.mixin(
|
||||
objects.clone(globals.contents), // target: global/default values (but dont modify!)
|
||||
consolidated.contents, // source: workspace configured values
|
||||
true // overwrite
|
||||
|
@ -147,6 +148,7 @@ export abstract class ConfigurationService implements IConfigurationService, IDi
|
|||
if (consolidated.parseErrors) {
|
||||
parseErrors = consolidated.parseErrors;
|
||||
}
|
||||
|
||||
if (globals.parseErrors) {
|
||||
parseErrors.push.apply(parseErrors, globals.parseErrors);
|
||||
}
|
||||
|
@ -225,10 +227,11 @@ export abstract class ConfigurationService implements IConfigurationService, IDi
|
|||
}
|
||||
|
||||
private handleFileEvents(event: FileChangesEvent): void {
|
||||
let events = event.changes;
|
||||
const events = event.changes;
|
||||
let affectedByChanges = false;
|
||||
|
||||
for (let i = 0, len = events.length; i < len; i++) {
|
||||
let workspacePath = this.contextService.toWorkspaceRelativePath(events[i].resource);
|
||||
const workspacePath = this.contextService.toWorkspaceRelativePath(events[i].resource);
|
||||
if (!workspacePath) {
|
||||
continue; // event is not inside workspace
|
||||
}
|
||||
|
@ -269,4 +272,4 @@ export abstract class ConfigurationService implements IConfigurationService, IDi
|
|||
this.callOnDispose.dispose();
|
||||
this._onDidUpdateConfiguration.dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,11 +19,11 @@ export interface IConfigFile {
|
|||
}
|
||||
|
||||
function setNode(root: any, key: string, value: any): void {
|
||||
let segments = key.split('.');
|
||||
let last = segments.pop();
|
||||
const segments = key.split('.');
|
||||
const last = segments.pop();
|
||||
|
||||
let curr = root;
|
||||
segments.forEach((s) => {
|
||||
segments.forEach(s => {
|
||||
let obj = curr[s];
|
||||
switch (typeof obj) {
|
||||
case 'undefined':
|
||||
|
@ -42,11 +42,12 @@ function setNode(root: any, key: string, value: any): void {
|
|||
|
||||
export function newConfigFile(value: string): IConfigFile {
|
||||
try {
|
||||
let root: any = Object.create(null);
|
||||
let contents = json.parse(value) || {};
|
||||
const root: any = Object.create(null);
|
||||
const contents = json.parse(value) || {};
|
||||
for (let key in contents) {
|
||||
setNode(root, key, contents[key]);
|
||||
}
|
||||
|
||||
return {
|
||||
contents: root
|
||||
};
|
||||
|
@ -73,27 +74,27 @@ export function merge(base: any, add: any, overwrite: boolean): void {
|
|||
}
|
||||
|
||||
export function consolidate(configMap: { [key: string]: IConfigFile; }): { contents: any; parseErrors: string[]; } {
|
||||
let finalConfig: any = Object.create(null);
|
||||
let parseErrors: string[] = [];
|
||||
let regexp = /\/(team\.)?([^\.]*)*\.json/;
|
||||
const finalConfig: any = Object.create(null);
|
||||
const parseErrors: string[] = [];
|
||||
const regexp = /\/(team\.)?([^\.]*)*\.json/;
|
||||
|
||||
// For each config file in .vscode folder
|
||||
Object.keys(configMap).forEach((configFileName) => {
|
||||
let config = objects.clone(configMap[configFileName]);
|
||||
let matches = regexp.exec(configFileName);
|
||||
const config = objects.clone(configMap[configFileName]);
|
||||
const matches = regexp.exec(configFileName);
|
||||
if (!matches || !config) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If a file is team.foo.json, it indicates team settings, strip this away
|
||||
let isTeamSetting = !!matches[1];
|
||||
const isTeamSetting = !!matches[1];
|
||||
|
||||
// Extract the config key from the file name (except for settings.json which is the default)
|
||||
let configElement: any = finalConfig;
|
||||
if (matches && matches[2] && matches[2] !== CONFIG_DEFAULT_NAME) {
|
||||
|
||||
// Use the name of the file as top level config section for all settings inside
|
||||
let configSection = matches[2];
|
||||
const configSection = matches[2];
|
||||
let element = configElement[configSection];
|
||||
if (!element) {
|
||||
element = Object.create(null);
|
||||
|
@ -118,11 +119,10 @@ export function consolidate(configMap: { [key: string]: IConfigFile; }): { conte
|
|||
// defaults...
|
||||
|
||||
function processDefaultValues(withConfig: (config: configurationRegistry.IConfigurationNode, isTop?: boolean) => boolean): void {
|
||||
const configurations = (<configurationRegistry.IConfigurationRegistry>platform.Registry.as(configurationRegistry.Extensions.Configuration)).getConfigurations();
|
||||
|
||||
let configurations = (<configurationRegistry.IConfigurationRegistry>platform.Registry.as(configurationRegistry.Extensions.Configuration)).getConfigurations();
|
||||
|
||||
let visit = (config: configurationRegistry.IConfigurationNode, level: number) => {
|
||||
let handled = withConfig(config, level === 0);
|
||||
const visit = (config: configurationRegistry.IConfigurationNode, level: number) => {
|
||||
const handled = withConfig(config, level === 0);
|
||||
|
||||
if (Array.isArray(config.allOf)) {
|
||||
config.allOf.forEach((c) => {
|
||||
|
@ -141,8 +141,8 @@ function processDefaultValues(withConfig: (config: configurationRegistry.IConfig
|
|||
return -1;
|
||||
}
|
||||
if (c1.order === c2.order) {
|
||||
let title1 = c1.title || '';
|
||||
let title2 = c2.title || '';
|
||||
const title1 = c1.title || '';
|
||||
const title2 = c2.title || '';
|
||||
return title1.localeCompare(title2);
|
||||
}
|
||||
return c1.order - c2.order;
|
||||
|
@ -153,34 +153,37 @@ function processDefaultValues(withConfig: (config: configurationRegistry.IConfig
|
|||
|
||||
|
||||
export function getDefaultValues(): any {
|
||||
let ret: any = Object.create(null);
|
||||
const ret: any = Object.create(null);
|
||||
|
||||
let handleConfig = (config: configurationRegistry.IConfigurationNode, isTop: boolean) : boolean => {
|
||||
const handleConfig = (config: configurationRegistry.IConfigurationNode, isTop: boolean): boolean => {
|
||||
if (config.properties) {
|
||||
Object.keys(config.properties).forEach((key) => {
|
||||
let prop = config.properties[key];
|
||||
const prop = config.properties[key];
|
||||
let value = prop.default;
|
||||
if (types.isUndefined(prop.default)) {
|
||||
value = getDefaultValue(prop.type);
|
||||
}
|
||||
setNode(ret, key, value);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
processDefaultValues(handleConfig);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
export function getDefaultValuesContent(indent: string): string {
|
||||
let lastEntry = -1;
|
||||
let result: string[] = [];
|
||||
const result: string[] = [];
|
||||
result.push('{');
|
||||
|
||||
let handleConfig = (config: configurationRegistry.IConfigurationNode, isTop: boolean) : boolean => {
|
||||
|
||||
const handleConfig = (config: configurationRegistry.IConfigurationNode, isTop: boolean): boolean => {
|
||||
let handled = false;
|
||||
if (config.title) {
|
||||
handled = true;
|
||||
|
@ -192,11 +195,12 @@ export function getDefaultValuesContent(indent: string): string {
|
|||
}
|
||||
result.push('');
|
||||
}
|
||||
|
||||
if (config.properties) {
|
||||
handled = true;
|
||||
Object.keys(config.properties).forEach((key) => {
|
||||
|
||||
let prop = config.properties[key];
|
||||
const prop = config.properties[key];
|
||||
let defaultValue = prop.default;
|
||||
if (types.isUndefined(defaultValue)) {
|
||||
defaultValue = getDefaultValue(prop.type);
|
||||
|
@ -219,11 +223,14 @@ export function getDefaultValuesContent(indent: string): string {
|
|||
result.push('');
|
||||
});
|
||||
}
|
||||
|
||||
return handled;
|
||||
};
|
||||
|
||||
processDefaultValues(handleConfig);
|
||||
|
||||
result.push('}');
|
||||
|
||||
return result.join('\n');
|
||||
}
|
||||
|
||||
|
@ -232,7 +239,7 @@ function addIndent(str: string, indent: string): string {
|
|||
}
|
||||
|
||||
function getDefaultValue(type: string | string[]): any {
|
||||
let t = Array.isArray(type) ? (<string[]> type)[0] : <string> type;
|
||||
const t = Array.isArray(type) ? (<string[]>type)[0] : <string>type;
|
||||
switch (t) {
|
||||
case 'boolean':
|
||||
return false;
|
||||
|
|
|
@ -6,14 +6,16 @@
|
|||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import paths = require('vs/base/common/paths');
|
||||
import {IWorkspaceContextService, IWorkspace, IConfiguration} from './workspace';
|
||||
import {IWorkspaceContextService, IWorkspace, IConfiguration} from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
/**
|
||||
* Simple IWorkspaceContextService implementation to allow sharing of this service implementation
|
||||
* between different layers of the platform.
|
||||
*/
|
||||
export class BaseWorkspaceContextService implements IWorkspaceContextService {
|
||||
|
||||
public _serviceBrand: any;
|
||||
|
||||
protected options: any;
|
||||
|
||||
private workspace: IWorkspace;
|
|
@ -22,7 +22,8 @@ import {ConfigurationService} from 'vs/workbench/services/configuration/node/con
|
|||
import path = require('path');
|
||||
import fs = require('fs');
|
||||
import gracefulFs = require('graceful-fs');
|
||||
gracefulFs.gracefulify(fs);
|
||||
|
||||
gracefulFs.gracefulify(fs); // enable gracefulFs
|
||||
|
||||
const timers = (<any>window).MonacoEnvironment.timers;
|
||||
|
||||
|
@ -117,15 +118,13 @@ function getWorkspace(environment: IMainEnvironment): IWorkspace {
|
|||
const folderName = path.basename(realWorkspacePath) || realWorkspacePath;
|
||||
const folderStat = fs.statSync(realWorkspacePath);
|
||||
|
||||
const workspace: IWorkspace = {
|
||||
return <IWorkspace>{
|
||||
'resource': workspaceResource,
|
||||
'id': platform.isLinux ? realWorkspacePath : realWorkspacePath.toLowerCase(),
|
||||
'name': folderName,
|
||||
'uid': platform.isLinux ? folderStat.ino : folderStat.birthtime.getTime(), // On Linux, birthtime is ctime, so we cannot use it! We use the ino instead!
|
||||
'mtime': folderStat.mtime.getTime()
|
||||
};
|
||||
|
||||
return workspace;
|
||||
}
|
||||
|
||||
function openWorkbench(workspace: IWorkspace, configuration: IConfiguration, options: IOptions): winjs.TPromise<void> {
|
||||
|
|
|
@ -20,7 +20,7 @@ import {IMainProcessExtHostIPC} from 'vs/platform/extensions/common/ipcRemoteCom
|
|||
import {ExtHostExtensionService} from 'vs/workbench/api/node/extHostExtensionService';
|
||||
import {ExtHostThreadService} from 'vs/workbench/services/thread/common/extHostThreadService';
|
||||
import {RemoteTelemetryService} from 'vs/workbench/api/node/extHostTelemetry';
|
||||
import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/baseWorkspaceContextService';
|
||||
import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/workspaceContextService';
|
||||
import {ExtensionScanner, MessagesCollector} from 'vs/workbench/node/extensionPoints';
|
||||
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
|
||||
import {Client} from 'vs/base/parts/ipc/node/ipc.net';
|
||||
|
|
|
@ -9,7 +9,7 @@ import {EventType, OptionsChangeEvent} from 'vs/workbench/common/events';
|
|||
import {IEventService} from 'vs/platform/event/common/event';
|
||||
import {createDecorator} from 'vs/platform/instantiation/common/instantiation';
|
||||
import {IWorkspace, IConfiguration, IWorkspaceContextService as IBaseWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
|
||||
import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/baseWorkspaceContextService';
|
||||
import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/workspaceContextService';
|
||||
|
||||
export const IWorkspaceContextService = createDecorator<IWorkspaceContextService>('contextService');
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import {Build, Builder} from 'vs/base/browser/builder';
|
|||
import {Part} from 'vs/workbench/browser/part';
|
||||
import * as Types from 'vs/base/common/types';
|
||||
import * as TestUtils from 'vs/test/utils/servicesTestUtils';
|
||||
import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/baseWorkspaceContextService';
|
||||
import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/workspaceContextService';
|
||||
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
|
||||
import {IStorageService} from 'vs/platform/storage/common/storage';
|
||||
import {Storage, InMemoryLocalStorage} from 'vs/workbench/common/storage';
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import 'vs/workbench/parts/search/browser/search.contribution'; // load contributions
|
||||
import * as assert from 'assert';
|
||||
import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/baseWorkspaceContextService';
|
||||
import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/workspaceContextService';
|
||||
import {createSyncDescriptor} from 'vs/platform/instantiation/common/descriptors';
|
||||
import {ensureStaticPlatformServices, IEditorOverrideServices} from 'vs/editor/browser/standalone/standaloneServices';
|
||||
import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService';
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/baseWorkspaceContextService';
|
||||
import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/workspaceContextService';
|
||||
import {StorageScope} from 'vs/platform/storage/common/storage';
|
||||
import * as TestUtils from 'vs/test/utils/servicesTestUtils';
|
||||
import {Memento, Scope} from 'vs/workbench/common/memento';
|
||||
|
|
Loading…
Reference in a new issue