mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-20 17:22:51 -05:00
Initial VS Code 1.19 source merge (#571)
* Initial 1.19 xcopy * Fix yarn build * Fix numerous build breaks * Next batch of build break fixes * More build break fixes * Runtime breaks * Additional post merge fixes * Fix windows setup file * Fix test failures. * Update license header blocks to refer to source eula
This commit is contained in:
@@ -36,7 +36,6 @@ import { ExtHostApiCommands } from 'vs/workbench/api/node/extHostApiCommands';
|
||||
import { ExtHostTask } from 'vs/workbench/api/node/extHostTask';
|
||||
// {{SQL CARBON EDIT}}
|
||||
//import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService';
|
||||
import { ExtHostCredentials } from 'vs/workbench/api/node/extHostCredentials';
|
||||
import { ExtHostWindow } from 'vs/workbench/api/node/extHostWindow';
|
||||
import * as extHostTypes from 'vs/workbench/api/node/extHostTypes';
|
||||
import URI from 'vs/base/common/uri';
|
||||
@@ -57,6 +56,10 @@ import { ExtHostDialogs } from 'vs/workbench/api/node/extHostDialogs';
|
||||
import { ExtHostFileSystem } from 'vs/workbench/api/node/extHostFileSystem';
|
||||
import { FileChangeType, FileType } from 'vs/platform/files/common/files';
|
||||
import { ExtHostDecorations } from 'vs/workbench/api/node/extHostDecorations';
|
||||
import { toGlobPattern, toLanguageSelector } from 'vs/workbench/api/node/extHostTypeConverters';
|
||||
import { ExtensionActivatedByAPI } from 'vs/workbench/api/node/extHostExtensionActivator';
|
||||
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
export interface IExtensionApiFactory {
|
||||
(extension: IExtensionDescription): typeof vscode;
|
||||
@@ -80,7 +83,8 @@ export function createApiFactory(
|
||||
threadService: ExtHostThreadService,
|
||||
extHostWorkspace: ExtHostWorkspace,
|
||||
extHostConfiguration: ExtHostConfiguration,
|
||||
extensionService: ExtHostExtensionService
|
||||
extensionService: ExtHostExtensionService,
|
||||
logService: ILogService
|
||||
): IExtensionApiFactory {
|
||||
|
||||
// Addressable instances
|
||||
@@ -91,11 +95,11 @@ export function createApiFactory(
|
||||
const extHostDocumentContentProviders = threadService.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(threadService, extHostDocumentsAndEditors));
|
||||
const extHostDocumentSaveParticipant = threadService.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostDocuments, threadService.get(MainContext.MainThreadEditors)));
|
||||
const extHostEditors = threadService.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(threadService, extHostDocumentsAndEditors));
|
||||
const extHostCommands = threadService.set(ExtHostContext.ExtHostCommands, new ExtHostCommands(threadService, extHostHeapService));
|
||||
const extHostCommands = threadService.set(ExtHostContext.ExtHostCommands, new ExtHostCommands(threadService, extHostHeapService, logService));
|
||||
const extHostTreeViews = threadService.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(threadService.get(MainContext.MainThreadTreeViews), extHostCommands));
|
||||
threadService.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace);
|
||||
// {{SQL CARBON EDIT}}
|
||||
// const extHostDebugService = threadService.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(threadService, extHostWorkspace));
|
||||
//const extHostDebugService = threadService.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(threadService, extHostWorkspace));
|
||||
threadService.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration);
|
||||
const extHostDiagnostics = threadService.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(threadService));
|
||||
const languageFeatures = threadService.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(threadService, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics));
|
||||
@@ -103,9 +107,8 @@ export function createApiFactory(
|
||||
const extHostFileSystemEvent = threadService.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService());
|
||||
const extHostQuickOpen = threadService.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(threadService, extHostWorkspace, extHostCommands));
|
||||
const extHostTerminalService = threadService.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(threadService));
|
||||
const extHostSCM = threadService.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(threadService, extHostCommands));
|
||||
const extHostSCM = threadService.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(threadService, extHostCommands, logService));
|
||||
const extHostTask = threadService.set(ExtHostContext.ExtHostTask, new ExtHostTask(threadService, extHostWorkspace));
|
||||
const extHostCredentials = threadService.set(ExtHostContext.ExtHostCredentials, new ExtHostCredentials(threadService));
|
||||
const extHostWindow = threadService.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(threadService));
|
||||
threadService.set(ExtHostContext.ExtHostExtensionService, extensionService);
|
||||
|
||||
@@ -126,8 +129,14 @@ export function createApiFactory(
|
||||
|
||||
return function (extension: IExtensionDescription): typeof vscode {
|
||||
|
||||
if (extension.enableProposedApi && !extension.isBuiltin) {
|
||||
if (!isFalsyOrEmpty(product.extensionAllowedProposedApi)
|
||||
&& product.extensionAllowedProposedApi.indexOf(extension.id) >= 0
|
||||
) {
|
||||
// fast lane -> proposed api is available to all extensions
|
||||
// that are listed in product.json-files
|
||||
extension.enableProposedApi = true;
|
||||
|
||||
} else if (extension.enableProposedApi && !extension.isBuiltin) {
|
||||
if (
|
||||
!initData.environment.enableProposedApiForAll &&
|
||||
initData.environment.enableProposedApiFor.indexOf(extension.id) < 0
|
||||
@@ -144,7 +153,7 @@ export function createApiFactory(
|
||||
|
||||
// namespace: commands
|
||||
const commands: typeof vscode.commands = {
|
||||
registerCommand<T>(id: string, command: <T>(...args: any[]) => T | Thenable<T>, thisArgs?: any): vscode.Disposable {
|
||||
registerCommand(id: string, command: <T>(...args: any[]) => T | Thenable<T>, thisArgs?: any): vscode.Disposable {
|
||||
return extHostCommands.registerCommand(id, command, thisArgs);
|
||||
},
|
||||
registerTextEditorCommand(id: string, callback: (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, ...args: any[]) => void, thisArg?: any): vscode.Disposable {
|
||||
@@ -220,7 +229,7 @@ export function createApiFactory(
|
||||
return extHostLanguages.getLanguages();
|
||||
},
|
||||
match(selector: vscode.DocumentSelector, document: vscode.TextDocument): number {
|
||||
return score(selector, <any>document.uri, document.languageId);
|
||||
return score(toLanguageSelector(selector), document.uri, document.languageId);
|
||||
},
|
||||
registerCodeActionsProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider): vscode.Disposable {
|
||||
return languageFeatures.registerCodeActionProvider(selector, provider);
|
||||
@@ -412,7 +421,7 @@ export function createApiFactory(
|
||||
return extHostWorkspace.getRelativePath(pathOrUri, includeWorkspace);
|
||||
},
|
||||
findFiles: (include, exclude, maxResults?, token?) => {
|
||||
return extHostWorkspace.findFiles(include, exclude, maxResults, token);
|
||||
return extHostWorkspace.findFiles(toGlobPattern(include), toGlobPattern(exclude), maxResults, token);
|
||||
},
|
||||
saveAll: (includeUntitled?) => {
|
||||
return extHostWorkspace.saveAll(includeUntitled);
|
||||
@@ -421,7 +430,7 @@ export function createApiFactory(
|
||||
return extHostEditors.applyWorkspaceEdit(edit);
|
||||
},
|
||||
createFileSystemWatcher: (pattern, ignoreCreate, ignoreChange, ignoreDelete): vscode.FileSystemWatcher => {
|
||||
return extHostFileSystemEvent.createFileSystemWatcher(pattern, ignoreCreate, ignoreChange, ignoreDelete);
|
||||
return extHostFileSystemEvent.createFileSystemWatcher(toGlobPattern(pattern), ignoreCreate, ignoreChange, ignoreDelete);
|
||||
},
|
||||
get textDocuments() {
|
||||
return extHostDocuments.getAllDocumentData().map(data => data.document);
|
||||
@@ -496,22 +505,7 @@ export function createApiFactory(
|
||||
// {{SQL CARBON EDIT}}
|
||||
// delete namespace: debug
|
||||
|
||||
|
||||
// namespace: credentials
|
||||
const credentials = {
|
||||
readSecret(service: string, account: string): Thenable<string | undefined> {
|
||||
return extHostCredentials.readSecret(service, account);
|
||||
},
|
||||
writeSecret(service: string, account: string, secret: string): Thenable<void> {
|
||||
return extHostCredentials.writeSecret(service, account, secret);
|
||||
},
|
||||
deleteSecret(service: string, account: string): Thenable<boolean> {
|
||||
return extHostCredentials.deleteSecret(service, account);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const api: typeof vscode = {
|
||||
return <typeof vscode>{
|
||||
version: pkg.version,
|
||||
// namespaces
|
||||
commands,
|
||||
@@ -524,7 +518,9 @@ export function createApiFactory(
|
||||
// {{SQL CARBON EDIT}}
|
||||
// debug,
|
||||
// types
|
||||
Breakpoint: extHostTypes.Breakpoint,
|
||||
CancellationTokenSource: CancellationTokenSource,
|
||||
CodeAction: extHostTypes.CodeAction,
|
||||
CodeLens: extHostTypes.CodeLens,
|
||||
Color: extHostTypes.Color,
|
||||
ColorPresentation: extHostTypes.ColorPresentation,
|
||||
@@ -541,6 +537,7 @@ export function createApiFactory(
|
||||
DocumentHighlightKind: extHostTypes.DocumentHighlightKind,
|
||||
DocumentLink: extHostTypes.DocumentLink,
|
||||
EventEmitter: Emitter,
|
||||
FunctionBreakpoint: extHostTypes.FunctionBreakpoint,
|
||||
Hover: extHostTypes.Hover,
|
||||
IndentAction: languageConfiguration.IndentAction,
|
||||
Location: extHostTypes.Location,
|
||||
@@ -553,6 +550,7 @@ export function createApiFactory(
|
||||
SignatureHelp: extHostTypes.SignatureHelp,
|
||||
SignatureInformation: extHostTypes.SignatureInformation,
|
||||
SnippetString: extHostTypes.SnippetString,
|
||||
SourceBreakpoint: extHostTypes.SourceBreakpoint,
|
||||
StatusBarAlignment: extHostTypes.StatusBarAlignment,
|
||||
SymbolInformation: extHostTypes.SymbolInformation,
|
||||
SymbolKind: extHostTypes.SymbolKind,
|
||||
@@ -585,10 +583,6 @@ export function createApiFactory(
|
||||
FileChangeType: <any>FileChangeType,
|
||||
FileType: <any>FileType
|
||||
};
|
||||
if (extension.enableProposedApi && extension.isBuiltin) {
|
||||
api['credentials'] = credentials;
|
||||
}
|
||||
return api;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -616,7 +610,7 @@ class Extension<T> implements vscode.Extension<T> {
|
||||
}
|
||||
|
||||
activate(): Thenable<T> {
|
||||
return this._extensionService.activateById(this.id, false).then(() => this.exports);
|
||||
return this._extensionService.activateById(this.id, new ExtensionActivatedByAPI(false)).then(() => this.exports);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,10 +46,10 @@ import { ITreeItem } from 'vs/workbench/common/views';
|
||||
import { ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { SerializedError } from 'vs/base/common/errors';
|
||||
import { IRelativePattern } from 'vs/base/common/glob';
|
||||
import { IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace';
|
||||
import { IStat, IFileChange } from 'vs/platform/files/common/files';
|
||||
import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
|
||||
export interface IEnvironment {
|
||||
isExtensionDevelopmentDebug: boolean;
|
||||
@@ -76,6 +76,9 @@ export interface IInitData {
|
||||
extensions: IExtensionDescription[];
|
||||
configuration: IConfigurationInitData;
|
||||
telemetryInfo: ITelemetryInfo;
|
||||
windowId: number;
|
||||
args: ParsedArgs;
|
||||
execPath: string;
|
||||
}
|
||||
|
||||
export interface IConfigurationInitData extends IConfigurationData {
|
||||
@@ -236,11 +239,11 @@ export interface MainThreadEditorsShape extends IDisposable {
|
||||
|
||||
export interface MainThreadTreeViewsShape extends IDisposable {
|
||||
$registerView(treeViewId: string): void;
|
||||
$refresh(treeViewId: string, treeItemHandles: number[]): void;
|
||||
$refresh(treeViewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem }): void;
|
||||
}
|
||||
|
||||
export interface MainThreadErrorsShape extends IDisposable {
|
||||
$onUnexpectedError(err: any | SerializedError, extensionId: string | undefined): void;
|
||||
$onUnexpectedError(err: any | SerializedError): void;
|
||||
}
|
||||
|
||||
export interface MainThreadLanguageFeaturesShape extends IDisposable {
|
||||
@@ -328,7 +331,7 @@ export interface MainThreadTelemetryShape extends IDisposable {
|
||||
}
|
||||
|
||||
export interface MainThreadWorkspaceShape extends IDisposable {
|
||||
$startSearch(include: string | IRelativePattern, exclude: string | IRelativePattern, maxResults: number, requestId: number): Thenable<URI[]>;
|
||||
$startSearch(includePattern: string, includeFolder: string, excludePattern: string, maxResults: number, requestId: number): Thenable<URI[]>;
|
||||
$cancelSearch(requestId: number): Thenable<boolean>;
|
||||
$saveAll(includeUntitled?: boolean): Thenable<boolean>;
|
||||
}
|
||||
@@ -351,8 +354,10 @@ export interface MainThreadTaskShape extends IDisposable {
|
||||
|
||||
export interface MainThreadExtensionServiceShape extends IDisposable {
|
||||
$localShowMessage(severity: Severity, msg: string): void;
|
||||
$onExtensionActivated(extensionId: string, startup: boolean, codeLoadingTime: number, activateCallTime: number, activateResolvedTime: number): void;
|
||||
$onExtensionActivated(extensionId: string, startup: boolean, codeLoadingTime: number, activateCallTime: number, activateResolvedTime: number, activationEvent: string): void;
|
||||
$onExtensionActivationFailed(extensionId: string): void;
|
||||
$onExtensionRuntimeError(extensionId: string, error: SerializedError): void;
|
||||
$addMessage(extensionId: string, severity: Severity, message: string): void;
|
||||
}
|
||||
|
||||
export interface SCMProviderFeatures {
|
||||
@@ -404,6 +409,7 @@ export interface MainThreadSCMShape extends IDisposable {
|
||||
$spliceResourceStates(sourceControlHandle: number, splices: SCMRawResourceSplices[]): void;
|
||||
|
||||
$setInputBoxValue(sourceControlHandle: number, value: string): void;
|
||||
$setInputBoxPlaceholder(sourceControlHandle: number, placeholder: string): void;
|
||||
}
|
||||
|
||||
|
||||
@@ -417,13 +423,10 @@ export interface MainThreadDebugServiceShape extends IDisposable {
|
||||
$startDebugging(folder: URI | undefined, nameOrConfig: string | vscode.DebugConfiguration): TPromise<boolean>;
|
||||
$customDebugAdapterRequest(id: DebugSessionUUID, command: string, args: any): TPromise<any>;
|
||||
$appendDebugConsole(value: string): TPromise<any>;
|
||||
$startBreakpointEvents(): TPromise<any>;
|
||||
}
|
||||
// {{SQL CARBON EDIT}}
|
||||
*/
|
||||
export interface MainThreadCredentialsShape extends IDisposable {
|
||||
$readSecret(service: string, account: string): Thenable<string | undefined>;
|
||||
$writeSecret(service: string, account: string, secret: string): Thenable<void>;
|
||||
$deleteSecret(service: string, account: string): Thenable<boolean>;
|
||||
}
|
||||
|
||||
export interface MainThreadWindowShape extends IDisposable {
|
||||
$getWindowVisibility(): TPromise<boolean>;
|
||||
@@ -497,7 +500,7 @@ export interface ExtHostDocumentsAndEditorsShape {
|
||||
|
||||
export interface ExtHostTreeViewsShape {
|
||||
$getElements(treeViewId: string): TPromise<ITreeItem[]>;
|
||||
$getChildren(treeViewId: string, treeItemHandle: number): TPromise<ITreeItem[]>;
|
||||
$getChildren(treeViewId: string, treeItemHandle: string): TPromise<ITreeItem[]>;
|
||||
}
|
||||
|
||||
export interface ExtHostWorkspaceShape {
|
||||
@@ -577,7 +580,7 @@ export namespace IdObject {
|
||||
}
|
||||
|
||||
export type IWorkspaceSymbol = IdObject & modes.SymbolInformation;
|
||||
export interface IWorkspaceSymbols extends IdObject { symbols: IWorkspaceSymbol[]; };
|
||||
export interface IWorkspaceSymbols extends IdObject { symbols: IWorkspaceSymbol[]; }
|
||||
|
||||
export interface ExtHostLanguageFeaturesShape {
|
||||
$provideDocumentSymbols(handle: number, resource: URI): TPromise<modes.SymbolInformation[]>;
|
||||
@@ -589,7 +592,7 @@ export interface ExtHostLanguageFeaturesShape {
|
||||
$provideHover(handle: number, resource: URI, position: IPosition): TPromise<modes.Hover>;
|
||||
$provideDocumentHighlights(handle: number, resource: URI, position: IPosition): TPromise<modes.DocumentHighlight[]>;
|
||||
$provideReferences(handle: number, resource: URI, position: IPosition, context: modes.ReferenceContext): TPromise<modes.Location[]>;
|
||||
$provideCodeActions(handle: number, resource: URI, range: IRange): TPromise<modes.Command[]>;
|
||||
$provideCodeActions(handle: number, resource: URI, range: IRange): TPromise<modes.CodeAction[]>;
|
||||
$provideDocumentFormattingEdits(handle: number, resource: URI, options: modes.FormattingOptions): TPromise<editorCommon.ISingleEditOperation[]>;
|
||||
$provideDocumentRangeFormattingEdits(handle: number, resource: URI, range: IRange, options: modes.FormattingOptions): TPromise<editorCommon.ISingleEditOperation[]>;
|
||||
$provideOnTypeFormattingEdits(handle: number, resource: URI, position: IPosition, ch: string, options: modes.FormattingOptions): TPromise<editorCommon.ISingleEditOperation[]>;
|
||||
@@ -627,6 +630,32 @@ export interface ExtHostTaskShape {
|
||||
$provideTasks(handle: number): TPromise<TaskSet>;
|
||||
}
|
||||
|
||||
export interface IBreakpointData {
|
||||
type: 'source' | 'function';
|
||||
id: string;
|
||||
enabled: boolean;
|
||||
condition?: string;
|
||||
hitCondition?: string;
|
||||
}
|
||||
|
||||
export interface ISourceBreakpointData extends IBreakpointData {
|
||||
type: 'source';
|
||||
uri: URI;
|
||||
line: number;
|
||||
character: number;
|
||||
}
|
||||
|
||||
export interface IFunctionBreakpointData extends IBreakpointData {
|
||||
type: 'function';
|
||||
functionName: string;
|
||||
}
|
||||
|
||||
export interface IBreakpointsDelta {
|
||||
added?: (ISourceBreakpointData | IFunctionBreakpointData)[];
|
||||
removed?: string[];
|
||||
changed?: (ISourceBreakpointData | IFunctionBreakpointData)[];
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
/*
|
||||
export interface ExtHostDebugServiceShape {
|
||||
@@ -636,7 +665,9 @@ export interface ExtHostDebugServiceShape {
|
||||
$acceptDebugSessionTerminated(id: DebugSessionUUID, type: string, name: string): void;
|
||||
$acceptDebugSessionActiveChanged(id: DebugSessionUUID | undefined, type?: string, name?: string): void;
|
||||
$acceptDebugSessionCustomEvent(id: DebugSessionUUID, type: string, name: string, event: any): void;
|
||||
$acceptBreakpointsDelta(delat: IBreakpointsDelta): void;
|
||||
}
|
||||
// {{SQL CARBON EDIT}}
|
||||
*/
|
||||
|
||||
export type DecorationData = [number, boolean, string, string, ThemeColor, string];
|
||||
@@ -645,9 +676,6 @@ export interface ExtHostDecorationsShape {
|
||||
$providerDecorations(handle: number, uri: URI): TPromise<DecorationData>;
|
||||
}
|
||||
|
||||
export interface ExtHostCredentialsShape {
|
||||
}
|
||||
|
||||
export interface ExtHostWindowShape {
|
||||
$onDidChangeWindowFocus(value: boolean): void;
|
||||
}
|
||||
@@ -682,7 +710,6 @@ export const MainContext = {
|
||||
MainThreadExtensionService: createMainId<MainThreadExtensionServiceShape>('MainThreadExtensionService'),
|
||||
MainThreadSCM: createMainId<MainThreadSCMShape>('MainThreadSCM'),
|
||||
MainThreadTask: createMainId<MainThreadTaskShape>('MainThreadTask'),
|
||||
MainThreadCredentials: createMainId<MainThreadCredentialsShape>('MainThreadCredentials'),
|
||||
MainThreadWindow: createMainId<MainThreadWindowShape>('MainThreadWindow'),
|
||||
};
|
||||
|
||||
@@ -709,6 +736,5 @@ export const ExtHostContext = {
|
||||
ExtHostSCM: createExtId<ExtHostSCMShape>('ExtHostSCM'),
|
||||
ExtHostTask: createExtId<ExtHostTaskShape>('ExtHostTask'),
|
||||
ExtHostWorkspace: createExtId<ExtHostWorkspaceShape>('ExtHostWorkspace'),
|
||||
ExtHostCredentials: createExtId<ExtHostCredentialsShape>('ExtHostCredentials'),
|
||||
ExtHostWindow: createExtId<ExtHostWindowShape>('ExtHostWindow'),
|
||||
};
|
||||
|
||||
@@ -15,7 +15,8 @@ import * as modes from 'vs/editor/common/modes';
|
||||
import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
|
||||
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { IWorkspaceSymbolProvider } from 'vs/workbench/parts/search/common/search';
|
||||
import { ITextEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { Position as EditorPosition, ITextEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { CustomCodeAction } from 'vs/workbench/api/node/extHostLanguageFeatures';
|
||||
|
||||
export class ExtHostApiCommands {
|
||||
|
||||
@@ -196,20 +197,11 @@ export class ExtHostApiCommands {
|
||||
});
|
||||
|
||||
this._register('vscode.diff', (left: URI, right: URI, label: string, options?: vscode.TextDocumentShowOptions) => {
|
||||
let editorOptions: ITextEditorOptions;
|
||||
if (options) {
|
||||
editorOptions = {
|
||||
pinned: typeof options.preview === 'boolean' ? !options.preview : undefined,
|
||||
preserveFocus: options.preserveFocus,
|
||||
selection: typeof options.selection === 'object' ? typeConverters.fromRange(options.selection) : undefined
|
||||
};
|
||||
}
|
||||
|
||||
return this._commands.executeCommand('_workbench.diff', [
|
||||
left, right,
|
||||
label,
|
||||
undefined,
|
||||
editorOptions,
|
||||
typeConverters.toTextEditorOptions(options),
|
||||
options ? typeConverters.fromViewColumn(options.viewColumn) : undefined
|
||||
]);
|
||||
}, {
|
||||
@@ -222,13 +214,29 @@ export class ExtHostApiCommands {
|
||||
]
|
||||
});
|
||||
|
||||
this._register('vscode.open', (resource: URI, column: vscode.ViewColumn) => {
|
||||
return this._commands.executeCommand('_workbench.open', [resource, typeConverters.fromViewColumn(column)]);
|
||||
this._register('vscode.open', (resource: URI, columnOrOptions?: vscode.ViewColumn | vscode.TextDocumentShowOptions) => {
|
||||
let options: ITextEditorOptions;
|
||||
let column: EditorPosition;
|
||||
|
||||
if (columnOrOptions) {
|
||||
if (typeof columnOrOptions === 'number') {
|
||||
column = typeConverters.fromViewColumn(columnOrOptions);
|
||||
} else {
|
||||
options = typeConverters.toTextEditorOptions(columnOrOptions);
|
||||
column = typeConverters.fromViewColumn(columnOrOptions.viewColumn);
|
||||
}
|
||||
}
|
||||
|
||||
return this._commands.executeCommand('_workbench.open', [
|
||||
resource,
|
||||
options,
|
||||
column
|
||||
]);
|
||||
}, {
|
||||
description: 'Opens the provided resource in the editor. Can be a text or binary file, or a http(s) url. If you need more control over the options for opening a text file, use vscode.window.showTextDocument instead.',
|
||||
args: [
|
||||
{ name: 'resource', description: 'Resource to open', constraint: URI },
|
||||
{ name: 'column', description: '(optional) Column in which to open', constraint: v => v === void 0 || typeof v === 'number' }
|
||||
{ name: 'columnOrOptions', description: '(optional) Either the column in which to open or editor options, see vscode.TextDocumentShowOptions', constraint: v => v === void 0 || typeof v === 'number' || typeof v === 'object' }
|
||||
]
|
||||
});
|
||||
}
|
||||
@@ -386,16 +394,26 @@ export class ExtHostApiCommands {
|
||||
});
|
||||
}
|
||||
|
||||
private _executeCodeActionProvider(resource: URI, range: types.Range): Thenable<vscode.Command[]> {
|
||||
private _executeCodeActionProvider(resource: URI, range: types.Range): Thenable<(vscode.CodeAction | vscode.Command)[]> {
|
||||
const args = {
|
||||
resource,
|
||||
range: typeConverters.fromRange(range)
|
||||
};
|
||||
return this._commands.executeCommand<modes.Command[]>('_executeCodeActionProvider', args).then(value => {
|
||||
return this._commands.executeCommand<CustomCodeAction[]>('_executeCodeActionProvider', args).then(value => {
|
||||
if (!Array.isArray(value)) {
|
||||
return undefined;
|
||||
}
|
||||
return value.map(quickFix => this._commands.converter.fromInternal(quickFix));
|
||||
return value.map(codeAction => {
|
||||
if (codeAction._isSynthetic) {
|
||||
return this._commands.converter.fromInternal(codeAction.command);
|
||||
} else {
|
||||
const ret = new types.CodeAction(
|
||||
codeAction.title,
|
||||
typeConverters.WorkspaceEdit.to(codeAction.edits)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import { ExtHostHeapService } from 'vs/workbench/api/node/extHostHeapService';
|
||||
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import * as vscode from 'vscode';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
interface CommandHandler {
|
||||
callback: Function;
|
||||
@@ -35,7 +36,8 @@ export class ExtHostCommands implements ExtHostCommandsShape {
|
||||
|
||||
constructor(
|
||||
mainContext: IMainContext,
|
||||
heapService: ExtHostHeapService
|
||||
heapService: ExtHostHeapService,
|
||||
private logService: ILogService
|
||||
) {
|
||||
this._proxy = mainContext.get(MainContext.MainThreadCommands);
|
||||
this._converter = new CommandsConverter(this, heapService);
|
||||
@@ -50,6 +52,7 @@ export class ExtHostCommands implements ExtHostCommandsShape {
|
||||
}
|
||||
|
||||
registerCommand(id: string, callback: <T>(...args: any[]) => T | Thenable<T>, thisArg?: any, description?: ICommandHandlerDescription): extHostTypes.Disposable {
|
||||
this.logService.trace('ExtHostCommands#registerCommand', id);
|
||||
|
||||
if (!id.trim().length) {
|
||||
throw new Error('invalid id');
|
||||
@@ -70,6 +73,7 @@ export class ExtHostCommands implements ExtHostCommandsShape {
|
||||
}
|
||||
|
||||
executeCommand<T>(id: string, ...args: any[]): Thenable<T> {
|
||||
this.logService.trace('ExtHostCommands#executeCommand', id);
|
||||
|
||||
if (this._commands.has(id)) {
|
||||
// we stay inside the extension host and support
|
||||
@@ -134,6 +138,8 @@ export class ExtHostCommands implements ExtHostCommandsShape {
|
||||
}
|
||||
|
||||
getCommands(filterUnderscoreCommands: boolean = false): Thenable<string[]> {
|
||||
this.logService.trace('ExtHostCommands#getCommands', filterUnderscoreCommands);
|
||||
|
||||
return this._proxy.$getCommands().then(result => {
|
||||
if (filterUnderscoreCommands) {
|
||||
result = result.filter(command => command[0] !== '_');
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { mixin, deepClone } from 'vs/base/common/objects';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import * as vscode from 'vscode';
|
||||
@@ -12,7 +12,7 @@ import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { ExtHostConfigurationShape, MainThreadConfigurationShape, IWorkspaceConfigurationChangeEventData, IConfigurationInitData } from './extHost.protocol';
|
||||
import { ConfigurationTarget as ExtHostConfigurationTarget } from './extHostTypes';
|
||||
import { IConfigurationData, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import { Configuration, ConfigurationModel, ConfigurationChangeEvent } from 'vs/platform/configuration/common/configurationModels';
|
||||
import { Configuration, ConfigurationChangeEvent, ConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
|
||||
import { WorkspaceConfigurationChangeEvent } from 'vs/workbench/services/configuration/common/configurationModels';
|
||||
import { StrictResourceMap } from 'vs/base/common/map';
|
||||
import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
@@ -61,9 +61,9 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
|
||||
}
|
||||
|
||||
getConfiguration(section?: string, resource?: URI, extensionId?: string): vscode.WorkspaceConfiguration {
|
||||
const config = section
|
||||
? lookUp(this._configuration.getSection(null, { resource }, this._extHostWorkspace.workspace), section)
|
||||
: this._configuration.getSection(null, { resource }, this._extHostWorkspace.workspace);
|
||||
const config = deepClone(section
|
||||
? lookUp(this._configuration.getValue(null, { resource }, this._extHostWorkspace.workspace), section)
|
||||
: this._configuration.getValue(null, { resource }, this._extHostWorkspace.workspace));
|
||||
|
||||
if (section) {
|
||||
this._validateConfigurationAccess(section, resource, extensionId);
|
||||
@@ -107,7 +107,7 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
|
||||
},
|
||||
inspect: <T>(key: string): ConfigurationInspect<T> => {
|
||||
key = section ? `${section}.${key}` : key;
|
||||
const config = this._configuration.lookup<T>(key, { resource }, this._extHostWorkspace.workspace);
|
||||
const config = deepClone(this._configuration.inspect<T>(key, { resource }, this._extHostWorkspace.workspace));
|
||||
if (config) {
|
||||
return {
|
||||
key,
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { MainContext, MainThreadCredentialsShape, ExtHostCredentialsShape, IMainContext } from 'vs/workbench/api/node/extHost.protocol';
|
||||
|
||||
|
||||
export class ExtHostCredentials implements ExtHostCredentialsShape {
|
||||
|
||||
private _proxy: MainThreadCredentialsShape;
|
||||
|
||||
constructor(mainContext: IMainContext) {
|
||||
this._proxy = mainContext.get(MainContext.MainThreadCredentials);
|
||||
};
|
||||
|
||||
readSecret(service: string, account: string): Thenable<string | undefined> {
|
||||
return this._proxy.$readSecret(service, account);
|
||||
}
|
||||
|
||||
writeSecret(service: string, account: string, secret: string): Thenable<void> {
|
||||
return this._proxy.$writeSecret(service, account, secret);
|
||||
}
|
||||
|
||||
deleteSecret(service: string, account: string): Thenable<boolean> {
|
||||
return this._proxy.$deleteSecret(service, account);
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,12 @@
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { MainContext, MainThreadDebugServiceShape, ExtHostDebugServiceShape, DebugSessionUUID, IMainContext } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { MainContext, MainThreadDebugServiceShape, ExtHostDebugServiceShape, DebugSessionUUID, IMainContext, IBreakpointsDelta, ISourceBreakpointData, IFunctionBreakpointData } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import * as types from 'vs/workbench/api/node/extHostTypes';
|
||||
import { Disposable, Position, Location, SourceBreakpoint, FunctionBreakpoint } from 'vs/workbench/api/node/extHostTypes';
|
||||
|
||||
|
||||
export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
@@ -42,8 +42,13 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
private _onDidReceiveDebugSessionCustomEvent: Emitter<vscode.DebugSessionCustomEvent>;
|
||||
get onDidReceiveDebugSessionCustomEvent(): Event<vscode.DebugSessionCustomEvent> { return this._onDidReceiveDebugSessionCustomEvent.event; }
|
||||
|
||||
private _debugConsole: ExtHostDebugConsole;
|
||||
get debugConsole(): ExtHostDebugConsole { return this._debugConsole; }
|
||||
private _activeDebugConsole: ExtHostDebugConsole;
|
||||
get activeDebugConsole(): ExtHostDebugConsole { return this._activeDebugConsole; }
|
||||
|
||||
private _breakpoints: Map<string, vscode.Breakpoint>;
|
||||
private _breakpointEventsActive: boolean;
|
||||
|
||||
private _onDidChangeBreakpoints: Emitter<vscode.BreakpointsChangeEvent>;
|
||||
|
||||
|
||||
constructor(mainContext: IMainContext, workspace: ExtHostWorkspace) {
|
||||
@@ -60,19 +65,94 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
|
||||
this._debugServiceProxy = mainContext.get(MainContext.MainThreadDebugService);
|
||||
|
||||
this._debugConsole = new ExtHostDebugConsole(this._debugServiceProxy);
|
||||
this._onDidChangeBreakpoints = new Emitter<vscode.BreakpointsChangeEvent>({
|
||||
onFirstListenerAdd: () => {
|
||||
this.startBreakpoints();
|
||||
}
|
||||
});
|
||||
|
||||
this._activeDebugConsole = new ExtHostDebugConsole(this._debugServiceProxy);
|
||||
|
||||
this._breakpoints = new Map<string, vscode.Breakpoint>();
|
||||
this._breakpointEventsActive = false;
|
||||
}
|
||||
|
||||
private startBreakpoints() {
|
||||
if (!this._breakpointEventsActive) {
|
||||
this._breakpointEventsActive = true;
|
||||
this._debugServiceProxy.$startBreakpointEvents();
|
||||
}
|
||||
}
|
||||
|
||||
get onDidChangeBreakpoints(): Event<vscode.BreakpointsChangeEvent> {
|
||||
return this._onDidChangeBreakpoints.event;
|
||||
}
|
||||
|
||||
get breakpoints(): vscode.Breakpoint[] {
|
||||
|
||||
this.startBreakpoints();
|
||||
|
||||
const result: vscode.Breakpoint[] = [];
|
||||
this._breakpoints.forEach(bp => result.push(bp));
|
||||
return result;
|
||||
}
|
||||
|
||||
public $acceptBreakpointsDelta(delta: IBreakpointsDelta): void {
|
||||
|
||||
let a: vscode.Breakpoint[] = [];
|
||||
let r: vscode.Breakpoint[] = [];
|
||||
let c: vscode.Breakpoint[] = [];
|
||||
|
||||
if (delta.added) {
|
||||
a = delta.added.map(bpd => {
|
||||
const bp = this.fromWire(bpd);
|
||||
this._breakpoints.set(bpd.id, bp);
|
||||
return bp;
|
||||
});
|
||||
}
|
||||
|
||||
if (delta.removed) {
|
||||
r = delta.removed.map(id => {
|
||||
const bp = this._breakpoints.get(id);
|
||||
if (bp) {
|
||||
this._breakpoints.delete(id);
|
||||
}
|
||||
return bp;
|
||||
});
|
||||
}
|
||||
|
||||
if (delta.changed) {
|
||||
c = delta.changed.map(bpd => {
|
||||
const bp = this.fromWire(bpd);
|
||||
this._breakpoints.set(bpd.id, bp);
|
||||
return bp;
|
||||
});
|
||||
}
|
||||
|
||||
this._onDidChangeBreakpoints.fire(Object.freeze({
|
||||
added: Object.freeze<vscode.Breakpoint[]>(a || []),
|
||||
removed: Object.freeze<vscode.Breakpoint[]>(r || []),
|
||||
changed: Object.freeze<vscode.Breakpoint[]>(c || [])
|
||||
}));
|
||||
}
|
||||
|
||||
private fromWire(bp: ISourceBreakpointData | IFunctionBreakpointData): vscode.Breakpoint {
|
||||
if (bp.type === 'function') {
|
||||
return new FunctionBreakpoint(bp.enabled, bp.condition, bp.hitCondition, bp.functionName);
|
||||
}
|
||||
return new SourceBreakpoint(bp.enabled, bp.condition, bp.hitCondition, new Location(bp.uri, new Position(bp.line, bp.character)));
|
||||
}
|
||||
|
||||
public registerDebugConfigurationProvider(type: string, provider: vscode.DebugConfigurationProvider): vscode.Disposable {
|
||||
if (!provider) {
|
||||
return new types.Disposable(() => { });
|
||||
return new Disposable(() => { });
|
||||
}
|
||||
|
||||
let handle = this.nextHandle();
|
||||
this._handlers.set(handle, provider);
|
||||
this._debugServiceProxy.$registerDebugConfigurationProvider(type, !!provider.provideDebugConfigurations, !!provider.resolveDebugConfiguration, handle);
|
||||
|
||||
return new types.Disposable(() => {
|
||||
return new Disposable(() => {
|
||||
this._handlers.delete(handle);
|
||||
this._debugServiceProxy.$unregisterDebugConfigurationProvider(handle);
|
||||
});
|
||||
@@ -89,7 +169,6 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
return asWinJsPromise(token => handler.provideDebugConfigurations(this.getFolder(folderUri), token));
|
||||
}
|
||||
|
||||
|
||||
public $resolveDebugConfiguration(handle: number, folderUri: URI | undefined, debugConfiguration: vscode.DebugConfiguration): TPromise<vscode.DebugConfiguration> {
|
||||
let handler = this._handlers.get(handle);
|
||||
if (!handler) {
|
||||
|
||||
@@ -111,7 +111,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
orderLoop: for (let i = 0; i < 4; i++) {
|
||||
for (let diagnostic of diagnostics) {
|
||||
if (diagnostic.severity === order[i]) {
|
||||
const len = marker.push(DiagnosticCollection._toMarkerData(diagnostic));
|
||||
const len = marker.push(DiagnosticCollection.toMarkerData(diagnostic));
|
||||
if (len === DiagnosticCollection._maxDiagnosticsPerFile) {
|
||||
break orderLoop;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
endColumn: marker[marker.length - 1].endColumn
|
||||
});
|
||||
} else {
|
||||
marker = diagnostics.map(DiagnosticCollection._toMarkerData);
|
||||
marker = diagnostics.map(DiagnosticCollection.toMarkerData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
}
|
||||
}
|
||||
|
||||
private static _toMarkerData(diagnostic: vscode.Diagnostic): IMarkerData {
|
||||
public static toMarkerData(diagnostic: vscode.Diagnostic): IMarkerData {
|
||||
|
||||
let range = diagnostic.range;
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
'use strict';
|
||||
|
||||
import Event from 'vs/base/common/event';
|
||||
import CallbackList from 'vs/base/common/callbackList';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { sequence, always } from 'vs/base/common/async';
|
||||
import { illegalState } from 'vs/base/common/errors';
|
||||
@@ -16,12 +15,13 @@ import { fromRange, TextDocumentSaveReason, EndOfLine } from 'vs/workbench/api/n
|
||||
import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
|
||||
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import * as vscode from 'vscode';
|
||||
import { LinkedList } from 'vs/base/common/linkedList';
|
||||
|
||||
export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSaveParticipantShape {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _mainThreadEditors: MainThreadEditorsShape;
|
||||
private _callbacks = new CallbackList();
|
||||
private _callbacks = new LinkedList<[Function, any]>();
|
||||
private _badListeners = new WeakMap<Function, number>();
|
||||
private _thresholds: { timeout: number; errors: number; };
|
||||
|
||||
@@ -32,12 +32,12 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._callbacks.dispose();
|
||||
this._callbacks.clear();
|
||||
}
|
||||
|
||||
get onWillSaveTextDocumentEvent(): Event<vscode.TextDocumentWillSaveEvent> {
|
||||
return (listener, thisArg, disposables) => {
|
||||
const remove = this._callbacks.add(listener, thisArg);
|
||||
const remove = this._callbacks.push([listener, thisArg]);
|
||||
const result = { dispose: remove };
|
||||
if (Array.isArray(disposables)) {
|
||||
disposables.push(result);
|
||||
@@ -47,7 +47,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
|
||||
}
|
||||
|
||||
$participateInSave(resource: URI, reason: SaveReason): TPromise<boolean[]> {
|
||||
const entries = this._callbacks.entries();
|
||||
const entries = this._callbacks.toArray();
|
||||
|
||||
let didTimeout = false;
|
||||
let didTimeoutHandle = setTimeout(() => didTimeout = true, this._thresholds.timeout);
|
||||
|
||||
@@ -12,7 +12,7 @@ import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/n
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
const hasOwnProperty = Object.hasOwnProperty;
|
||||
const NO_OP_VOID_PROMISE = TPromise.as<void>(void 0);
|
||||
const NO_OP_VOID_PROMISE = TPromise.wrap<void>(void 0);
|
||||
|
||||
export interface IExtensionMemento {
|
||||
get<T>(key: string, defaultValue: T): T;
|
||||
@@ -45,7 +45,7 @@ export interface IExtensionAPI {
|
||||
|
||||
export class ExtensionActivationTimes {
|
||||
|
||||
public static NONE = new ExtensionActivationTimes(false, -1, -1, -1);
|
||||
public static readonly NONE = new ExtensionActivationTimes(false, -1, -1, -1);
|
||||
|
||||
public readonly startup: boolean;
|
||||
public readonly codeLoadingTime: number;
|
||||
@@ -159,9 +159,24 @@ export class FailedExtension extends ActivatedExtension {
|
||||
export interface IExtensionsActivatorHost {
|
||||
showMessage(severity: Severity, message: string): void;
|
||||
|
||||
actualActivateExtension(extensionDescription: IExtensionDescription, startup: boolean): TPromise<ActivatedExtension>;
|
||||
actualActivateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): TPromise<ActivatedExtension>;
|
||||
}
|
||||
|
||||
export class ExtensionActivatedByEvent {
|
||||
constructor(
|
||||
public readonly startup: boolean,
|
||||
public readonly activationEvent: string
|
||||
) { }
|
||||
}
|
||||
|
||||
export class ExtensionActivatedByAPI {
|
||||
constructor(
|
||||
public readonly startup: boolean
|
||||
) { }
|
||||
}
|
||||
|
||||
export type ExtensionActivationReason = ExtensionActivatedByEvent | ExtensionActivatedByAPI;
|
||||
|
||||
export class ExtensionsActivator {
|
||||
|
||||
private readonly _registry: ExtensionDescriptionRegistry;
|
||||
@@ -192,23 +207,23 @@ export class ExtensionsActivator {
|
||||
return this._activatedExtensions[extensionId];
|
||||
}
|
||||
|
||||
public activateByEvent(activationEvent: string, startup: boolean): TPromise<void> {
|
||||
public activateByEvent(activationEvent: string, reason: ExtensionActivationReason): TPromise<void> {
|
||||
if (this._alreadyActivatedEvents[activationEvent]) {
|
||||
return NO_OP_VOID_PROMISE;
|
||||
}
|
||||
let activateExtensions = this._registry.getExtensionDescriptionsForActivationEvent(activationEvent);
|
||||
return this._activateExtensions(activateExtensions, startup, 0).then(() => {
|
||||
return this._activateExtensions(activateExtensions, reason, 0).then(() => {
|
||||
this._alreadyActivatedEvents[activationEvent] = true;
|
||||
});
|
||||
}
|
||||
|
||||
public activateById(extensionId: string, startup: boolean): TPromise<void> {
|
||||
public activateById(extensionId: string, reason: ExtensionActivationReason): TPromise<void> {
|
||||
let desc = this._registry.getExtensionDescription(extensionId);
|
||||
if (!desc) {
|
||||
throw new Error('Extension `' + extensionId + '` is not known');
|
||||
}
|
||||
|
||||
return this._activateExtensions([desc], startup, 0);
|
||||
return this._activateExtensions([desc], reason, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -252,7 +267,7 @@ export class ExtensionsActivator {
|
||||
}
|
||||
}
|
||||
|
||||
private _activateExtensions(extensionDescriptions: IExtensionDescription[], startup: boolean, recursionLevel: number): TPromise<void> {
|
||||
private _activateExtensions(extensionDescriptions: IExtensionDescription[], reason: ExtensionActivationReason, recursionLevel: number): TPromise<void> {
|
||||
// console.log(recursionLevel, '_activateExtensions: ', extensionDescriptions.map(p => p.id));
|
||||
if (extensionDescriptions.length === 0) {
|
||||
return TPromise.as(void 0);
|
||||
@@ -294,15 +309,15 @@ export class ExtensionsActivator {
|
||||
|
||||
if (red.length === 0) {
|
||||
// Finally reached only leafs!
|
||||
return TPromise.join(green.map((p) => this._activateExtension(p, startup))).then(_ => void 0);
|
||||
return TPromise.join(green.map((p) => this._activateExtension(p, reason))).then(_ => void 0);
|
||||
}
|
||||
|
||||
return this._activateExtensions(green, startup, recursionLevel + 1).then(_ => {
|
||||
return this._activateExtensions(red, startup, recursionLevel + 1);
|
||||
return this._activateExtensions(green, reason, recursionLevel + 1).then(_ => {
|
||||
return this._activateExtensions(red, reason, recursionLevel + 1);
|
||||
});
|
||||
}
|
||||
|
||||
private _activateExtension(extensionDescription: IExtensionDescription, startup: boolean): TPromise<void> {
|
||||
private _activateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): TPromise<void> {
|
||||
if (hasOwnProperty.call(this._activatedExtensions, extensionDescription.id)) {
|
||||
return TPromise.as(void 0);
|
||||
}
|
||||
@@ -311,7 +326,7 @@ export class ExtensionsActivator {
|
||||
return this._activatingExtensions[extensionDescription.id];
|
||||
}
|
||||
|
||||
this._activatingExtensions[extensionDescription.id] = this._host.actualActivateExtension(extensionDescription, startup).then(null, (err) => {
|
||||
this._activatingExtensions[extensionDescription.id] = this._host.actualActivateExtension(extensionDescription, reason).then(null, (err) => {
|
||||
this._host.showMessage(Severity.Error, nls.localize('activationError', "Activating extension `{0}` failed: {1}.", extensionDescription.id, err.message));
|
||||
console.error('Activating extension `' + extensionDescription.id + '` failed: ', err.message);
|
||||
console.log('Here is the error stack: ', err.stack);
|
||||
|
||||
@@ -15,13 +15,14 @@ import { ExtHostStorage } from 'vs/workbench/api/node/extHostStorage';
|
||||
// {{SQL CARBON EDIT}}
|
||||
import { createApiFactory, initializeExtensionApi } from 'sql/workbench/api/node/sqlExtHost.api.impl';
|
||||
import { MainContext, MainThreadExtensionServiceShape, IWorkspaceData, IEnvironment, IInitData, ExtHostExtensionServiceShape, MainThreadTelemetryShape } from './extHost.protocol';
|
||||
import { IExtensionMemento, ExtensionsActivator, ActivatedExtension, IExtensionAPI, IExtensionContext, EmptyExtension, IExtensionModule, ExtensionActivationTimesBuilder, ExtensionActivationTimes } from 'vs/workbench/api/node/extHostExtensionActivator';
|
||||
import { Barrier } from 'vs/workbench/services/extensions/node/barrier';
|
||||
import { IExtensionMemento, ExtensionsActivator, ActivatedExtension, IExtensionAPI, IExtensionContext, EmptyExtension, IExtensionModule, ExtensionActivationTimesBuilder, ExtensionActivationTimes, ExtensionActivationReason, ExtensionActivatedByEvent } from 'vs/workbench/api/node/extHostExtensionActivator';
|
||||
import { ExtHostThreadService } from 'vs/workbench/services/thread/node/extHostThreadService';
|
||||
import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { realpath } from 'fs';
|
||||
import { TernarySearchTree } from 'vs/base/common/map';
|
||||
import { Barrier } from 'vs/base/common/async';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
class ExtensionMemento implements IExtensionMemento {
|
||||
|
||||
@@ -118,6 +119,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
private readonly _storage: ExtHostStorage;
|
||||
private readonly _storagePath: ExtensionStoragePath;
|
||||
private readonly _proxy: MainThreadExtensionServiceShape;
|
||||
private readonly _logService: ILogService;
|
||||
private _activator: ExtensionsActivator;
|
||||
private _extensionPathIndex: TPromise<TernarySearchTree<IExtensionDescription>>;
|
||||
/**
|
||||
@@ -126,11 +128,13 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
constructor(initData: IInitData,
|
||||
threadService: ExtHostThreadService,
|
||||
extHostWorkspace: ExtHostWorkspace,
|
||||
extHostConfiguration: ExtHostConfiguration
|
||||
extHostConfiguration: ExtHostConfiguration,
|
||||
logService: ILogService
|
||||
) {
|
||||
this._barrier = new Barrier();
|
||||
this._registry = new ExtensionDescriptionRegistry(initData.extensions);
|
||||
this._threadService = threadService;
|
||||
this._logService = logService;
|
||||
this._mainThreadTelemetry = threadService.get(MainContext.MainThreadTelemetry);
|
||||
this._storage = new ExtHostStorage(threadService);
|
||||
this._storagePath = new ExtensionStoragePath(initData.workspace, initData.environment);
|
||||
@@ -138,7 +142,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
this._activator = null;
|
||||
|
||||
// initialize API first (i.e. do not release barrier until the API is initialized)
|
||||
const apiFactory = createApiFactory(initData, threadService, extHostWorkspace, extHostConfiguration, this);
|
||||
const apiFactory = createApiFactory(initData, threadService, extHostWorkspace, extHostConfiguration, this, logService);
|
||||
|
||||
initializeExtensionApi(this, apiFactory).then(() => {
|
||||
|
||||
@@ -158,8 +162,8 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
}
|
||||
},
|
||||
|
||||
actualActivateExtension: (extensionDescription: IExtensionDescription, startup: boolean): TPromise<ActivatedExtension> => {
|
||||
return this._activateExtension(extensionDescription, startup);
|
||||
actualActivateExtension: (extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): TPromise<ActivatedExtension> => {
|
||||
return this._activateExtension(extensionDescription, reason);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -179,18 +183,19 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
}
|
||||
|
||||
public activateByEvent(activationEvent: string, startup: boolean): TPromise<void> {
|
||||
const reason = new ExtensionActivatedByEvent(startup, activationEvent);
|
||||
if (this._barrier.isOpen()) {
|
||||
return this._activator.activateByEvent(activationEvent, startup);
|
||||
return this._activator.activateByEvent(activationEvent, reason);
|
||||
} else {
|
||||
return this._barrier.wait().then(() => this._activator.activateByEvent(activationEvent, startup));
|
||||
return this._barrier.wait().then(() => this._activator.activateByEvent(activationEvent, reason));
|
||||
}
|
||||
}
|
||||
|
||||
public activateById(extensionId: string, startup: boolean): TPromise<void> {
|
||||
public activateById(extensionId: string, reason: ExtensionActivationReason): TPromise<void> {
|
||||
if (this._barrier.isOpen()) {
|
||||
return this._activator.activateById(extensionId, startup);
|
||||
return this._activator.activateById(extensionId, reason);
|
||||
} else {
|
||||
return this._barrier.wait().then(() => this._activator.activateById(extensionId, startup));
|
||||
return this._barrier.wait().then(() => this._activator.activateById(extensionId, reason));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,12 +278,17 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
return result;
|
||||
}
|
||||
|
||||
public addMessage(extensionId: string, severity: Severity, message: string): void {
|
||||
this._proxy.$addMessage(extensionId, severity, message);
|
||||
}
|
||||
|
||||
// --- impl
|
||||
|
||||
private _activateExtension(extensionDescription: IExtensionDescription, startup: boolean): TPromise<ActivatedExtension> {
|
||||
return this._doActivateExtension(extensionDescription, startup).then((activatedExtension) => {
|
||||
private _activateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): TPromise<ActivatedExtension> {
|
||||
return this._doActivateExtension(extensionDescription, reason).then((activatedExtension) => {
|
||||
const activationTimes = activatedExtension.activationTimes;
|
||||
this._proxy.$onExtensionActivated(extensionDescription.id, activationTimes.startup, activationTimes.codeLoadingTime, activationTimes.activateCallTime, activationTimes.activateResolvedTime);
|
||||
let activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null);
|
||||
this._proxy.$onExtensionActivated(extensionDescription.id, activationTimes.startup, activationTimes.codeLoadingTime, activationTimes.activateCallTime, activationTimes.activateResolvedTime, activationEvent);
|
||||
return activatedExtension;
|
||||
}, (err) => {
|
||||
this._proxy.$onExtensionActivationFailed(extensionDescription.id);
|
||||
@@ -286,7 +296,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
});
|
||||
}
|
||||
|
||||
private _doActivateExtension(extensionDescription: IExtensionDescription, startup: boolean): TPromise<ActivatedExtension> {
|
||||
private _doActivateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): TPromise<ActivatedExtension> {
|
||||
let event = getTelemetryActivationEvent(extensionDescription);
|
||||
/* __GDPR__
|
||||
"activatePlugin" : {
|
||||
@@ -301,12 +311,14 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
return TPromise.as(new EmptyExtension(ExtensionActivationTimes.NONE));
|
||||
}
|
||||
|
||||
const activationTimesBuilder = new ExtensionActivationTimesBuilder(startup);
|
||||
this._logService.info(`ExtensionService#_doActivateExtension ${extensionDescription.id} ${JSON.stringify(reason)}`);
|
||||
|
||||
const activationTimesBuilder = new ExtensionActivationTimesBuilder(reason.startup);
|
||||
return TPromise.join<any>([
|
||||
loadCommonJSModule(extensionDescription.main, activationTimesBuilder),
|
||||
loadCommonJSModule(this._logService, extensionDescription.main, activationTimesBuilder),
|
||||
this._loadExtensionContext(extensionDescription)
|
||||
]).then(values => {
|
||||
return ExtHostExtensionService._callActivate(<IExtensionModule>values[0], <IExtensionContext>values[1], activationTimesBuilder);
|
||||
return ExtHostExtensionService._callActivate(this._logService, extensionDescription.id, <IExtensionModule>values[0], <IExtensionContext>values[1], activationTimesBuilder);
|
||||
}, (errors: any[]) => {
|
||||
// Avoid failing with an array of errors, fail with a single error
|
||||
if (errors[0]) {
|
||||
@@ -324,6 +336,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
let globalState = new ExtensionMemento(extensionDescription.id, true, this._storage);
|
||||
let workspaceState = new ExtensionMemento(extensionDescription.id, false, this._storage);
|
||||
|
||||
this._logService.trace(`ExtensionService#loadExtensionContext ${extensionDescription.id}`);
|
||||
return TPromise.join([
|
||||
globalState.whenReady,
|
||||
workspaceState.whenReady,
|
||||
@@ -340,22 +353,23 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
});
|
||||
}
|
||||
|
||||
private static _callActivate(extensionModule: IExtensionModule, context: IExtensionContext, activationTimesBuilder: ExtensionActivationTimesBuilder): TPromise<ActivatedExtension> {
|
||||
private static _callActivate(logService: ILogService, extensionId: string, extensionModule: IExtensionModule, context: IExtensionContext, activationTimesBuilder: ExtensionActivationTimesBuilder): Thenable<ActivatedExtension> {
|
||||
// Make sure the extension's surface is not undefined
|
||||
extensionModule = extensionModule || {
|
||||
activate: undefined,
|
||||
deactivate: undefined
|
||||
};
|
||||
|
||||
return this._callActivateOptional(extensionModule, context, activationTimesBuilder).then((extensionExports) => {
|
||||
return this._callActivateOptional(logService, extensionId, extensionModule, context, activationTimesBuilder).then((extensionExports) => {
|
||||
return new ActivatedExtension(false, activationTimesBuilder.build(), extensionModule, extensionExports, context.subscriptions);
|
||||
});
|
||||
}
|
||||
|
||||
private static _callActivateOptional(extensionModule: IExtensionModule, context: IExtensionContext, activationTimesBuilder: ExtensionActivationTimesBuilder): TPromise<IExtensionAPI> {
|
||||
private static _callActivateOptional(logService: ILogService, extensionId: string, extensionModule: IExtensionModule, context: IExtensionContext, activationTimesBuilder: ExtensionActivationTimesBuilder): Thenable<IExtensionAPI> {
|
||||
if (typeof extensionModule.activate === 'function') {
|
||||
try {
|
||||
activationTimesBuilder.activateCallStart();
|
||||
logService.trace(`ExtensionService#_callActivateOptional ${extensionId}`);
|
||||
const activateResult: TPromise<IExtensionAPI> = extensionModule.activate.apply(global, [context]);
|
||||
activationTimesBuilder.activateCallStop();
|
||||
|
||||
@@ -380,9 +394,10 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
}
|
||||
}
|
||||
|
||||
function loadCommonJSModule<T>(modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): TPromise<T> {
|
||||
function loadCommonJSModule<T>(logService: ILogService, modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): TPromise<T> {
|
||||
let r: T = null;
|
||||
activationTimesBuilder.codeLoadingStart();
|
||||
logService.info(`ExtensionService#loadCommonJSModule ${modulePath}`);
|
||||
try {
|
||||
r = require.__$__nodeRequire<T>(modulePath);
|
||||
} catch (e) {
|
||||
@@ -400,13 +415,7 @@ function getTelemetryActivationEvent(extensionDescription: IExtensionDescription
|
||||
"name": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
|
||||
"publisherDisplayName": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
|
||||
"activationEvents": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"isBuiltin": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"${wildcard}": [
|
||||
{
|
||||
"${prefix}": "contribution.",
|
||||
"${classification}": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
]
|
||||
"isBuiltin": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
let event = {
|
||||
@@ -417,34 +426,5 @@ function getTelemetryActivationEvent(extensionDescription: IExtensionDescription
|
||||
isBuiltin: extensionDescription.isBuiltin
|
||||
};
|
||||
|
||||
for (let contribution in extensionDescription.contributes) {
|
||||
let contributionDetails = extensionDescription.contributes[contribution];
|
||||
|
||||
if (!contributionDetails) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (contribution) {
|
||||
case 'debuggers':
|
||||
let types = contributionDetails.reduce((p, c) => p ? p + ',' + c['type'] : c['type'], '');
|
||||
event['contribution.debuggers'] = types;
|
||||
break;
|
||||
case 'grammars':
|
||||
let grammers = contributionDetails.reduce((p, c) => p ? p + ',' + c['language'] : c['language'], '');
|
||||
event['contribution.grammars'] = grammers;
|
||||
break;
|
||||
case 'languages':
|
||||
let languages = contributionDetails.reduce((p, c) => p ? p + ',' + c['id'] : c['id'], '');
|
||||
event['contribution.languages'] = languages;
|
||||
break;
|
||||
case 'tmSnippets':
|
||||
let tmSnippets = contributionDetails.reduce((p, c) => p ? p + ',' + c['languageId'] : c['languageId'], '');
|
||||
event['contribution.tmSnippets'] = tmSnippets;
|
||||
break;
|
||||
default:
|
||||
event[`contribution.${contribution}`] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import * as modes from 'vs/editor/common/modes';
|
||||
import { ExtHostHeapService } from 'vs/workbench/api/node/extHostHeapService';
|
||||
import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
|
||||
import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { ExtHostDiagnostics } from 'vs/workbench/api/node/extHostDiagnostics';
|
||||
import { ExtHostDiagnostics, DiagnosticCollection } from 'vs/workbench/api/node/extHostDiagnostics';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IMainContext, IExtHostSuggestResult, IExtHostSuggestion, IWorkspaceSymbols, IWorkspaceSymbol, IdObject } from './extHost.protocol';
|
||||
import { regExpLeadsToEndlessLoop } from 'vs/base/common/strings';
|
||||
@@ -255,7 +255,11 @@ class ReferenceAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
class QuickFixAdapter {
|
||||
export interface CustomCodeAction extends modes.CodeAction {
|
||||
_isSynthetic?: boolean;
|
||||
}
|
||||
|
||||
class CodeActionAdapter {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _commands: CommandsConverter;
|
||||
@@ -269,7 +273,7 @@ class QuickFixAdapter {
|
||||
this._provider = provider;
|
||||
}
|
||||
|
||||
provideCodeActions(resource: URI, range: IRange): TPromise<modes.Command[]> {
|
||||
provideCodeActions(resource: URI, range: IRange): TPromise<modes.CodeAction[]> {
|
||||
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
const ran = <vscode.Range>TypeConverters.toRange(range);
|
||||
@@ -285,13 +289,45 @@ class QuickFixAdapter {
|
||||
}
|
||||
});
|
||||
|
||||
return asWinJsPromise(token => this._provider.provideCodeActions(doc, ran, { diagnostics: allDiagnostics }, token)).then(commands => {
|
||||
if (!Array.isArray(commands)) {
|
||||
return asWinJsPromise(token => this._provider.provideCodeActions2
|
||||
? this._provider.provideCodeActions2(doc, ran, { diagnostics: allDiagnostics }, token)
|
||||
: this._provider.provideCodeActions(doc, ran, { diagnostics: allDiagnostics }, token)
|
||||
).then(commandsOrActions => {
|
||||
if (isFalsyOrEmpty(commandsOrActions)) {
|
||||
return undefined;
|
||||
}
|
||||
return commands.map(command => this._commands.toInternal(command));
|
||||
const result: CustomCodeAction[] = [];
|
||||
for (const candidate of commandsOrActions) {
|
||||
if (!candidate) {
|
||||
continue;
|
||||
}
|
||||
if (CodeActionAdapter._isCommand(candidate)) {
|
||||
// old school: synthetic code action
|
||||
result.push({
|
||||
_isSynthetic: true,
|
||||
title: candidate.title,
|
||||
command: this._commands.toInternal(candidate),
|
||||
});
|
||||
} else {
|
||||
// new school: convert code action
|
||||
result.push({
|
||||
title: candidate.title,
|
||||
command: candidate.command && this._commands.toInternal(candidate.command),
|
||||
diagnostics: candidate.diagnostics && candidate.diagnostics.map(DiagnosticCollection.toMarkerData),
|
||||
edits: Array.isArray(candidate.edits)
|
||||
? TypeConverters.WorkspaceEdit.fromTextEdits(resource, candidate.edits)
|
||||
: candidate.edits && TypeConverters.WorkspaceEdit.from(candidate.edits),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
private static _isCommand(thing: any): thing is vscode.Command {
|
||||
return typeof (<vscode.Command>thing).command === 'string' && typeof (<vscode.Command>thing).title === 'string';
|
||||
}
|
||||
}
|
||||
|
||||
class DocumentFormattingAdapter {
|
||||
@@ -382,13 +418,23 @@ class NavigateTypeAdapter {
|
||||
return asWinJsPromise(token => this._provider.provideWorkspaceSymbols(search, token)).then(value => {
|
||||
if (!isFalsyOrEmpty(value)) {
|
||||
for (const item of value) {
|
||||
if (!item) {
|
||||
// drop
|
||||
continue;
|
||||
}
|
||||
if (!item.name) {
|
||||
console.warn('INVALID SymbolInformation, lacks name', item);
|
||||
continue;
|
||||
}
|
||||
const symbol = IdObject.mixin(TypeConverters.fromSymbolInformation(item));
|
||||
this._symbolCache[symbol._id] = item;
|
||||
result.symbols.push(symbol);
|
||||
}
|
||||
}
|
||||
}).then(() => {
|
||||
this._resultCache[result._id] = [result.symbols[0]._id, result.symbols[result.symbols.length - 1]._id];
|
||||
if (result.symbols.length > 0) {
|
||||
this._resultCache[result._id] = [result.symbols[0]._id, result.symbols[result.symbols.length - 1]._id];
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
@@ -438,30 +484,22 @@ class RenameAdapter {
|
||||
if (!value) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let result = <modes.WorkspaceEdit>{
|
||||
edits: []
|
||||
};
|
||||
|
||||
for (let entry of value.entries()) {
|
||||
let [uri, textEdits] = entry;
|
||||
for (let textEdit of textEdits) {
|
||||
result.edits.push({
|
||||
resource: uri,
|
||||
newText: textEdit.newText,
|
||||
range: TypeConverters.fromRange(textEdit.range)
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return TypeConverters.WorkspaceEdit.from(value);
|
||||
}, err => {
|
||||
if (typeof err === 'string') {
|
||||
return <modes.WorkspaceEdit>{
|
||||
edits: undefined,
|
||||
rejectReason: err
|
||||
};
|
||||
} else if (err instanceof Error && typeof err.message === 'string') {
|
||||
return <modes.WorkspaceEdit>{
|
||||
edits: undefined,
|
||||
rejectReason: err.message
|
||||
};
|
||||
} else {
|
||||
// generic error
|
||||
return TPromise.wrapError<modes.WorkspaceEdit>(err);
|
||||
}
|
||||
return TPromise.wrapError<modes.WorkspaceEdit>(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -707,9 +745,7 @@ class LinkProviderAdapter {
|
||||
class ColorProviderAdapter {
|
||||
|
||||
constructor(
|
||||
private _proxy: MainThreadLanguageFeaturesShape,
|
||||
private _documents: ExtHostDocuments,
|
||||
private _colorFormatCache: Map<string, number>,
|
||||
private _provider: vscode.DocumentColorProvider
|
||||
) { }
|
||||
|
||||
@@ -742,7 +778,7 @@ class ColorProviderAdapter {
|
||||
}
|
||||
|
||||
type Adapter = OutlineAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapter
|
||||
| DocumentHighlightAdapter | ReferenceAdapter | QuickFixAdapter | DocumentFormattingAdapter
|
||||
| DocumentHighlightAdapter | ReferenceAdapter | CodeActionAdapter | DocumentFormattingAdapter
|
||||
| RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
|
||||
| SuggestAdapter | SignatureHelpAdapter | LinkProviderAdapter | ImplementationAdapter | TypeDefinitionAdapter | ColorProviderAdapter;
|
||||
|
||||
@@ -756,7 +792,6 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
private _heapService: ExtHostHeapService;
|
||||
private _diagnostics: ExtHostDiagnostics;
|
||||
private _adapter = new Map<number, Adapter>();
|
||||
private _colorFormatCache = new Map<string, number>();
|
||||
|
||||
constructor(
|
||||
mainContext: IMainContext,
|
||||
@@ -908,13 +943,13 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerCodeActionProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter.set(handle, new QuickFixAdapter(this._documents, this._commands.converter, this._diagnostics, provider));
|
||||
this._adapter.set(handle, new CodeActionAdapter(this._documents, this._commands.converter, this._diagnostics, provider));
|
||||
this._proxy.$registerQuickFixSupport(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideCodeActions(handle: number, resource: URI, range: IRange): TPromise<modes.Command[]> {
|
||||
return this._withAdapter(handle, QuickFixAdapter, adapter => adapter.provideCodeActions(resource, range));
|
||||
$provideCodeActions(handle: number, resource: URI, range: IRange): TPromise<modes.CodeAction[]> {
|
||||
return this._withAdapter(handle, CodeActionAdapter, adapter => adapter.provideCodeActions(resource, range));
|
||||
}
|
||||
|
||||
// --- formatting
|
||||
@@ -1039,7 +1074,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerColorProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentColorProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter.set(handle, new ColorProviderAdapter(this._proxy, this._documents, this._colorFormatCache, provider));
|
||||
this._adapter.set(handle, new ColorProviderAdapter(this._documents, provider));
|
||||
this._proxy.$registerDocumentColorProvider(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
@@ -9,8 +9,7 @@ import vscode = require('vscode');
|
||||
import { MainContext, MainThreadMessageServiceShape, MainThreadMessageOptions, IMainContext } from './extHost.protocol';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
|
||||
function isMessageItem<T>(item: any): item is vscode.MessageItem {
|
||||
function isMessageItem(item: any): item is vscode.MessageItem {
|
||||
return item && item.title;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ import { MainContext, MainThreadSCMShape, SCMRawResource, SCMRawResourceSplice,
|
||||
import { sortedDiff } from 'vs/base/common/arrays';
|
||||
import { comparePaths } from 'vs/base/common/comparers';
|
||||
import * as vscode from 'vscode';
|
||||
import { ISplice } from 'vs/base/common/sequence';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
type ProviderHandle = number;
|
||||
type GroupHandle = number;
|
||||
@@ -127,6 +129,17 @@ export class ExtHostSCMInputBox {
|
||||
return this._onDidChange.event;
|
||||
}
|
||||
|
||||
private _placeholder: string = '';
|
||||
|
||||
get placeholder(): string {
|
||||
return this._placeholder;
|
||||
}
|
||||
|
||||
set placeholder(placeholder: string) {
|
||||
this._proxy.$setInputBoxPlaceholder(this._sourceControlHandle, placeholder);
|
||||
this._placeholder = placeholder;
|
||||
}
|
||||
|
||||
constructor(private _proxy: MainThreadSCMShape, private _sourceControlHandle: number) {
|
||||
// noop
|
||||
}
|
||||
@@ -147,7 +160,6 @@ class ExtHostSourceControlResourceGroup implements vscode.SourceControlResourceG
|
||||
private _resourceHandlePool: number = 0;
|
||||
private _resourceStates: vscode.SourceControlResourceState[] = [];
|
||||
|
||||
private _resourceStatesRollingDisposables: { (): void }[] = [];
|
||||
private _resourceStatesMap: Map<ResourceStateHandle, vscode.SourceControlResourceState> = new Map<ResourceStateHandle, vscode.SourceControlResourceState>();
|
||||
private _resourceStatesCommandsMap: Map<ResourceStateHandle, vscode.Command> = new Map<ResourceStateHandle, vscode.Command>();
|
||||
|
||||
@@ -210,65 +222,63 @@ class ExtHostSourceControlResourceGroup implements vscode.SourceControlResourceG
|
||||
_takeResourceStateSnapshot(): SCMRawResourceSplice[] {
|
||||
const snapshot = [...this._resourceStates].sort(compareResourceStates);
|
||||
const diffs = sortedDiff(this._resourceSnapshot, snapshot, compareResourceStates);
|
||||
const handlesToDelete: number[] = [];
|
||||
|
||||
const splices = diffs.map(diff => {
|
||||
const { start, deleteCount } = diff;
|
||||
const handles: number[] = [];
|
||||
const splices = diffs.map<ISplice<{ rawResource: SCMRawResource, handle: number }>>(diff => {
|
||||
const toInsert = diff.toInsert.map(r => {
|
||||
const handle = this._resourceHandlePool++;
|
||||
this._resourceStatesMap.set(handle, r);
|
||||
|
||||
const rawResources = diff.inserted
|
||||
.map(r => {
|
||||
const handle = this._resourceHandlePool++;
|
||||
this._resourceStatesMap.set(handle, r);
|
||||
handles.push(handle);
|
||||
const sourceUri = r.resourceUri.toString();
|
||||
const iconPath = getIconPath(r.decorations);
|
||||
const lightIconPath = r.decorations && getIconPath(r.decorations.light) || iconPath;
|
||||
const darkIconPath = r.decorations && getIconPath(r.decorations.dark) || iconPath;
|
||||
const icons: string[] = [];
|
||||
|
||||
const sourceUri = r.resourceUri.toString();
|
||||
const iconPath = getIconPath(r.decorations);
|
||||
const lightIconPath = r.decorations && getIconPath(r.decorations.light) || iconPath;
|
||||
const darkIconPath = r.decorations && getIconPath(r.decorations.dark) || iconPath;
|
||||
const icons: string[] = [];
|
||||
if (r.command) {
|
||||
this._resourceStatesCommandsMap.set(handle, r.command);
|
||||
}
|
||||
|
||||
if (r.command) {
|
||||
this._resourceStatesCommandsMap.set(handle, r.command);
|
||||
}
|
||||
if (lightIconPath || darkIconPath) {
|
||||
icons.push(lightIconPath);
|
||||
}
|
||||
|
||||
if (lightIconPath || darkIconPath) {
|
||||
icons.push(lightIconPath);
|
||||
}
|
||||
if (darkIconPath !== lightIconPath) {
|
||||
icons.push(darkIconPath);
|
||||
}
|
||||
|
||||
if (darkIconPath !== lightIconPath) {
|
||||
icons.push(darkIconPath);
|
||||
}
|
||||
const tooltip = (r.decorations && r.decorations.tooltip) || '';
|
||||
const strikeThrough = r.decorations && !!r.decorations.strikeThrough;
|
||||
const faded = r.decorations && !!r.decorations.faded;
|
||||
|
||||
const tooltip = (r.decorations && r.decorations.tooltip) || '';
|
||||
const strikeThrough = r.decorations && !!r.decorations.strikeThrough;
|
||||
const faded = r.decorations && !!r.decorations.faded;
|
||||
const source = r.decorations && r.decorations.source || undefined;
|
||||
const letter = r.decorations && r.decorations.letter || undefined;
|
||||
const color = r.decorations && r.decorations.color || undefined;
|
||||
|
||||
const source = r.decorations && r.decorations.source || undefined;
|
||||
const letter = r.decorations && r.decorations.letter || undefined;
|
||||
const color = r.decorations && r.decorations.color || undefined;
|
||||
const rawResource = [handle, sourceUri, icons, tooltip, strikeThrough, faded, source, letter, color] as SCMRawResource;
|
||||
|
||||
return [handle, sourceUri, icons, tooltip, strikeThrough, faded, source, letter, color] as SCMRawResource;
|
||||
});
|
||||
return { rawResource, handle };
|
||||
});
|
||||
|
||||
handlesToDelete.push(...this._handlesSnapshot.splice(start, deleteCount, ...handles));
|
||||
|
||||
return [start, deleteCount, rawResources] as SCMRawResourceSplice;
|
||||
return { start: diff.start, deleteCount: diff.deleteCount, toInsert };
|
||||
});
|
||||
|
||||
const disposable = () => handlesToDelete.forEach(handle => {
|
||||
this._resourceStatesMap.delete(handle);
|
||||
this._resourceStatesCommandsMap.delete(handle);
|
||||
});
|
||||
const rawResourceSplices = splices
|
||||
.map(({ start, deleteCount, toInsert }) => [start, deleteCount, toInsert.map(i => i.rawResource)] as SCMRawResourceSplice);
|
||||
|
||||
this._resourceStatesRollingDisposables.push(disposable);
|
||||
const reverseSplices = splices.reverse();
|
||||
|
||||
while (this._resourceStatesRollingDisposables.length >= 10) {
|
||||
this._resourceStatesRollingDisposables.shift()();
|
||||
for (const { start, deleteCount, toInsert } of reverseSplices) {
|
||||
const handles = toInsert.map(i => i.handle);
|
||||
const handlesToDelete = this._handlesSnapshot.splice(start, deleteCount, ...handles);
|
||||
|
||||
for (const handle of handlesToDelete) {
|
||||
this._resourceStatesMap.delete(handle);
|
||||
this._resourceStatesCommandsMap.delete(handle);
|
||||
}
|
||||
}
|
||||
|
||||
this._resourceSnapshot = snapshot;
|
||||
return splices;
|
||||
return rawResourceSplices;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
@@ -434,7 +444,8 @@ export class ExtHostSCM {
|
||||
|
||||
constructor(
|
||||
mainContext: IMainContext,
|
||||
private _commands: ExtHostCommands
|
||||
private _commands: ExtHostCommands,
|
||||
@ILogService private logService: ILogService
|
||||
) {
|
||||
this._proxy = mainContext.get(MainContext.MainThreadSCM);
|
||||
|
||||
@@ -478,6 +489,8 @@ export class ExtHostSCM {
|
||||
}
|
||||
|
||||
createSourceControl(extension: IExtensionDescription, id: string, label: string, rootUri: vscode.Uri | undefined): vscode.SourceControl {
|
||||
this.logService.trace('ExtHostSCM#createSourceControl', extension.id, id, label, rootUri);
|
||||
|
||||
const handle = ExtHostSCM._handlePool++;
|
||||
const sourceControl = new ExtHostSourceControl(this._proxy, this._commands, id, label, rootUri);
|
||||
this._sourceControls.set(handle, sourceControl);
|
||||
@@ -491,6 +504,8 @@ export class ExtHostSCM {
|
||||
|
||||
// Deprecated
|
||||
getLastInputBox(extension: IExtensionDescription): ExtHostSCMInputBox {
|
||||
this.logService.trace('ExtHostSCM#getLastInputBox', extension.id);
|
||||
|
||||
const sourceControls = this._sourceControlsByExtension.get(extension.id);
|
||||
const sourceControl = sourceControls && sourceControls[sourceControls.length - 1];
|
||||
const inputBox = sourceControl && sourceControl.inputBox;
|
||||
@@ -499,6 +514,8 @@ export class ExtHostSCM {
|
||||
}
|
||||
|
||||
$provideOriginalResource(sourceControlHandle: number, uri: URI): TPromise<URI> {
|
||||
this.logService.trace('ExtHostSCM#$provideOriginalResource', sourceControlHandle, uri);
|
||||
|
||||
const sourceControl = this._sourceControls.get(sourceControlHandle);
|
||||
|
||||
if (!sourceControl || !sourceControl.quickDiffProvider) {
|
||||
@@ -512,6 +529,8 @@ export class ExtHostSCM {
|
||||
}
|
||||
|
||||
$onInputBoxValueChange(sourceControlHandle: number, value: string): TPromise<void> {
|
||||
this.logService.trace('ExtHostSCM#$onInputBoxValueChange', sourceControlHandle);
|
||||
|
||||
const sourceControl = this._sourceControls.get(sourceControlHandle);
|
||||
|
||||
if (!sourceControl) {
|
||||
@@ -523,6 +542,8 @@ export class ExtHostSCM {
|
||||
}
|
||||
|
||||
async $executeResourceCommand(sourceControlHandle: number, groupHandle: number, handle: number): TPromise<void> {
|
||||
this.logService.trace('ExtHostSCM#$executeResourceCommand', sourceControlHandle, groupHandle, handle);
|
||||
|
||||
const sourceControl = this._sourceControls.get(sourceControlHandle);
|
||||
|
||||
if (!sourceControl) {
|
||||
|
||||
@@ -19,9 +19,6 @@ import * as types from 'vs/workbench/api/node/extHostTypes';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
interface StringMap<V> {
|
||||
[key: string]: V;
|
||||
}
|
||||
|
||||
/*
|
||||
namespace ProblemPattern {
|
||||
@@ -431,7 +428,7 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
this._extHostWorkspace = extHostWorkspace;
|
||||
this._handleCounter = 0;
|
||||
this._handlers = new Map<number, HandlerData>();
|
||||
};
|
||||
}
|
||||
|
||||
public registerTaskProvider(extension: IExtensionDescription, provider: vscode.TaskProvider): vscode.Disposable {
|
||||
if (!provider) {
|
||||
@@ -463,4 +460,4 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
private nextHandle(): number {
|
||||
return this._handleCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import { IRange } from 'vs/editor/common/core/range';
|
||||
|
||||
export class TextEditorDecorationType implements vscode.TextEditorDecorationType {
|
||||
|
||||
private static _Keys = new IdGenerator('TextEditorDecorationType');
|
||||
private static readonly _Keys = new IdGenerator('TextEditorDecorationType');
|
||||
|
||||
private _proxy: MainThreadEditorsShape;
|
||||
public key: string;
|
||||
|
||||
@@ -20,13 +20,13 @@ export class ExtHostEditors implements ExtHostEditorsShape {
|
||||
private readonly _onDidChangeTextEditorSelection = new Emitter<vscode.TextEditorSelectionChangeEvent>();
|
||||
private readonly _onDidChangeTextEditorOptions = new Emitter<vscode.TextEditorOptionsChangeEvent>();
|
||||
private readonly _onDidChangeTextEditorViewColumn = new Emitter<vscode.TextEditorViewColumnChangeEvent>();
|
||||
private readonly _onDidChangeActiveTextEditor = new Emitter<vscode.TextEditor>();
|
||||
private readonly _onDidChangeActiveTextEditor = new Emitter<vscode.TextEditor | undefined>();
|
||||
private readonly _onDidChangeVisibleTextEditors = new Emitter<vscode.TextEditor[]>();
|
||||
|
||||
readonly onDidChangeTextEditorSelection: Event<vscode.TextEditorSelectionChangeEvent> = this._onDidChangeTextEditorSelection.event;
|
||||
readonly onDidChangeTextEditorOptions: Event<vscode.TextEditorOptionsChangeEvent> = this._onDidChangeTextEditorOptions.event;
|
||||
readonly onDidChangeTextEditorViewColumn: Event<vscode.TextEditorViewColumnChangeEvent> = this._onDidChangeTextEditorViewColumn.event;
|
||||
readonly onDidChangeActiveTextEditor: Event<vscode.TextEditor> = this._onDidChangeActiveTextEditor.event;
|
||||
readonly onDidChangeActiveTextEditor: Event<vscode.TextEditor | undefined> = this._onDidChangeActiveTextEditor.event;
|
||||
readonly onDidChangeVisibleTextEditors: Event<vscode.TextEditor[]> = this._onDidChangeVisibleTextEditors.event;
|
||||
|
||||
|
||||
|
||||
@@ -7,17 +7,15 @@
|
||||
import { localize } from 'vs/nls';
|
||||
import * as vscode from 'vscode';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { distinct } from 'vs/base/common/arrays';
|
||||
import { debounceEvent } from 'vs/base/common/event';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ExtHostTreeViewsShape, MainThreadTreeViewsShape } from './extHost.protocol';
|
||||
import { ITreeItem, TreeViewItemHandleArg } from 'vs/workbench/common/views';
|
||||
import { TreeItemCollapsibleState } from './extHostTypes';
|
||||
import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
|
||||
type TreeItemHandle = number;
|
||||
type TreeItemHandle = string;
|
||||
|
||||
export class ExtHostTreeViews implements ExtHostTreeViewsShape {
|
||||
|
||||
@@ -56,7 +54,7 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
|
||||
return treeView.getTreeItems();
|
||||
}
|
||||
|
||||
$getChildren(treeViewId: string, treeItemHandle?: number): TPromise<ITreeItem[]> {
|
||||
$getChildren(treeViewId: string, treeItemHandle?: string): TPromise<ITreeItem[]> {
|
||||
const treeView = this.treeViews.get(treeViewId);
|
||||
if (!treeView) {
|
||||
return TPromise.wrapError<ITreeItem[]>(new Error(localize('treeView.notRegistered', 'No tree view with id \'{0}\' registered.', treeViewId)));
|
||||
@@ -70,13 +68,18 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
|
||||
}
|
||||
}
|
||||
|
||||
interface TreeNode {
|
||||
index: number;
|
||||
handle: TreeItemHandle;
|
||||
parent: TreeItemHandle;
|
||||
children: TreeItemHandle[];
|
||||
}
|
||||
|
||||
class ExtHostTreeView<T> extends Disposable {
|
||||
|
||||
private _itemHandlePool = 0;
|
||||
|
||||
private extElementsMap: Map<TreeItemHandle, T> = new Map<TreeItemHandle, T>();
|
||||
private itemHandlesMap: Map<T, TreeItemHandle> = new Map<T, TreeItemHandle>();
|
||||
private extChildrenElementsMap: Map<T, T[]> = new Map<T, T[]>();
|
||||
private static ROOT_HANDLE = '0';
|
||||
private elements: Map<TreeItemHandle, T> = new Map<TreeItemHandle, T>();
|
||||
private nodes: Map<T, TreeNode> = new Map<T, TreeNode>();
|
||||
|
||||
constructor(private viewId: string, private dataProvider: vscode.TreeDataProvider<T>, private proxy: MainThreadTreeViewsShape, private commands: CommandsConverter) {
|
||||
super();
|
||||
@@ -87,12 +90,9 @@ class ExtHostTreeView<T> extends Disposable {
|
||||
}
|
||||
|
||||
getTreeItems(): TPromise<ITreeItem[]> {
|
||||
this.extChildrenElementsMap.clear();
|
||||
this.extElementsMap.clear();
|
||||
this.itemHandlesMap.clear();
|
||||
|
||||
this.clearAll();
|
||||
return asWinJsPromise(() => this.dataProvider.getChildren())
|
||||
.then(elements => this.processAndMapElements(elements));
|
||||
.then(elements => this.resolveElements(elements));
|
||||
}
|
||||
|
||||
getChildren(treeItemHandle: TreeItemHandle): TPromise<ITreeItem[]> {
|
||||
@@ -104,77 +104,86 @@ class ExtHostTreeView<T> extends Disposable {
|
||||
}
|
||||
|
||||
return asWinJsPromise(() => this.dataProvider.getChildren(extElement))
|
||||
.then(childrenElements => this.processAndMapElements(childrenElements));
|
||||
.then(childrenElements => this.resolveElements(childrenElements, treeItemHandle))
|
||||
.then(childrenItems => {
|
||||
this.nodes.get(extElement).children = childrenItems.map(c => c.handle);
|
||||
return childrenItems;
|
||||
});
|
||||
}
|
||||
|
||||
getExtensionElement(treeItemHandle: TreeItemHandle): T {
|
||||
return this.extElementsMap.get(treeItemHandle);
|
||||
return this.elements.get(treeItemHandle);
|
||||
}
|
||||
|
||||
private _refresh(elements: T[]): void {
|
||||
const hasRoot = elements.some(element => !element);
|
||||
if (hasRoot) {
|
||||
this.proxy.$refresh(this.viewId, []);
|
||||
this.proxy.$refresh(this.viewId);
|
||||
} else {
|
||||
const itemHandles = distinct(elements.map(element => this.itemHandlesMap.get(element))
|
||||
.filter(itemHandle => !!itemHandle));
|
||||
if (itemHandles.length) {
|
||||
this.proxy.$refresh(this.viewId, itemHandles);
|
||||
const handlesToUpdate = this.getHandlesToUpdate(elements);
|
||||
if (handlesToUpdate.length) {
|
||||
this._refreshHandles(handlesToUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private processAndMapElements(elements: T[]): TPromise<ITreeItem[]> {
|
||||
private resolveElements(elements: T[], parentHandle?: TreeItemHandle): TPromise<ITreeItem[]> {
|
||||
if (elements && elements.length) {
|
||||
return TPromise.join(
|
||||
elements.filter(element => !!element)
|
||||
.map(element => {
|
||||
if (this.extChildrenElementsMap.has(element)) {
|
||||
return TPromise.wrapError<ITreeItem>(new Error(localize('treeView.duplicateElement', 'Element {0} is already registered', element)));
|
||||
}
|
||||
return this.resolveElement(element);
|
||||
.map((element, index) => {
|
||||
return this.resolveElement(element, index, parentHandle)
|
||||
.then(treeItem => {
|
||||
if (treeItem) {
|
||||
this.nodes.set(element, {
|
||||
index,
|
||||
handle: treeItem.handle,
|
||||
parent: parentHandle,
|
||||
children: void 0
|
||||
});
|
||||
if (this.elements.has(treeItem.handle)) {
|
||||
return TPromise.wrapError<ITreeItem>(new Error(localize('treeView.duplicateElement', 'Element {0} is already registered', element)));
|
||||
}
|
||||
this.elements.set(treeItem.handle, element);
|
||||
}
|
||||
return treeItem;
|
||||
});
|
||||
}))
|
||||
.then(treeItems => treeItems.filter(treeItem => !!treeItem));
|
||||
}
|
||||
return TPromise.as([]);
|
||||
}
|
||||
|
||||
private resolveElement(element: T): TPromise<ITreeItem> {
|
||||
private resolveElement(element: T, index: number, parentHandle?: TreeItemHandle): TPromise<ITreeItem> {
|
||||
return asWinJsPromise(() => this.dataProvider.getTreeItem(element))
|
||||
.then(extTreeItem => {
|
||||
const treeItem = this.massageTreeItem(extTreeItem);
|
||||
if (treeItem) {
|
||||
this.itemHandlesMap.set(element, treeItem.handle);
|
||||
this.extElementsMap.set(treeItem.handle, element);
|
||||
if (treeItem.collapsibleState === TreeItemCollapsibleState.Expanded) {
|
||||
return this.getChildren(treeItem.handle).then(children => {
|
||||
treeItem.children = children;
|
||||
return treeItem;
|
||||
});
|
||||
} else {
|
||||
return treeItem;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
.then(extTreeItem => this.massageTreeItem(element, extTreeItem, index, parentHandle));
|
||||
}
|
||||
|
||||
private massageTreeItem(extensionTreeItem: vscode.TreeItem): ITreeItem {
|
||||
private massageTreeItem(element: T, extensionTreeItem: vscode.TreeItem, index: number, parentHandle: TreeItemHandle): ITreeItem {
|
||||
if (!extensionTreeItem) {
|
||||
return null;
|
||||
}
|
||||
const icon = this.getLightIconPath(extensionTreeItem);
|
||||
const label = extensionTreeItem.label;
|
||||
const handle = typeof element === 'string' ? element : this.generateHandle(label, index, parentHandle);
|
||||
return {
|
||||
handle: ++this._itemHandlePool,
|
||||
label: extensionTreeItem.label,
|
||||
handle,
|
||||
parentHandle,
|
||||
label,
|
||||
command: extensionTreeItem.command ? this.commands.toInternal(extensionTreeItem.command) : void 0,
|
||||
contextValue: extensionTreeItem.contextValue,
|
||||
icon,
|
||||
iconDark: this.getDarkIconPath(extensionTreeItem) || icon,
|
||||
collapsibleState: extensionTreeItem.collapsibleState,
|
||||
collapsibleState: extensionTreeItem.collapsibleState
|
||||
};
|
||||
}
|
||||
|
||||
private generateHandle(label: string, index: number, parentHandle: TreeItemHandle): TreeItemHandle {
|
||||
parentHandle = parentHandle ? parentHandle : ExtHostTreeView.ROOT_HANDLE;
|
||||
label = label.indexOf('/') !== -1 ? label.replace('/', '//') : label;
|
||||
return `${parentHandle}/${index}:${label}`;
|
||||
}
|
||||
|
||||
private getLightIconPath(extensionTreeItem: vscode.TreeItem): string {
|
||||
if (extensionTreeItem.iconPath) {
|
||||
if (typeof extensionTreeItem.iconPath === 'string' || extensionTreeItem.iconPath instanceof URI) {
|
||||
@@ -199,29 +208,107 @@ class ExtHostTreeView<T> extends Disposable {
|
||||
return URI.file(iconPath).toString();
|
||||
}
|
||||
|
||||
private clearChildren(extElement: T): void {
|
||||
const children = this.extChildrenElementsMap.get(extElement);
|
||||
if (children) {
|
||||
for (const child of children) {
|
||||
this.clearElement(child);
|
||||
private getHandlesToUpdate(elements: T[]): TreeItemHandle[] {
|
||||
const elementsToUpdate = new Set<TreeItemHandle>();
|
||||
for (const element of elements) {
|
||||
let elementNode = this.nodes.get(element);
|
||||
if (elementNode && !elementsToUpdate.has(elementNode.handle)) {
|
||||
// check if an ancestor of extElement is already in the elements to update list
|
||||
let currentNode = elementNode;
|
||||
while (currentNode && currentNode.parent && !elementsToUpdate.has(currentNode.parent)) {
|
||||
const parentElement = this.elements.get(currentNode.parent);
|
||||
currentNode = this.nodes.get(parentElement);
|
||||
}
|
||||
if (!currentNode.parent) {
|
||||
elementsToUpdate.add(elementNode.handle);
|
||||
}
|
||||
}
|
||||
this.extChildrenElementsMap.delete(extElement);
|
||||
}
|
||||
|
||||
const handlesToUpdate: TreeItemHandle[] = [];
|
||||
// Take only top level elements
|
||||
elementsToUpdate.forEach((handle) => {
|
||||
const element = this.elements.get(handle);
|
||||
let node = this.nodes.get(element);
|
||||
if (node && !elementsToUpdate.has(node.parent)) {
|
||||
handlesToUpdate.push(handle);
|
||||
}
|
||||
});
|
||||
|
||||
return handlesToUpdate;
|
||||
}
|
||||
|
||||
private clearElement(extElement: T): void {
|
||||
this.clearChildren(extElement);
|
||||
private _refreshHandles(itemHandles: TreeItemHandle[]): TPromise<void> {
|
||||
const itemsToRefresh: { [handle: string]: ITreeItem } = {};
|
||||
const promises: TPromise<void>[] = [];
|
||||
itemHandles.forEach(treeItemHandle => {
|
||||
const extElement = this.getExtensionElement(treeItemHandle);
|
||||
const node = this.nodes.get(extElement);
|
||||
const promise = this.resolveElement(extElement, node.index, node.parent)
|
||||
.then(treeItem => {
|
||||
if (treeItemHandle !== treeItem.handle) {
|
||||
// Update caches if handle changes
|
||||
this.updateCaches(node, treeItem, extElement);
|
||||
}
|
||||
itemsToRefresh[treeItemHandle] = treeItem;
|
||||
});
|
||||
promises.push(promise);
|
||||
});
|
||||
return TPromise.join(promises)
|
||||
.then(treeItems => {
|
||||
this.proxy.$refresh(this.viewId, itemsToRefresh);
|
||||
});
|
||||
}
|
||||
|
||||
const treeItemhandle = this.itemHandlesMap.get(extElement);
|
||||
this.itemHandlesMap.delete(extElement);
|
||||
if (treeItemhandle) {
|
||||
this.extElementsMap.delete(treeItemhandle);
|
||||
private updateCaches(node: TreeNode, treeItem: ITreeItem, element: T): void {
|
||||
if (node.parent) {
|
||||
// Update parent's children handles
|
||||
const parentElement = this.getExtensionElement(node.parent);
|
||||
const parentNode = this.nodes.get(parentElement);
|
||||
parentNode.children[node.index] = treeItem.handle;
|
||||
}
|
||||
|
||||
// Update elements map
|
||||
this.elements.delete(node.handle);
|
||||
this.elements.set(treeItem.handle, element);
|
||||
|
||||
// Update node
|
||||
node.handle = treeItem.handle;
|
||||
}
|
||||
|
||||
private clearChildren(element: T): void {
|
||||
let node = this.nodes.get(element);
|
||||
if (node.children) {
|
||||
for (const childHandle of node.children) {
|
||||
const childEleement = this.elements.get(childHandle);
|
||||
if (childEleement) {
|
||||
this.clear(childEleement);
|
||||
}
|
||||
}
|
||||
}
|
||||
node.children = void 0;
|
||||
}
|
||||
|
||||
private clear(element: T): void {
|
||||
let node = this.nodes.get(element);
|
||||
if (node.children) {
|
||||
for (const childHandle of node.children) {
|
||||
const childEleement = this.elements.get(childHandle);
|
||||
if (childEleement) {
|
||||
this.clear(childEleement);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.nodes.delete(element);
|
||||
this.elements.delete(node.handle);
|
||||
}
|
||||
|
||||
private clearAll(): void {
|
||||
this.elements.clear();
|
||||
this.nodes.clear();
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.extElementsMap.clear();
|
||||
this.itemHandlesMap.clear();
|
||||
this.extChildrenElementsMap.clear();
|
||||
this.clearAll();
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import * as types from './extHostTypes';
|
||||
import { Position as EditorPosition } from 'vs/platform/editor/common/editor';
|
||||
import { Position as EditorPosition, ITextEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { IDecorationOptions, EndOfLineSequence } from 'vs/editor/common/editorCommon';
|
||||
import * as vscode from 'vscode';
|
||||
import URI from 'vs/base/common/uri';
|
||||
@@ -17,6 +17,8 @@ import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { ISelection } from 'vs/editor/common/core/selection';
|
||||
import * as htmlContent from 'vs/base/common/htmlContent';
|
||||
import { IRelativePattern } from 'vs/base/common/glob';
|
||||
import { LanguageSelector, LanguageFilter } from 'vs/editor/common/modes/languageSelector';
|
||||
|
||||
export interface PositionLike {
|
||||
line: number;
|
||||
@@ -223,6 +225,43 @@ export const TextEdit = {
|
||||
}
|
||||
};
|
||||
|
||||
export namespace WorkspaceEdit {
|
||||
export function from(value: vscode.WorkspaceEdit): modes.WorkspaceEdit {
|
||||
const result: modes.WorkspaceEdit = { edits: [] };
|
||||
for (let entry of value.entries()) {
|
||||
let [uri, textEdits] = entry;
|
||||
for (let textEdit of textEdits) {
|
||||
result.edits.push({
|
||||
resource: uri,
|
||||
newText: textEdit.newText,
|
||||
range: fromRange(textEdit.range)
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function fromTextEdits(uri: vscode.Uri, textEdits: vscode.TextEdit[]): modes.WorkspaceEdit {
|
||||
const result: modes.WorkspaceEdit = { edits: [] };
|
||||
for (let textEdit of textEdits) {
|
||||
result.edits.push({
|
||||
resource: uri,
|
||||
newText: textEdit.newText,
|
||||
range: fromRange(textEdit.range)
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function to(value: modes.WorkspaceEdit) {
|
||||
const result = new types.WorkspaceEdit();
|
||||
for (const edit of value.edits) {
|
||||
result.replace(edit.resource, toRange(edit.range), edit.newText);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export namespace SymbolKind {
|
||||
|
||||
@@ -385,7 +424,8 @@ export namespace Suggest {
|
||||
result.insertText = suggestion.insertText;
|
||||
result.kind = CompletionItemKind.to(suggestion.type);
|
||||
result.detail = suggestion.detail;
|
||||
result.documentation = <string>suggestion.documentation; // htmlContent.isMarkdownString(suggestion.documentation) ? MarkdownString.to(suggestion.documentation) : suggestion.documentation;
|
||||
// {{SQL CARBON EDIT}}
|
||||
result.documentation = <string>suggestion.documentation;
|
||||
result.sortText = suggestion.sortText;
|
||||
result.filterText = suggestion.filterText;
|
||||
|
||||
@@ -410,7 +450,7 @@ export namespace Suggest {
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export namespace ParameterInformation {
|
||||
export function from(info: types.ParameterInformation): modes.ParameterInformation {
|
||||
@@ -543,3 +583,53 @@ export namespace ProgressLocation {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function toTextEditorOptions(options?: vscode.TextDocumentShowOptions): ITextEditorOptions {
|
||||
if (options) {
|
||||
return {
|
||||
pinned: typeof options.preview === 'boolean' ? !options.preview : undefined,
|
||||
preserveFocus: options.preserveFocus,
|
||||
selection: typeof options.selection === 'object' ? fromRange(options.selection) : undefined
|
||||
} as ITextEditorOptions;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function toGlobPattern(pattern: vscode.GlobPattern): string | IRelativePattern {
|
||||
if (typeof pattern === 'string') {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
if (!isRelativePattern(pattern)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return new types.RelativePattern(pattern.base, pattern.pattern);
|
||||
}
|
||||
|
||||
function isRelativePattern(obj: any): obj is vscode.RelativePattern {
|
||||
const rp = obj as vscode.RelativePattern;
|
||||
|
||||
return rp && typeof rp.base === 'string' && typeof rp.pattern === 'string';
|
||||
}
|
||||
|
||||
export function toLanguageSelector(selector: vscode.DocumentSelector): LanguageSelector {
|
||||
if (Array.isArray(selector)) {
|
||||
return selector.map(sel => doToLanguageSelector(sel));
|
||||
}
|
||||
|
||||
return doToLanguageSelector(selector);
|
||||
}
|
||||
|
||||
function doToLanguageSelector(selector: string | vscode.DocumentFilter): string | LanguageFilter {
|
||||
if (typeof selector === 'string') {
|
||||
return selector;
|
||||
}
|
||||
|
||||
return {
|
||||
language: selector.language,
|
||||
scheme: selector.scheme,
|
||||
pattern: toGlobPattern(selector.pattern)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { illegalArgument } from 'vs/base/common/errors';
|
||||
import * as vscode from 'vscode';
|
||||
import { isMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { IRelativePattern } from 'vs/base/common/glob';
|
||||
import { relative } from 'path';
|
||||
|
||||
export class Disposable {
|
||||
|
||||
@@ -808,6 +809,21 @@ export class SymbolInformation {
|
||||
}
|
||||
}
|
||||
|
||||
export class CodeAction {
|
||||
title: string;
|
||||
|
||||
command?: vscode.Command;
|
||||
|
||||
edits?: TextEdit[] | WorkspaceEdit;
|
||||
|
||||
dianostics?: Diagnostic[];
|
||||
|
||||
constructor(title: string, edits?: TextEdit[] | WorkspaceEdit) {
|
||||
this.title = title;
|
||||
this.edits = edits;
|
||||
}
|
||||
}
|
||||
|
||||
export class CodeLens {
|
||||
|
||||
range: Range;
|
||||
@@ -889,6 +905,11 @@ export class SignatureHelp {
|
||||
}
|
||||
}
|
||||
|
||||
export enum CodeActionType {
|
||||
QuickFix = 1,
|
||||
Refactoring = 2
|
||||
}
|
||||
|
||||
export enum CompletionTriggerKind {
|
||||
Invoke = 0,
|
||||
TriggerCharacter = 1
|
||||
@@ -1132,7 +1153,6 @@ export enum TaskPanelKind {
|
||||
export class TaskGroup implements vscode.TaskGroup {
|
||||
|
||||
private _id: string;
|
||||
private _label: string;
|
||||
|
||||
public static Clean: TaskGroup = new TaskGroup('clean', 'Clean');
|
||||
|
||||
@@ -1142,15 +1162,14 @@ export class TaskGroup implements vscode.TaskGroup {
|
||||
|
||||
public static Test: TaskGroup = new TaskGroup('test', 'Test');
|
||||
|
||||
constructor(id: string, label: string) {
|
||||
constructor(id: string, _label: string) {
|
||||
if (typeof id !== 'string') {
|
||||
throw illegalArgument('name');
|
||||
}
|
||||
if (typeof label !== 'string') {
|
||||
if (typeof _label !== 'string') {
|
||||
throw illegalArgument('name');
|
||||
}
|
||||
this._id = id;
|
||||
this._label = label;
|
||||
}
|
||||
|
||||
get id(): string {
|
||||
@@ -1475,4 +1494,41 @@ export class RelativePattern implements IRelativePattern {
|
||||
this.base = typeof base === 'string' ? base : base.uri.fsPath;
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
public pathToRelative(from: string, to: string): string {
|
||||
return relative(from, to);
|
||||
}
|
||||
}
|
||||
|
||||
export class Breakpoint {
|
||||
|
||||
readonly enabled: boolean;
|
||||
readonly condition?: string;
|
||||
readonly hitCondition?: string;
|
||||
|
||||
protected constructor(enabled: boolean, condition: string, hitCondition: string) {
|
||||
this.enabled = enabled;
|
||||
this.condition = condition;
|
||||
this.hitCondition = hitCondition;
|
||||
this.condition = condition;
|
||||
this.hitCondition = hitCondition;
|
||||
}
|
||||
}
|
||||
|
||||
export class SourceBreakpoint extends Breakpoint {
|
||||
readonly location: Location;
|
||||
|
||||
constructor(enabled: boolean, condition: string, hitCondition: string, location: Location) {
|
||||
super(enabled, condition, hitCondition);
|
||||
this.location = location;
|
||||
}
|
||||
}
|
||||
|
||||
export class FunctionBreakpoint extends Breakpoint {
|
||||
readonly functionName: string;
|
||||
|
||||
constructor(enabled: boolean, condition: string, hitCondition: string, functionName: string) {
|
||||
super(enabled, condition, hitCondition);
|
||||
this.functionName = functionName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import { IWorkspaceData, ExtHostWorkspaceShape, MainContext, MainThreadWorkspace
|
||||
import * as vscode from 'vscode';
|
||||
import { compare } from 'vs/base/common/strings';
|
||||
import { TernarySearchTree } from 'vs/base/common/map';
|
||||
import { IRelativePattern } from 'vs/base/common/glob';
|
||||
|
||||
class Workspace2 extends Workspace {
|
||||
|
||||
@@ -156,9 +155,30 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
|
||||
// --- search ---
|
||||
|
||||
findFiles(include: string | IRelativePattern, exclude: string | IRelativePattern, maxResults?: number, token?: vscode.CancellationToken): Thenable<vscode.Uri[]> {
|
||||
findFiles(include: vscode.GlobPattern, exclude: vscode.GlobPattern, maxResults?: number, token?: vscode.CancellationToken): Thenable<vscode.Uri[]> {
|
||||
const requestId = ExtHostWorkspace._requestIdPool++;
|
||||
const result = this._proxy.$startSearch(include, exclude, maxResults, requestId);
|
||||
|
||||
let includePattern: string;
|
||||
let includeFolder: string;
|
||||
if (include) {
|
||||
if (typeof include === 'string') {
|
||||
includePattern = include;
|
||||
} else {
|
||||
includePattern = include.pattern;
|
||||
includeFolder = include.base;
|
||||
}
|
||||
}
|
||||
|
||||
let excludePattern: string;
|
||||
if (exclude) {
|
||||
if (typeof exclude === 'string') {
|
||||
excludePattern = exclude;
|
||||
} else {
|
||||
excludePattern = exclude.pattern;
|
||||
}
|
||||
}
|
||||
|
||||
const result = this._proxy.$startSearch(includePattern, includeFolder, excludePattern, maxResults, requestId);
|
||||
if (token) {
|
||||
token.onCancellationRequested(() => this._proxy.$cancelSearch(requestId));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user