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

@@ -109,40 +109,48 @@ export class MainThreadCommentThread implements modes.CommentThread2 {
private _onDidChangeLabel = new Emitter<string>();
get onDidChangeLabel(): Event<string> { return this._onDidChangeLabel.event; }
private _comments: modes.Comment[] | undefined;
public get comments(): modes.Comment[] {
public get comments(): modes.Comment[] | undefined {
return this._comments;
}
public set comments(newComments: modes.Comment[]) {
public set comments(newComments: modes.Comment[] | undefined) {
this._comments = newComments;
this._onDidChangeComments.fire(this._comments);
}
private _onDidChangeComments = new Emitter<modes.Comment[]>();
get onDidChangeComments(): Event<modes.Comment[]> { return this._onDidChangeComments.event; }
private _onDidChangeComments = new Emitter<modes.Comment[] | undefined>();
get onDidChangeComments(): Event<modes.Comment[] | undefined> { return this._onDidChangeComments.event; }
set acceptInputCommand(newCommand: modes.Command) {
private _acceptInputCommand: modes.Command | undefined;
set acceptInputCommand(newCommand: modes.Command | undefined) {
this._acceptInputCommand = newCommand;
this._onDidChangeAcceptInputCommand.fire(this._acceptInputCommand);
}
get acceptInputCommand(): modes.Command {
get acceptInputCommand(): modes.Command | undefined {
return this._acceptInputCommand!;
}
private _onDidChangeAcceptInputCommand = new Emitter<modes.Command>();
get onDidChangeAcceptInputCommand(): Event<modes.Command> { return this._onDidChangeAcceptInputCommand.event; }
private _onDidChangeAcceptInputCommand = new Emitter<modes.Command | undefined>();
get onDidChangeAcceptInputCommand(): Event<modes.Command | undefined> { return this._onDidChangeAcceptInputCommand.event; }
set additionalCommands(newCommands: modes.Command[]) {
private _additionalCommands: modes.Command[] | undefined;
set additionalCommands(newCommands: modes.Command[] | undefined) {
this._additionalCommands = newCommands;
this._onDidChangeAdditionalCommands.fire(this._additionalCommands);
}
get additionalCommands(): modes.Command[] {
get additionalCommands(): modes.Command[] | undefined {
return this._additionalCommands;
}
private _onDidChangeAdditionalCommands = new Emitter<modes.Command[] | undefined>();
get onDidChangeAdditionalCommands(): Event<modes.Command[] | undefined> { return this._onDidChangeAdditionalCommands.event; }
private _deleteCommand: modes.Command | undefined;
set deleteCommand(newCommand: modes.Command | undefined) {
this._deleteCommand = newCommand;
}
@@ -151,9 +159,6 @@ export class MainThreadCommentThread implements modes.CommentThread2 {
return this._deleteCommand;
}
private _onDidChangeAdditionalCommands = new Emitter<modes.Command[]>();
get onDidChangeAdditionalCommands(): Event<modes.Command[]> { return this._onDidChangeAdditionalCommands.event; }
set range(range: IRange) {
this._range = range;
this._onDidChangeRange.fire(this._range);
@@ -166,16 +171,17 @@ export class MainThreadCommentThread implements modes.CommentThread2 {
private _onDidChangeRange = new Emitter<IRange>();
public onDidChangeRange = this._onDidChangeRange.event;
private _collapsibleState: modes.CommentThreadCollapsibleState | undefined;
get collapsibleState() {
return this._collapsibleState;
}
set collapsibleState(newState: modes.CommentThreadCollapsibleState) {
set collapsibleState(newState: modes.CommentThreadCollapsibleState | undefined) {
this._collapsibleState = newState;
this._onDidChangeCollasibleState.fire(this._collapsibleState);
}
private _onDidChangeCollasibleState = new Emitter<modes.CommentThreadCollapsibleState>();
private _onDidChangeCollasibleState = new Emitter<modes.CommentThreadCollapsibleState | undefined>();
public onDidChangeCollasibleState = this._onDidChangeCollasibleState.event;
constructor(
@@ -184,14 +190,24 @@ export class MainThreadCommentThread implements modes.CommentThread2 {
public extensionId: string,
public threadId: string,
public resource: string,
private _range: IRange,
private _comments: modes.Comment[],
private _acceptInputCommand: modes.Command | undefined,
private _additionalCommands: modes.Command[],
private _deleteCommand: modes.Command | undefined,
private _collapsibleState: modes.CommentThreadCollapsibleState
) {
private _range: IRange
) { }
batchUpdate(
range: IRange,
label: string,
comments: modes.Comment[],
acceptInputCommand: modes.Command | undefined,
additionalCommands: modes.Command[],
deleteCommand: modes.Command | undefined,
collapsibleState: modes.CommentThreadCollapsibleState) {
this._range = range;
this._label = label;
this._comments = comments;
this._acceptInputCommand = acceptInputCommand;
this._additionalCommands = additionalCommands;
this._deleteCommand = deleteCommand;
this._collapsibleState = collapsibleState;
}
dispose() { }
@@ -254,23 +270,14 @@ export class MainThreadCommentController {
threadId: string,
resource: UriComponents,
range: IRange,
comments: modes.Comment[],
acceptInputCommand: modes.Command | undefined,
additionalCommands: modes.Command[],
deleteCommand: modes.Command | undefined,
collapseState: modes.CommentThreadCollapsibleState): modes.CommentThread2 {
): modes.CommentThread2 {
let thread = new MainThreadCommentThread(
commentThreadHandle,
this,
'',
threadId,
URI.revive(resource).toString(),
range,
comments,
acceptInputCommand,
additionalCommands,
deleteCommand,
collapseState
range
);
this._threads.set(commentThreadHandle, thread);
@@ -284,6 +291,27 @@ export class MainThreadCommentController {
return thread;
}
updateCommentThread(commentThreadHandle: number,
threadId: string,
resource: UriComponents,
range: IRange,
label: string,
comments: modes.Comment[],
acceptInputCommand: modes.Command | undefined,
additionalCommands: modes.Command[],
deleteCommand: modes.Command | undefined,
collapsibleState: modes.CommentThreadCollapsibleState): void {
let thread = this.getKnownThread(commentThreadHandle);
thread.batchUpdate(range, label, comments, acceptInputCommand, additionalCommands, deleteCommand, collapsibleState);
this._commentService.updateComments(this._uniqueId, {
added: [],
removed: [],
changed: [thread],
draftMode: modes.DraftMode.NotSupported
});
}
deleteCommentThread(commentThreadHandle: number) {
let thread = this.getKnownThread(commentThreadHandle);
this._threads.delete(commentThreadHandle);
@@ -298,48 +326,6 @@ export class MainThreadCommentController {
thread.dispose();
}
updateComments(commentThreadHandle: number, comments: modes.Comment[]) {
let thread = this.getKnownThread(commentThreadHandle);
thread.comments = comments;
this._commentService.updateComments(this._uniqueId, {
added: [],
removed: [],
changed: [thread],
draftMode: modes.DraftMode.NotSupported
});
}
updateAcceptInputCommand(commentThreadHandle: number, acceptInputCommand: modes.Command) {
let thread = this.getKnownThread(commentThreadHandle);
thread.acceptInputCommand = acceptInputCommand;
}
updateAdditionalCommands(commentThreadHandle: number, additionalCommands: modes.Command[]) {
let thread = this.getKnownThread(commentThreadHandle);
thread.additionalCommands = additionalCommands;
}
updateDeleteCommand(commentThreadHandle: number, deleteCommand: modes.Command) {
const thread = this.getKnownThread(commentThreadHandle);
thread.deleteCommand = deleteCommand;
}
updateCollapsibleState(commentThreadHandle: number, collapseState: modes.CommentThreadCollapsibleState) {
let thread = this.getKnownThread(commentThreadHandle);
thread.collapsibleState = collapseState;
}
updateCommentThreadRange(commentThreadHandle: number, range: IRange) {
let thread = this.getKnownThread(commentThreadHandle);
thread.range = range;
}
updateCommentThreadLabel(commentThreadHandle: number, label: string) {
let thread = this.getKnownThread(commentThreadHandle);
thread.label = label;
}
updateInput(input: string) {
let thread = this.activeCommentThread;
@@ -358,7 +344,6 @@ export class MainThreadCommentController {
return thread;
}
async getDocumentComments(resource: URI, token: CancellationToken) {
let ret: modes.CommentThread2[] = [];
for (let thread of keys(this._threads)) {
@@ -499,19 +484,35 @@ export class MainThreadComments extends Disposable implements MainThreadComments
commentThreadHandle: number,
threadId: string,
resource: UriComponents,
range: IRange,
comments: modes.Comment[],
acceptInputCommand: modes.Command | undefined,
additionalCommands: modes.Command[],
deleteCommand: modes.Command,
collapseState: modes.CommentThreadCollapsibleState): modes.CommentThread2 | undefined {
range: IRange
): modes.CommentThread2 | undefined {
let provider = this._commentControllers.get(handle);
if (!provider) {
return undefined;
}
return provider.createCommentThread(commentThreadHandle, threadId, resource, range, comments, acceptInputCommand, additionalCommands, deleteCommand, collapseState);
return provider.createCommentThread(commentThreadHandle, threadId, resource, range);
}
$updateCommentThread(handle: number,
commentThreadHandle: number,
threadId: string,
resource: UriComponents,
range: IRange,
label: string,
comments: modes.Comment[],
acceptInputCommand: modes.Command | undefined,
additionalCommands: modes.Command[],
deleteCommand: modes.Command,
collapsibleState: modes.CommentThreadCollapsibleState): void {
let provider = this._commentControllers.get(handle);
if (!provider) {
return undefined;
}
return provider.updateCommentThread(commentThreadHandle, threadId, resource, range, label, comments, acceptInputCommand, additionalCommands, deleteCommand, collapsibleState);
}
$deleteCommentThread(handle: number, commentThreadHandle: number) {
@@ -524,16 +525,6 @@ export class MainThreadComments extends Disposable implements MainThreadComments
return provider.deleteCommentThread(commentThreadHandle);
}
$updateComments(handle: number, commentThreadHandle: number, comments: modes.Comment[]) {
let provider = this._commentControllers.get(handle);
if (!provider) {
return;
}
provider.updateComments(commentThreadHandle, comments);
}
$setInputValue(handle: number, input: string) {
let provider = this._commentControllers.get(handle);
@@ -544,66 +535,6 @@ export class MainThreadComments extends Disposable implements MainThreadComments
provider.updateInput(input);
}
$updateCommentThreadAcceptInputCommand(handle: number, commentThreadHandle: number, acceptInputCommand: modes.Command) {
let provider = this._commentControllers.get(handle);
if (!provider) {
return;
}
provider.updateAcceptInputCommand(commentThreadHandle, acceptInputCommand);
}
$updateCommentThreadAdditionalCommands(handle: number, commentThreadHandle: number, additionalCommands: modes.Command[]) {
let provider = this._commentControllers.get(handle);
if (!provider) {
return;
}
provider.updateAdditionalCommands(commentThreadHandle, additionalCommands);
}
$updateCommentThreadDeleteCommand(handle: number, commentThreadHandle: number, acceptInputCommand: modes.Command) {
let provider = this._commentControllers.get(handle);
if (!provider) {
return;
}
provider.updateDeleteCommand(commentThreadHandle, acceptInputCommand);
}
$updateCommentThreadCollapsibleState(handle: number, commentThreadHandle: number, collapseState: modes.CommentThreadCollapsibleState): void {
let provider = this._commentControllers.get(handle);
if (!provider) {
return;
}
provider.updateCollapsibleState(commentThreadHandle, collapseState);
}
$updateCommentThreadRange(handle: number, commentThreadHandle: number, range: any): void {
let provider = this._commentControllers.get(handle);
if (!provider) {
return;
}
provider.updateCommentThreadRange(commentThreadHandle, range);
}
$updateCommentThreadLabel(handle: number, commentThreadHandle: number, label: string): void {
let provider = this._commentControllers.get(handle);
if (!provider) {
return;
}
provider.updateCommentThreadLabel(commentThreadHandle, label);
}
$registerDocumentCommentProvider(handle: number, features: CommentProviderFeatures): void {
this._documentProviders.set(handle, undefined);
const handler = new MainThreadDocumentCommentProvider(this._proxy, handle, features);

View File

@@ -9,8 +9,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
import { IRemoteConsoleLog, log, parse } from 'vs/base/common/console';
import { parseExtensionDevOptions } from 'vs/workbench/services/extensions/common/extensionDevOptions';
import { IWindowsService } from 'vs/platform/windows/common/windows';
import { IBroadcastService } from 'vs/workbench/services/broadcast/common/broadcast';
import { EXTENSION_LOG_BROADCAST_CHANNEL } from 'vs/platform/extensions/common/extensionHost';
import { IExtensionHostDebugService } from 'vs/workbench/services/extensions/common/extensionHostDebug';
@extHostNamedCustomer(MainContext.MainThreadConsole)
export class MainThreadConsole implements MainThreadConsoleShape {
@@ -22,7 +21,7 @@ export class MainThreadConsole implements MainThreadConsoleShape {
extHostContext: IExtHostContext,
@IEnvironmentService private readonly _environmentService: IEnvironmentService,
@IWindowsService private readonly _windowsService: IWindowsService,
@IBroadcastService private readonly _broadcastService: IBroadcastService,
@IExtensionHostDebugService private readonly _extensionHostDebugService: IExtensionHostDebugService,
) {
const devOpts = parseExtensionDevOptions(this._environmentService);
this._isExtensionDevHost = devOpts.isExtensionDevHost;
@@ -45,14 +44,8 @@ export class MainThreadConsole implements MainThreadConsoleShape {
}
// Broadcast to other windows if we are in development mode
else if (!this._environmentService.isBuilt || this._isExtensionDevHost) {
this._broadcastService.broadcast({
channel: EXTENSION_LOG_BROADCAST_CHANNEL,
payload: {
logEntry: entry,
debugId: this._environmentService.debugExtensionHost.debugId
}
});
else if (this._environmentService.debugExtensionHost.debugId && (!this._environmentService.isBuilt || this._isExtensionDevHost)) {
this._extensionHostDebugService.logToSession(this._environmentService.debugExtensionHost.debugId, entry);
}
}
}

View File

@@ -0,0 +1,61 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { MainContext, MainThreadKeytarShape, IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
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>;
}
@extHostNamedCustomer(MainContext.MainThreadKeytar)
export class MainThreadKeytar implements MainThreadKeytarShape {
private _keytar: IKeytarModule | null;
constructor(
extHostContext: IExtHostContext
) {
try {
this._keytar = <IKeytarModule>require.__$__nodeRequire('keytar');
} catch (e) {
this._keytar = null;
}
}
dispose(): void {
//
}
async $getPassword(service: string, account: string): Promise<string | null> {
if (this._keytar) {
return this._keytar.getPassword(service, account);
}
return null;
}
async $setPassword(service: string, account: string, password: string): Promise<void> {
if (this._keytar) {
return this._keytar.setPassword(service, account, password);
}
}
async $deletePassword(service: string, account: string): Promise<boolean> {
if (this._keytar) {
return this._keytar.deletePassword(service, account);
}
return false;
}
async $findPassword(service: string): Promise<string | null> {
if (this._keytar) {
return this._keytar.findPassword(service);
}
return null;
}
}

View File

@@ -10,8 +10,8 @@ import * as modes from 'vs/editor/common/modes';
import * as search from 'vs/workbench/contrib/search/common/search';
import { CancellationToken } from 'vs/base/common/cancellation';
import { Position as EditorPosition } from 'vs/editor/common/core/position';
import { Range as EditorRange } from 'vs/editor/common/core/range';
import { ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, MainContext, IExtHostContext, ISerializedLanguageConfiguration, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, LocationDto, WorkspaceSymbolDto, CodeActionDto, reviveWorkspaceEditDto, ISerializedDocumentFilter, DefinitionLinkDto, ISerializedSignatureHelpProviderMetadata, CodeInsetDto, LinkDto, CallHierarchyDto } from '../common/extHost.protocol';
import { Range as EditorRange, IRange } from 'vs/editor/common/core/range';
import { ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, MainContext, IExtHostContext, ISerializedLanguageConfiguration, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, LocationDto, WorkspaceSymbolDto, CodeActionDto, reviveWorkspaceEditDto, ISerializedDocumentFilter, DefinitionLinkDto, ISerializedSignatureHelpProviderMetadata, CodeInsetDto, LinkDto, CallHierarchyDto, SuggestDataDto } from '../common/extHost.protocol';
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
import { LanguageConfiguration, IndentationRule, OnEnterRule } from 'vs/editor/common/modes/languageConfiguration';
import { IModeService } from 'vs/editor/common/services/modeService';
@@ -22,6 +22,7 @@ import * as codeInset from 'vs/workbench/contrib/codeinset/common/codeInset';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import * as callh from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';
import { IHeapService } from 'vs/workbench/services/heap/common/heap';
import { mixin } from 'vs/base/common/objects';
@extHostNamedCustomer(MainContext.MainThreadLanguageFeatures)
export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesShape {
@@ -150,8 +151,8 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
return dto;
});
},
resolveCodeLens: (model: ITextModel, codeLens: modes.ICodeLensSymbol, token: CancellationToken): Promise<modes.ICodeLensSymbol | undefined> => {
return this._proxy.$resolveCodeLens(handle, model.uri, codeLens, token).then(obj => {
resolveCodeLens: (_model: ITextModel, codeLens: modes.ICodeLensSymbol, token: CancellationToken): Promise<modes.ICodeLensSymbol | undefined> => {
return this._proxy.$resolveCodeLens(handle, codeLens, token).then(obj => {
if (obj) {
this._heapService.trackObject(obj);
this._heapService.trackObject(obj.command);
@@ -359,29 +360,56 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
// --- suggest
private static _inflateSuggestDto(defaultRange: IRange, data: SuggestDataDto): modes.CompletionItem {
return {
label: data.a,
kind: data.b,
detail: data.c,
documentation: data.d,
sortText: data.e,
filterText: data.f,
preselect: data.g,
insertText: data.h || data.a,
insertTextRules: data.i,
range: data.j || defaultRange,
commitCharacters: data.k,
additionalTextEdits: data.l,
command: data.m,
// not-standard
_id: data.x,
_pid: data.y
};
}
$registerSuggestSupport(handle: number, selector: ISerializedDocumentFilter[], triggerCharacters: string[], supportsResolveDetails: boolean): void {
this._registrations[handle] = modes.CompletionProviderRegistry.register(selector, <modes.CompletionItemProvider>{
const provider: modes.CompletionItemProvider = {
triggerCharacters,
provideCompletionItems: (model: ITextModel, position: EditorPosition, context: modes.CompletionContext, token: CancellationToken): Promise<modes.CompletionList | undefined> => {
return this._proxy.$provideCompletionItems(handle, model.uri, position, context, token).then(result => {
if (!result) {
return result;
// {{SQL CARBON EDIT}} @todo anthonydresser required because of strict null checks
return undefined;
}
return {
suggestions: result.suggestions,
incomplete: result.incomplete,
dispose: () => {
if (typeof result._id === 'number') {
this._proxy.$releaseCompletionItems(handle, result._id);
}
}
suggestions: result.b.map(d => MainThreadLanguageFeatures._inflateSuggestDto(result.a, d)),
incomplete: result.c,
dispose: () => this._proxy.$releaseCompletionItems(handle, result.x)
};
});
},
resolveCompletionItem: supportsResolveDetails
? (model, position, suggestion, token) => this._proxy.$resolveCompletionItem(handle, model.uri, position, suggestion, token)
: undefined
});
}
};
if (supportsResolveDetails) {
provider.resolveCompletionItem = (model, position, suggestion, token) => {
return this._proxy.$resolveCompletionItem(handle, model.uri, position, suggestion._id, suggestion._pid, token).then(result => {
if (!result) {
return suggestion;
}
let newSuggestion = MainThreadLanguageFeatures._inflateSuggestDto(suggestion.range, result);
return mixin(suggestion, newSuggestion, true);
});
};
}
this._registrations[handle] = modes.CompletionProviderRegistry.register(selector, provider);
}
// --- parameter hints

View File

@@ -220,7 +220,7 @@ CommandsRegistry.registerCommand('_workbench.enterWorkspace', async function (ac
const runningExtensions = await extensionService.getExtensions();
// If requested extension to disable is running, then reload window with given workspace
if (disableExtensions && runningExtensions.some(runningExtension => disableExtensions.some(id => ExtensionIdentifier.equals(runningExtension.identifier, id)))) {
return windowService.openWindow([{ uri: workspace, typeHint: 'file' }], { args: { _: [], 'disable-extension': disableExtensions } });
return windowService.openWindow([{ workspaceUri: workspace }], { args: { _: [], 'disable-extension': disableExtensions } });
}
}

View File

@@ -126,16 +126,10 @@ export interface MainThreadCommentsShape extends IDisposable {
$registerCommentController(handle: number, id: string, label: string): void;
$unregisterCommentController(handle: number): void;
$updateCommentControllerFeatures(handle: number, features: CommentProviderFeatures): void;
$createCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange, comments: modes.Comment[], acceptInputCommand: modes.Command | undefined, additionalCommands: modes.Command[], deleteCommand: modes.Command | undefined, collapseState: modes.CommentThreadCollapsibleState): modes.CommentThread2 | undefined;
$createCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange): modes.CommentThread2 | undefined;
$updateCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange, label: string, comments: modes.Comment[], acceptInputCommand: modes.Command | undefined, additionalCommands: modes.Command[], deleteCommand: modes.Command | undefined, collapseState: modes.CommentThreadCollapsibleState): void;
$deleteCommentThread(handle: number, commentThreadHandle: number): void;
$updateComments(handle: number, commentThreadHandle: number, comments: modes.Comment[]): void;
$setInputValue(handle: number, input: string): void;
$updateCommentThreadAcceptInputCommand(handle: number, commentThreadHandle: number, acceptInputCommand: modes.Command): void;
$updateCommentThreadAdditionalCommands(handle: number, commentThreadHandle: number, additionalCommands: modes.Command[]): void;
$updateCommentThreadDeleteCommand(handle: number, commentThreadHandle: number, deleteCommand: modes.Command): void;
$updateCommentThreadCollapsibleState(handle: number, commentThreadHandle: number, collapseState: modes.CommentThreadCollapsibleState): void;
$updateCommentThreadRange(handle: number, commentThreadHandle: number, range: IRange): void;
$updateCommentThreadLabel(handle: number, commentThreadHandle: number, label: string): void;
$registerDocumentCommentProvider(handle: number, features: CommentProviderFeatures): void;
$unregisterDocumentCommentProvider(handle: number): void;
$registerWorkspaceCommentProvider(handle: number, extensionId: ExtensionIdentifier): void;
@@ -266,6 +260,13 @@ export interface MainThreadConsoleShape extends IDisposable {
}): void;
}
export interface MainThreadKeytarShape extends IDisposable {
$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 interface ISerializedRegExp {
pattern: string;
flags?: string;
@@ -862,14 +863,30 @@ export class IdObject {
}
}
export interface SuggestionDto extends modes.CompletionItem {
_id: number;
_parentId: number;
export interface SuggestDataDto {
a/* label */: string;
b/* kind */: modes.CompletionItemKind;
c/* detail */?: string;
d/* documentation */?: string | IMarkdownString;
e/* sortText */?: string;
f/* filterText */?: string;
g/* preselect */?: boolean;
h/* insertText */?: string;
i/* insertTextRules */?: modes.CompletionItemInsertTextRule;
j/* range */?: IRange;
k/* commitCharacters */?: string[];
l/* additionalTextEdits */?: ISingleEditOperation[];
m/* command */?: modes.Command;
// not-standard
x: number;
y: number;
}
export interface SuggestResultDto extends IdObject {
suggestions: SuggestionDto[];
incomplete?: boolean;
export interface SuggestResultDto {
x: number;
a: IRange;
b: SuggestDataDto[];
c?: boolean;
}
export interface LocationDto {
@@ -970,7 +987,7 @@ export interface CallHierarchyDto {
export interface ExtHostLanguageFeaturesShape {
$provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise<modes.DocumentSymbol[] | undefined>;
$provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise<CodeLensDto[]>;
$resolveCodeLens(handle: number, resource: UriComponents, symbol: CodeLensDto, token: CancellationToken): Promise<CodeLensDto | undefined>;
$resolveCodeLens(handle: number, symbol: CodeLensDto, token: CancellationToken): Promise<CodeLensDto | undefined>;
$provideCodeInsets(handle: number, resource: UriComponents, token: CancellationToken): Promise<CodeInsetDto[] | undefined>;
$resolveCodeInset(handle: number, resource: UriComponents, symbol: CodeInsetDto, token: CancellationToken): Promise<CodeInsetDto>;
$provideDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<DefinitionLinkDto[]>;
@@ -990,7 +1007,7 @@ export interface ExtHostLanguageFeaturesShape {
$provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise<WorkspaceEditDto | undefined>;
$resolveRenameLocation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.RenameLocation | undefined>;
$provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<SuggestResultDto | undefined>;
$resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, suggestion: modes.CompletionItem, token: CancellationToken): Promise<modes.CompletionItem>;
$resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, id: number, pid: number, token: CancellationToken): Promise<SuggestDataDto | undefined>;
$releaseCompletionItems(handle: number, id: number): void;
$provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise<modes.SignatureHelp | undefined>;
$provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise<LinkDto[] | undefined>;
@@ -1199,6 +1216,7 @@ export const MainContext = {
MainThreadTextEditors: createMainId<MainThreadTextEditorsShape>('MainThreadTextEditors'),
MainThreadErrors: createMainId<MainThreadErrorsShape>('MainThreadErrors'),
MainThreadTreeViews: createMainId<MainThreadTreeViewsShape>('MainThreadTreeViews'),
MainThreadKeytar: createMainId<MainThreadKeytarShape>('MainThreadKeytar'),
MainThreadLanguageFeatures: createMainId<MainThreadLanguageFeaturesShape>('MainThreadLanguageFeatures'),
MainThreadLanguages: createMainId<MainThreadLanguagesShape>('MainThreadLanguages'),
MainThreadMessageService: createMainId<MainThreadMessageServiceShape>('MainThreadMessageService'),

View File

@@ -34,7 +34,6 @@ namespace schema {
case 'explorer/context': return MenuId.ExplorerContext;
case 'editor/title/context': return MenuId.EditorTitleContext;
case 'debug/callstack/context': return MenuId.DebugCallStackContext;
case 'debug/toolbar': return MenuId.DebugToolBar;
case 'debug/toolBar': return MenuId.DebugToolBar;
case 'menuBar/file': return MenuId.MenubarFileMenu;
case 'scm/title': return MenuId.SCMTitle;

View File

@@ -33,6 +33,7 @@ import '../browser/mainThreadExtensionService';
import '../browser/mainThreadFileSystem';
import '../browser/mainThreadFileSystemEventService';
import '../browser/mainThreadHeapService';
import '../browser/mainThreadKeytar';
import '../browser/mainThreadLanguageFeatures';
import '../browser/mainThreadLanguages';
import '../browser/mainThreadLogService';

View File

@@ -7,30 +7,38 @@ import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import * as map from 'vs/base/common/map';
import { URI, UriComponents } from 'vs/base/common/uri';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { IWebviewOptions } from 'vs/editor/common/modes';
import { localize } from 'vs/nls';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import product from 'vs/platform/product/node/product';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewInsetHandle, WebviewPanelHandle, WebviewPanelShowOptions } from 'vs/workbench/api/common/extHost.protocol';
import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor';
import { CodeInsetController } from 'vs/workbench/contrib/codeinset/electron-browser/codeInset.contribution';
import { WebviewEditor } from 'vs/workbench/contrib/webview/electron-browser/webviewEditor';
import { WebviewEditorInput } from 'vs/workbench/contrib/webview/electron-browser/webviewEditorInput';
import { ICreateWebViewShowOptions, IWebviewEditorService, WebviewInputOptions } from 'vs/workbench/contrib/webview/electron-browser/webviewEditorService';
import { WebviewEditor } from 'vs/workbench/contrib/webview/browser/webviewEditor';
import { WebviewEditorInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput';
import { ICreateWebViewShowOptions, IWebviewEditorService, WebviewInputOptions } from 'vs/workbench/contrib/webview/browser/webviewEditorService';
import { WebviewElement } from 'vs/workbench/contrib/webview/electron-browser/webviewElement';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { ACTIVE_GROUP, IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
import { extHostNamedCustomer } from '../common/extHostCustomers';
import { IWebviewOptions } from 'vs/editor/common/modes';
@extHostNamedCustomer(MainContext.MainThreadWebviews)
export class MainThreadWebviews extends Disposable implements MainThreadWebviewsShape {
private static readonly standardSupportedLinkSchemes = ['http', 'https', 'mailto'];
private static readonly standardSupportedLinkSchemes = new Set([
'http',
'https',
'mailto',
product.urlProtocol,
'vscode',
'vscode-insiders'
]);
private static revivalPool = 0;
@@ -104,7 +112,6 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews
};
this._webviews.set(handle, webview);
this._activeWebview = handle;
/* __GDPR__
"webviews:createWebviewPanel" : {
@@ -200,9 +207,9 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews
return;
}
const targetGroup = this._editorGroupService.getGroup(viewColumnToEditorGroup(this._editorGroupService, showOptions.viewColumn));
const targetGroup = this._editorGroupService.getGroup(viewColumnToEditorGroup(this._editorGroupService, showOptions.viewColumn)) || this._editorGroupService.getGroup(webview.group || 0);
if (targetGroup) {
this._webviewService.revealWebview(webview, targetGroup || this._editorGroupService.getGroup(webview.group || ACTIVE_GROUP), !!showOptions.preserveFocus);
this._webviewService.revealWebview(webview, targetGroup, !!showOptions.preserveFocus);
}
}
@@ -366,12 +373,18 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews
}
const webview = this.getWebview(handle);
const enableCommandUris = webview.options.enableCommandUris;
if (MainThreadWebviews.standardSupportedLinkSchemes.indexOf(link.scheme) >= 0 || enableCommandUris && link.scheme === 'command') {
if (this.isSupportedLink(webview, link)) {
this._openerService.open(link);
}
}
private isSupportedLink(webview: WebviewEditorInput, link: URI): boolean {
if (MainThreadWebviews.standardSupportedLinkSchemes.has(link.scheme)) {
return true;
}
return !!webview.options.enableCommandUris && link.scheme === 'command';
}
private getWebview(handle: WebviewPanelHandle): WebviewEditorInput {
const webview = this._webviews.get(handle);
if (!webview) {

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>) {