Merge from vscode 2b0b9136329c181a9e381463a1f7dc3a2d105a34 (#4880)

This commit is contained in:
Karl Burtram
2019-04-05 10:09:18 -07:00
committed by GitHub
parent 9bd7e30d18
commit cb5bcf2248
433 changed files with 8915 additions and 8361 deletions

View File

@@ -11,9 +11,9 @@ import { ITextEditorOptions } from 'vs/platform/editor/common/editor';
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import { EditorGroupLayout } from 'vs/workbench/services/editor/common/editorGroupsService';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IWindowsService, IOpenSettings } from 'vs/platform/windows/common/windows';
import { IWindowsService, IOpenSettings, IURIToOpen } from 'vs/platform/windows/common/windows';
import { IDownloadService } from 'vs/platform/download/common/download';
import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspacesService, hasWorkspaceFileExtension } from 'vs/platform/workspaces/common/workspaces';
import { IRecent } from 'vs/platform/history/common/history';
// -----------------------------------------------------------------
@@ -51,7 +51,8 @@ export class OpenFolderAPICommand {
}
const options: IOpenSettings = { forceNewWindow: arg.forceNewWindow, noRecentEntry: arg.noRecentEntry };
uri = URI.revive(uri);
return executor.executeCommand('_files.windowOpen', [{ uri }], options);
const uriToOpen: IURIToOpen = hasWorkspaceFileExtension(uri.path) ? { workspaceUri: uri } : { folderUri: uri };
return executor.executeCommand('_files.windowOpen', [uriToOpen], options);
}
}
CommandsRegistry.registerCommand({

View File

@@ -19,7 +19,7 @@ import { score } from 'vs/editor/common/modes/languageSelector';
import * as files from 'vs/platform/files/common/files';
import pkg from 'vs/platform/product/node/package';
import product from 'vs/platform/product/node/product';
import { ExtHostContext, IInitData, IMainContext, MainContext } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostContext, IInitData, IMainContext, MainContext, MainThreadKeytarShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostApiCommands } from 'vs/workbench/api/node/extHostApiCommands';
import { ExtHostClipboard } from 'vs/workbench/api/node/extHostClipboard';
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
@@ -237,6 +237,7 @@ export function createApiFactory(
get language() { return platform.language!; },
get appName() { return product.nameLong; },
get appRoot() { return initData.environment.appRoot!.fsPath; },
get uriScheme() { return product.urlProtocol; },
get logLevel() {
checkProposedApiEnabled(extension);
return typeConverters.LogLevel.to(extHostLogService.getLevel());
@@ -883,41 +884,105 @@ class Extension<T> implements vscode.Extension<T> {
}
}
export function initializeExtensionApi(extensionService: ExtHostExtensionService, apiFactory: IExtensionApiFactory, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): Promise<void> {
return extensionService.getExtensionPathIndex().then(trie => defineAPI(apiFactory, trie, extensionRegistry, configProvider));
interface INodeModuleFactory {
readonly nodeModuleName: string;
load(request: string, parent: { filename: string; }): any;
}
function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchTree<IExtensionDescription>, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): void {
export class NodeModuleRequireInterceptor {
public static INSTANCE = new NodeModuleRequireInterceptor();
// each extension is meant to get its own api implementation
const extApiImpl = new Map<string, typeof vscode>();
let defaultApiImpl: typeof vscode;
private readonly _factories: Map<string, INodeModuleFactory>;
const node_module = <any>require.__$__nodeRequire('module');
const original = node_module._load;
node_module._load = function load(request: string, parent: any, isMain: any) {
if (request !== 'vscode') {
return original.apply(this, arguments);
}
constructor() {
this._factories = new Map<string, INodeModuleFactory>();
this._installInterceptor(this._factories);
}
private _installInterceptor(factories: Map<string, INodeModuleFactory>): void {
const node_module = <any>require.__$__nodeRequire('module');
const original = node_module._load;
node_module._load = function load(request: string, parent: { filename: string; }, isMain: any) {
if (!factories.has(request)) {
return original.apply(this, arguments);
}
return factories.get(request)!.load(request, parent);
};
}
public register(interceptor: INodeModuleFactory): void {
this._factories.set(interceptor.nodeModuleName, interceptor);
}
}
export class VSCodeNodeModuleFactory implements INodeModuleFactory {
public readonly nodeModuleName = 'vscode';
private readonly _extApiImpl = new Map<string, typeof vscode>();
private _defaultApiImpl: typeof vscode;
constructor(
private readonly _apiFactory: IExtensionApiFactory,
private readonly _extensionPaths: TernarySearchTree<IExtensionDescription>,
private readonly _extensionRegistry: ExtensionDescriptionRegistry,
private readonly _configProvider: ExtHostConfigProvider
) {
}
public load(request: string, parent: { filename: string; }): any {
// get extension id from filename and api for extension
const ext = extensionPaths.findSubstr(URI.file(parent.filename).fsPath);
const ext = this._extensionPaths.findSubstr(URI.file(parent.filename).fsPath);
if (ext) {
let apiImpl = extApiImpl.get(ExtensionIdentifier.toKey(ext.identifier));
let apiImpl = this._extApiImpl.get(ExtensionIdentifier.toKey(ext.identifier));
if (!apiImpl) {
apiImpl = factory(ext, extensionRegistry, configProvider);
extApiImpl.set(ExtensionIdentifier.toKey(ext.identifier), apiImpl);
apiImpl = this._apiFactory(ext, this._extensionRegistry, this._configProvider);
this._extApiImpl.set(ExtensionIdentifier.toKey(ext.identifier), apiImpl);
}
return apiImpl;
}
// fall back to a default implementation
if (!defaultApiImpl) {
if (!this._defaultApiImpl) {
let extensionPathsPretty = '';
extensionPaths.forEach((value, index) => extensionPathsPretty += `\t${index} -> ${value.identifier.value}\n`);
this._extensionPaths.forEach((value, index) => extensionPathsPretty += `\t${index} -> ${value.identifier.value}\n`);
console.warn(`Could not identify extension for 'vscode' require call from ${parent.filename}. These are the extension path mappings: \n${extensionPathsPretty}`);
defaultApiImpl = factory(nullExtensionDescription, extensionRegistry, configProvider);
this._defaultApiImpl = this._apiFactory(nullExtensionDescription, this._extensionRegistry, this._configProvider);
}
return defaultApiImpl;
};
return this._defaultApiImpl;
}
}
interface IKeytarModule {
getPassword(service: string, account: string): Promise<string | null>;
setPassword(service: string, account: string, password: string): Promise<void>;
deletePassword(service: string, account: string): Promise<boolean>;
findPassword(service: string): Promise<string | null>;
}
export class KeytarNodeModuleFactory implements INodeModuleFactory {
public readonly nodeModuleName = 'keytar';
private _impl: IKeytarModule;
constructor(mainThreadKeytar: MainThreadKeytarShape) {
this._impl = {
getPassword: (service: string, account: string): Promise<string | null> => {
return mainThreadKeytar.$getPassword(service, account);
},
setPassword: (service: string, account: string, password: string): Promise<void> => {
return mainThreadKeytar.$setPassword(service, account, password);
},
deletePassword: (service: string, account: string): Promise<boolean> => {
return mainThreadKeytar.$deletePassword(service, account);
},
findPassword: (service: string): Promise<string | null> => {
return mainThreadKeytar.$findPassword(service);
}
};
}
public load(request: string, parent: { filename: string; }): any {
return this._impl;
}
}

View File

@@ -7,7 +7,7 @@ import { generateRandomPipeName } from 'vs/base/parts/ipc/node/ipc.net';
import * as http from 'http';
import * as fs from 'fs';
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
import { IURIToOpen, URIType, IOpenSettings } from 'vs/platform/windows/common/windows';
import { IURIToOpen, IOpenSettings } from 'vs/platform/windows/common/windows';
import { URI } from 'vs/base/common/uri';
import { hasWorkspaceFileExtension } from 'vs/platform/workspaces/common/workspaces';
@@ -55,17 +55,6 @@ export class CLIServer {
return this._ipcHandlePath;
}
private collectURIToOpen(strs: string[] | undefined, typeHint: URIType, result: IURIToOpen[]): void {
if (Array.isArray(strs)) {
for (const s of strs) {
try {
result.push({ uri: URI.parse(s), typeHint });
} catch (e) {
// ignore
}
}
}
}
private onRequest(req: http.IncomingMessage, res: http.ServerResponse): void {
const chunks: string[] = [];
@@ -95,13 +84,32 @@ export class CLIServer {
private open(data: OpenCommandPipeArgs, res: http.ServerResponse) {
let { fileURIs, folderURIs, forceNewWindow, diffMode, addMode, forceReuseWindow, waitMarkerFilePath } = data;
if (folderURIs && folderURIs.length || fileURIs && fileURIs.length) {
const urisToOpen: IURIToOpen[] = [];
this.collectURIToOpen(folderURIs, 'folder', urisToOpen);
this.collectURIToOpen(fileURIs, 'file', urisToOpen);
if (!forceReuseWindow && urisToOpen.some(o => o.typeHint === 'folder' || (o.typeHint === 'file' && hasWorkspaceFileExtension(o.uri.path)))) {
forceNewWindow = true;
const urisToOpen: IURIToOpen[] = [];
if (Array.isArray(folderURIs)) {
for (const s of folderURIs) {
try {
urisToOpen.push({ folderUri: URI.parse(s) });
forceNewWindow = true;
} catch (e) {
// ignore
}
}
}
if (Array.isArray(fileURIs)) {
for (const s of fileURIs) {
try {
if (hasWorkspaceFileExtension(s)) {
urisToOpen.push({ workspaceUri: URI.parse(s) });
forceNewWindow = true;
} else {
urisToOpen.push({ fileUri: URI.parse(s) });
}
} catch (e) {
// ignore
}
}
}
if (urisToOpen.length) {
const waitMarkerFileURI = waitMarkerFilePath ? URI.file(waitMarkerFilePath) : undefined;
const windowOpenArgs: IOpenSettings = { forceNewWindow, diffMode, addMode, forceReuseWindow, waitMarkerFileURI };
this._commands.executeCommand('_files.windowOpen', urisToOpen, windowOpenArgs);

View File

@@ -16,6 +16,7 @@ import { IRange } from 'vs/editor/common/core/range';
import { CancellationToken } from 'vs/base/common/cancellation';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { Event, Emitter } from 'vs/base/common/event';
import { debounce } from 'vs/base/common/decorators';
interface HandlerData<T> {
@@ -360,10 +361,13 @@ export class ExtHostCommentThread implements vscode.CommentThread {
return this._resource;
}
private _onDidUpdateCommentThread = new Emitter<void>();
readonly onDidUpdateCommentThread = this._onDidUpdateCommentThread.event;
set range(range: vscode.Range) {
if (range.isEqual(this._range)) {
this._range = range;
this._proxy.$updateCommentThreadRange(this._commentController.handle, this.handle, extHostTypeConverter.Range.from(this._range));
this._onDidUpdateCommentThread.fire();
}
}
@@ -379,7 +383,7 @@ export class ExtHostCommentThread implements vscode.CommentThread {
set label(label: string) {
this._label = label;
this._proxy.$updateCommentThreadLabel(this._commentController.handle, this.handle, this._label);
this._onDidUpdateCommentThread.fire();
}
get comments(): vscode.Comment[] {
@@ -387,8 +391,8 @@ export class ExtHostCommentThread implements vscode.CommentThread {
}
set comments(newComments: vscode.Comment[]) {
this._proxy.$updateComments(this._commentController.handle, this.handle, newComments.map(cmt => { return convertToModeComment(this._commentController, cmt, this._commandsConverter); }));
this._comments = newComments;
this._onDidUpdateCommentThread.fire();
}
private _acceptInputCommand: vscode.Command;
@@ -398,9 +402,7 @@ export class ExtHostCommentThread implements vscode.CommentThread {
set acceptInputCommand(acceptInputCommand: vscode.Command) {
this._acceptInputCommand = acceptInputCommand;
const internal = this._commandsConverter.toInternal(acceptInputCommand);
this._proxy.$updateCommentThreadAcceptInputCommand(this._commentController.handle, this.handle, internal);
this._onDidUpdateCommentThread.fire();
}
private _additionalCommands: vscode.Command[] = [];
@@ -410,9 +412,7 @@ export class ExtHostCommentThread implements vscode.CommentThread {
set additionalCommands(additionalCommands: vscode.Command[]) {
this._additionalCommands = additionalCommands;
const internals = additionalCommands.map(x => this._commandsConverter.toInternal(x));
this._proxy.$updateCommentThreadAdditionalCommands(this._commentController.handle, this.handle, internals);
this._onDidUpdateCommentThread.fire();
}
private _deleteCommand?: vscode.Command;
@@ -422,9 +422,7 @@ export class ExtHostCommentThread implements vscode.CommentThread {
set deleteCommand(deleteCommand: vscode.Command) {
this._deleteCommand = deleteCommand;
const internal = this._commandsConverter.toInternal(deleteCommand);
this._proxy.$updateCommentThreadDeleteCommand(this._commentController.handle, this.handle, internal);
this._onDidUpdateCommentThread.fire();
}
private _collapseState?: vscode.CommentThreadCollapsibleState;
@@ -435,9 +433,11 @@ export class ExtHostCommentThread implements vscode.CommentThread {
set collapsibleState(newState: vscode.CommentThreadCollapsibleState) {
this._collapseState = newState;
this._proxy.$updateCommentThreadCollapsibleState(this._commentController.handle, this.handle, convertToCollapsibleState(newState));
this._onDidUpdateCommentThread.fire();
}
private _localDisposables: types.Disposable[];
constructor(
private _proxy: MainThreadCommentsShape,
private readonly _commandsConverter: CommandsConverter,
@@ -452,12 +452,41 @@ export class ExtHostCommentThread implements vscode.CommentThread {
this.handle,
this._threadId,
this._resource,
extHostTypeConverter.Range.from(this._range),
this._comments.map(comment => { return convertToModeComment(this._commentController, comment, this._commandsConverter); }),
this._acceptInputCommand ? this._commandsConverter.toInternal(this._acceptInputCommand) : undefined,
this._additionalCommands ? this._additionalCommands.map(x => this._commandsConverter.toInternal(x)) : [],
this._deleteCommand ? this._commandsConverter.toInternal(this._deleteCommand) : undefined,
this._collapseState!
extHostTypeConverter.Range.from(this._range)
);
this._localDisposables = [];
this._localDisposables.push(this.onDidUpdateCommentThread(() => {
this.eventuallyUpdateCommentThread();
}));
// set up comments after ctor to batch update events.
this.comments = _comments;
}
@debounce(100)
eventuallyUpdateCommentThread(): void {
const commentThreadRange = extHostTypeConverter.Range.from(this._range);
const label = this.label;
const comments = this._comments.map(cmt => { return convertToModeComment(this._commentController, cmt, this._commandsConverter); });
const acceptInputCommand = this._acceptInputCommand ? this._commandsConverter.toInternal(this._acceptInputCommand) : undefined;
const additionalCommands = this._additionalCommands ? this._additionalCommands.map(x => this._commandsConverter.toInternal(x)) : [];
const deleteCommand = this._deleteCommand ? this._commandsConverter.toInternal(this._deleteCommand) : undefined;
const collapsibleState = convertToCollapsibleState(this._collapseState);
this._proxy.$updateCommentThread(
this._commentController.handle,
this.handle,
this._threadId,
this._resource,
commentThreadRange,
label,
comments,
acceptInputCommand,
additionalCommands,
deleteCommand,
collapsibleState
);
}
@@ -472,6 +501,7 @@ export class ExtHostCommentThread implements vscode.CommentThread {
}
dispose() {
this._localDisposables.forEach(disposable => disposable.dispose());
this._proxy.$deleteCommentThread(
this._commentController.handle,
this.handle
@@ -607,7 +637,7 @@ function convertFromCommentThread(commentThread: modes.CommentThread): vscode.Co
threadId: commentThread.threadId!,
resource: URI.parse(commentThread.resource!),
range: extHostTypeConverter.Range.to(commentThread.range),
comments: commentThread.comments.map(convertFromComment),
comments: commentThread.comments ? commentThread.comments.map(convertFromComment) : [],
collapsibleState: commentThread.collapsibleState
};
}

View File

@@ -15,6 +15,8 @@ import { URI } from 'vs/base/common/uri';
import * as pfs from 'vs/base/node/pfs';
import { ILogService } from 'vs/platform/log/common/log';
// {{SQL CARBON EDIT}} - Remove createApiFactory initializeExtensionApi, and IExtensionApiFactory imports
//import { createApiFactory, IExtensionApiFactory, NodeModuleRequireInterceptor, VSCodeNodeModuleFactory } from 'vs/workbench/api/node/extHost.api.impl';
import { NodeModuleRequireInterceptor, VSCodeNodeModuleFactory, KeytarNodeModuleFactory } from 'vs/workbench/api/node/extHost.api.impl';
import { ExtHostExtensionServiceShape, IEnvironment, IInitData, IMainContext, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IStaticWorkspaceData } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration';
import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionMemento, IExtensionModule, HostExtension } from 'vs/workbench/api/node/extHostExtensionActivator';
@@ -32,6 +34,7 @@ import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensio
import { IWorkspace } from 'vs/platform/workspace/common/workspace';
import { Schemas } from 'vs/base/common/network';
import { withNullAsUndefined } from 'vs/base/common/types';
import { realpath } from 'vs/base/node/extpath';
class ExtensionMemento implements IExtensionMemento {
@@ -243,7 +246,13 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
private async _initialize(): Promise<void> {
try {
const configProvider = await this._extHostConfiguration.getConfigProvider();
// {{SQL CARBON EDIT}} - disable VSCodeNodeModuleFactory and use older initializeExtensionApi
// const extensionPaths = await this.getExtensionPathIndex();
// NodeModuleRequireInterceptor.INSTANCE.register(new VSCodeNodeModuleFactory(this._extensionApiFactory, extensionPaths, this._registry, configProvider));
await initializeExtensionApi(this, this._extensionApiFactory, this._registry, configProvider);
NodeModuleRequireInterceptor.INSTANCE.register(new KeytarNodeModuleFactory(this._extHostContext.getProxy(MainContext.MainThreadKeytar)));
// Do this when extension service exists, but extensions are not being activated yet.
await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._extHostLogService, this._mainThreadTelemetryProxy);
this._almostReadyToRunExtensions.open();
@@ -318,7 +327,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
if (!ext.main) {
return undefined;
}
return pfs.realpath(ext.extensionLocation.fsPath).then(value => tree.set(URI.file(value).fsPath, ext));
return realpath(ext.extensionLocation.fsPath).then(value => tree.set(URI.file(value).fsPath, ext));
});
this._extensionPathIndex = Promise.all(extensions).then(() => tree);
}
@@ -735,13 +744,13 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
if (!extensionDescription) {
return;
}
const realpath = await pfs.realpath(extensionDescription.extensionLocation.fsPath);
trie.delete(URI.file(realpath).fsPath);
const realpathValue = await realpath(extensionDescription.extensionLocation.fsPath);
trie.delete(URI.file(realpathValue).fsPath);
}));
await Promise.all(toAdd.map(async (extensionDescription) => {
const realpath = await pfs.realpath(extensionDescription.extensionLocation.fsPath);
trie.set(URI.file(realpath).fsPath, extensionDescription);
const realpathValue = await realpath(extensionDescription.extensionLocation.fsPath);
trie.set(URI.file(realpathValue).fsPath, extensionDescription);
}));
this._registry.deltaExtensions(toAdd, toRemove);

View File

@@ -15,7 +15,7 @@ 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 { asPromise } from 'vs/base/common/async';
import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IMainContext, IdObject, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, ISerializedLanguageConfiguration, WorkspaceSymbolDto, SuggestResultDto, WorkspaceSymbolsDto, SuggestionDto, CodeActionDto, ISerializedDocumentFilter, WorkspaceEditDto, ISerializedSignatureHelpProviderMetadata, LinkDto, CodeLensDto, MainThreadWebviewsShape, CodeInsetDto } from '../common/extHost.protocol';
import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IMainContext, IdObject, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, ISerializedLanguageConfiguration, WorkspaceSymbolDto, SuggestResultDto, WorkspaceSymbolsDto, CodeActionDto, ISerializedDocumentFilter, WorkspaceEditDto, ISerializedSignatureHelpProviderMetadata, LinkDto, CodeLensDto, MainThreadWebviewsShape, CodeInsetDto, SuggestDataDto } from '../common/extHost.protocol';
import { regExpLeadsToEndlessLoop, regExpFlags } from 'vs/base/common/strings';
import { IPosition } from 'vs/editor/common/core/position';
import { IRange, Range as EditorRange } from 'vs/editor/common/core/range';
@@ -129,7 +129,7 @@ class CodeLensAdapter {
});
}
resolveCodeLens(resource: URI, symbol: CodeLensDto, token: CancellationToken): Promise<CodeLensDto | undefined> {
resolveCodeLens(symbol: CodeLensDto, token: CancellationToken): Promise<CodeLensDto | undefined> {
const lens = this._heapService.get<vscode.CodeLens>(ObjectIdentifier.of(symbol));
if (!lens) {
@@ -637,15 +637,18 @@ class SuggestAdapter {
const doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position);
return asPromise<vscode.CompletionItem[] | vscode.CompletionList | null | undefined>(
() => this._provider.provideCompletionItems(doc, pos, token, typeConvert.CompletionContext.to(context))
).then(value => {
return asPromise(() => this._provider.provideCompletionItems(doc, pos, token, typeConvert.CompletionContext.to(context))).then(value => {
const _id = this._idPool++;
// the default text edit range
const wordRangeBeforePos = (doc.getWordRangeAtPosition(pos) as Range || new Range(pos, pos))
.with({ end: pos });
const result: SuggestResultDto = {
_id,
suggestions: [],
x: _id,
b: [],
a: typeConvert.Range.from(wordRangeBeforePos),
};
let list: CompletionList;
@@ -658,54 +661,45 @@ class SuggestAdapter {
} else {
list = value;
result.incomplete = list.isIncomplete;
result.c = list.isIncomplete;
}
// the default text edit range
const wordRangeBeforePos = (doc.getWordRangeAtPosition(pos) as Range || new Range(pos, pos))
.with({ end: pos });
for (let i = 0; i < list.items.length; i++) {
const suggestion = this._convertCompletionItem(list.items[i], pos, wordRangeBeforePos, i, _id);
const suggestion = this._convertCompletionItem2(list.items[i], pos, i, _id);
// check for bad completion item
// for the converter did warn
if (suggestion) {
result.suggestions.push(suggestion);
result.b.push(suggestion);
}
}
this._cache.set(_id, list.items);
if (SuggestAdapter.supportsResolving(this._provider)) {
this._cache.set(_id, list.items);
}
return result;
});
}
resolveCompletionItem(resource: URI, position: IPosition, suggestion: modes.CompletionItem, token: CancellationToken): Promise<modes.CompletionItem> {
resolveCompletionItem(_resource: URI, position: IPosition, id: number, pid: number, token: CancellationToken): Promise<SuggestDataDto | undefined> {
if (typeof this._provider.resolveCompletionItem !== 'function') {
return Promise.resolve(suggestion);
return Promise.resolve(undefined);
}
const { _parentId, _id } = (<SuggestionDto>suggestion);
const item = this._cache.has(_parentId) ? this._cache.get(_parentId)![_id] : undefined;
const item = this._cache.has(pid) ? this._cache.get(pid)![id] : undefined;
if (!item) {
return Promise.resolve(suggestion);
return Promise.resolve(undefined);
}
return asPromise(() => this._provider.resolveCompletionItem!(item, token)).then(resolvedItem => {
if (!resolvedItem) {
return suggestion;
return undefined;
}
const doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position);
const wordRangeBeforePos = (doc.getWordRangeAtPosition(pos) as Range || new Range(pos, pos)).with({ end: pos });
const newSuggestion = this._convertCompletionItem(resolvedItem, pos, wordRangeBeforePos, _id, _parentId);
if (newSuggestion) {
mixin(suggestion, newSuggestion, true);
}
return suggestion;
return this._convertCompletionItem2(resolvedItem, pos, id, pid);
});
}
@@ -713,60 +707,52 @@ class SuggestAdapter {
this._cache.delete(id);
}
private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, defaultRange: vscode.Range, _id: number, _parentId: number): SuggestionDto | undefined {
private _convertCompletionItem2(item: vscode.CompletionItem, position: vscode.Position, id: number, pid: number): SuggestDataDto | undefined {
if (typeof item.label !== 'string' || item.label.length === 0) {
console.warn('INVALID text edit -> must have at least a label');
return undefined;
}
const result: SuggestionDto = {
const result: SuggestDataDto = {
//
_id,
_parentId,
x: id,
y: pid,
//
label: item.label,
kind: typeConvert.CompletionItemKind.from(item.kind),
detail: item.detail,
documentation: typeof item.documentation === 'undefined' ? undefined : typeConvert.MarkdownString.fromStrict(item.documentation),
filterText: item.filterText,
sortText: item.sortText,
preselect: item.preselect,
//
range: undefined!, // populated below
insertText: undefined!, // populated below
insertTextRules: item.keepWhitespace ? modes.CompletionItemInsertTextRule.KeepWhitespace : 0,
additionalTextEdits: item.additionalTextEdits && item.additionalTextEdits.map(typeConvert.TextEdit.from),
command: this._commands.toInternal(item.command),
commitCharacters: item.commitCharacters
a: item.label,
b: typeConvert.CompletionItemKind.from(item.kind),
c: item.detail,
d: typeof item.documentation === 'undefined' ? undefined : typeConvert.MarkdownString.fromStrict(item.documentation),
e: item.sortText,
f: item.filterText,
g: item.preselect,
i: item.keepWhitespace ? modes.CompletionItemInsertTextRule.KeepWhitespace : 0,
k: item.commitCharacters,
l: item.additionalTextEdits && item.additionalTextEdits.map(typeConvert.TextEdit.from),
m: this._commands.toInternal(item.command),
};
// 'insertText'-logic
if (item.textEdit) {
result.insertText = item.textEdit.newText;
result.h = item.textEdit.newText;
} else if (typeof item.insertText === 'string') {
result.insertText = item.insertText;
result.h = item.insertText;
} else if (item.insertText instanceof SnippetString) {
result.insertText = item.insertText.value;
result.insertTextRules! |= modes.CompletionItemInsertTextRule.InsertAsSnippet;
} else {
result.insertText = item.label;
result.h = item.insertText.value;
result.i! |= modes.CompletionItemInsertTextRule.InsertAsSnippet;
}
// 'overwrite[Before|After]'-logic
let range: vscode.Range;
let range: vscode.Range | undefined;
if (item.textEdit) {
range = item.textEdit.range;
} else if (item.range) {
range = item.range;
} else {
range = defaultRange;
}
result.range = typeConvert.Range.from(range);
result.j = typeConvert.Range.from(range);
if (!range.isSingleLine || range.start.line !== position.line) {
if (range && (!range.isSingleLine || range.start.line !== position.line)) {
console.warn('INVALID text edit -> must be single line and on the same line');
return undefined;
}
@@ -1181,8 +1167,8 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return this._withAdapter(handle, CodeLensAdapter, adapter => adapter.provideCodeLenses(URI.revive(resource), token), []);
}
$resolveCodeLens(handle: number, resource: UriComponents, symbol: modes.ICodeLensSymbol, token: CancellationToken): Promise<modes.ICodeLensSymbol | undefined> {
return this._withAdapter(handle, CodeLensAdapter, adapter => adapter.resolveCodeLens(URI.revive(resource), symbol, token), undefined);
$resolveCodeLens(handle: number, symbol: modes.ICodeLensSymbol, token: CancellationToken): Promise<modes.ICodeLensSymbol | undefined> {
return this._withAdapter(handle, CodeLensAdapter, adapter => adapter.resolveCodeLens(symbol, token), undefined);
}
// --- code insets
@@ -1387,8 +1373,8 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return this._withAdapter(handle, SuggestAdapter, adapter => adapter.provideCompletionItems(URI.revive(resource), position, context, token), undefined);
}
$resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, suggestion: modes.CompletionItem, token: CancellationToken): Promise<modes.CompletionItem> {
return this._withAdapter(handle, SuggestAdapter, adapter => adapter.resolveCompletionItem(URI.revive(resource), position, suggestion, token), suggestion);
$resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, id: number, pid: number, token: CancellationToken): Promise<SuggestDataDto | undefined> {
return this._withAdapter(handle, SuggestAdapter, adapter => adapter.resolveCompletionItem(URI.revive(resource), position, id, pid, token), undefined);
}
$releaseCompletionItems(handle: number, id: number): void {

View File

@@ -163,7 +163,7 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape {
constructor(logsLocation: URI, mainContext: IMainContext) {
const outputDirPath = join(logsLocation.fsPath, `output_logging_${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}`);
this._outputDir = dirExists(outputDirPath).then(exists => exists ? exists : mkdirp(outputDirPath)).then(() => outputDirPath);
this._outputDir = dirExists(outputDirPath).then(exists => exists ? exists : mkdirp(outputDirPath).then(() => true)).then(() => outputDirPath);
this._proxy = mainContext.getProxy(MainContext.MainThreadOutputService);
}

View File

@@ -6,7 +6,7 @@
import { CancellationToken } from 'vs/base/common/cancellation';
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { URI, UriComponents } from 'vs/base/common/uri';
import * as extfs from 'vs/base/node/extfs';
import * as pfs from 'vs/base/node/pfs';
import { ILogService } from 'vs/platform/log/common/log';
import { IFileQuery, IFolderQuery, IRawFileQuery, IRawQuery, IRawTextQuery, ISearchCompleteStats, ITextQuery, isSerializedFileMatch, ISerializedSearchProgressItem } from 'vs/workbench/services/search/common/search';
import { FileSearchManager } from 'vs/workbench/services/search/node/fileSearchManager';
@@ -35,7 +35,7 @@ export class ExtHostSearch implements ExtHostSearchShape {
private _fileSearchManager: FileSearchManager;
constructor(mainContext: IMainContext, private _schemeTransformer: ISchemeTransformer | null, private _logService: ILogService, private _extfs = extfs) {
constructor(mainContext: IMainContext, private _schemeTransformer: ISchemeTransformer | null, private _logService: ILogService, private _pfs = pfs) {
this._proxy = mainContext.getProxy(MainContext.MainThreadSearch);
this._fileSearchManager = new FileSearchManager();
}
@@ -146,7 +146,7 @@ export class ExtHostSearch implements ExtHostSearchShape {
}
const query = reviveQuery(rawQuery);
const engine = new TextSearchManager(query, provider, this._extfs);
const engine = new TextSearchManager(query, provider, this._pfs);
return engine.search(progress => this._proxy.$handleTextMatch(handle, session, progress), token);
}
}

View File

@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as crypto from 'crypto';
import { coalesce, equals } from 'vs/base/common/arrays';
import { illegalArgument } from 'vs/base/common/errors';
import { IRelativePattern } from 'vs/base/common/glob';
@@ -1545,6 +1544,14 @@ export class TaskGroup implements vscode.TaskGroup {
}
}
function computeTaskExecutionId(values: string[]): string {
let id: string = '';
for (let i = 0; i < values.length; i++) {
id += values[i].replace(/,/g, ',,') + ',';
}
return id;
}
@es5ClassCompat
export class ProcessExecution implements vscode.ProcessExecution {
@@ -1604,17 +1611,17 @@ export class ProcessExecution implements vscode.ProcessExecution {
}
public computeId(): string {
const hash = crypto.createHash('md5');
hash.update('process');
const props: string[] = [];
props.push('process');
if (this._process !== undefined) {
hash.update(this._process);
props.push(this._process);
}
if (this._args && this._args.length > 0) {
for (let arg of this._args) {
hash.update(arg);
props.push(arg);
}
}
return hash.digest('hex');
return computeTaskExecutionId(props);
}
}
@@ -1687,20 +1694,20 @@ export class ShellExecution implements vscode.ShellExecution {
}
public computeId(): string {
const hash = crypto.createHash('md5');
hash.update('shell');
const props: string[] = [];
props.push('shell');
if (this._commandLine !== undefined) {
hash.update(this._commandLine);
props.push(this._commandLine);
}
if (this._command !== undefined) {
hash.update(typeof this._command === 'string' ? this._command : this._command.value);
props.push(typeof this._command === 'string' ? this._command : this._command.value);
}
if (this._args && this._args.length > 0) {
for (let arg of this._args) {
hash.update(typeof arg === 'string' ? arg : arg.value);
props.push(typeof arg === 'string' ? arg : arg.value);
}
}
return hash.digest('hex');
return computeTaskExecutionId(props);
}
}
@@ -1723,10 +1730,7 @@ export class CustomExecution implements vscode.CustomExecution {
}
public computeId(): string {
const hash = crypto.createHash('md5');
hash.update('customExecution');
hash.update(generateUuid());
return hash.digest('hex');
return 'customExecution' + generateUuid();
}
public set callback(value: (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable<number>) {