Merge branch 'main' into sandy081/fix140120

This commit is contained in:
Sandeep Somavarapu
2022-01-08 00:37:53 +01:00
227 changed files with 5779 additions and 2688 deletions

View File

@@ -354,8 +354,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
: extHostTypes.ExtensionKind.UI;
const tests: typeof vscode.tests = {
createTestController(provider, label) {
return extHostTesting.createTestController(provider, label);
createTestController(provider, label, refreshHandler?: () => Thenable<void> | void) {
return extHostTesting.createTestController(provider, label, refreshHandler);
},
createTestObserver() {
checkProposedApiEnabled(extension, 'testObserver');
@@ -1276,6 +1276,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
WorkspaceEdit: extHostTypes.WorkspaceEdit,
// proposed api types
InlayHint: extHostTypes.InlayHint,
InlayHintLabelPart: extHostTypes.InlayHintLabelPart,
InlayHintKind: extHostTypes.InlayHintKind,
RemoteAuthorityResolverError: extHostTypes.RemoteAuthorityResolverError,
ResolvedAuthority: extHostTypes.ResolvedAuthority,

View File

@@ -98,6 +98,12 @@ export interface IWorkspaceData extends IStaticWorkspaceData {
folders: { uri: UriComponents, name: string, index: number; }[];
}
export interface MessagePortLike {
postMessage(message: any, transfer?: any[]): void;
addEventListener(type: 'message', listener: (e: any) => any): void;
removeEventListener(type: 'message', listener: (e: any) => any): void;
}
export interface IInitData {
version: string;
commit?: string;
@@ -114,6 +120,7 @@ export interface IInitData {
autoStart: boolean;
remote: { isRemote: boolean; authority: string | undefined; connectionData: IRemoteConnectionData | null; };
uiKind: UIKind;
messagePorts?: ReadonlyMap<string, MessagePortLike>;
}
export interface IConfigurationInitData extends IConfigurationData {
@@ -414,7 +421,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
$registerSuggestSupport(handle: number, selector: IDocumentFilterDto[], triggerCharacters: string[], supportsResolveDetails: boolean, displayName: string): void;
$registerInlineCompletionsSupport(handle: number, selector: IDocumentFilterDto[]): void;
$registerSignatureHelpProvider(handle: number, selector: IDocumentFilterDto[], metadata: ISignatureHelpProviderMetadataDto): void;
$registerInlayHintsProvider(handle: number, selector: IDocumentFilterDto[], eventHandle: number | undefined): void;
$registerInlayHintsProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean, eventHandle: number | undefined): void;
$emitInlayHintsEvent(eventHandle: number): void;
$registerDocumentLinkProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean): void;
$registerDocumentColorProvider(handle: number, selector: IDocumentFilterDto[]): void;
@@ -1496,7 +1503,9 @@ export interface ISignatureHelpContextDto {
}
export interface IInlayHintDto {
text: string;
cacheId?: ChainedCacheId;
label: string | modes.InlayHintLabelPart[];
tooltip?: string | IMarkdownString;
position: IPosition;
kind: modes.InlayHintKind;
whitespaceBefore?: boolean;
@@ -1504,6 +1513,7 @@ export interface IInlayHintDto {
}
export interface IInlayHintsDto {
cacheId?: CacheId
hints: IInlayHintDto[]
}
@@ -1715,6 +1725,8 @@ export interface ExtHostLanguageFeaturesShape {
$provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise<ISignatureHelpDto | undefined>;
$releaseSignatureHelp(handle: number, id: number): void;
$provideInlayHints(handle: number, resource: UriComponents, range: IRange, token: CancellationToken): Promise<IInlayHintsDto | undefined>
$resolveInlayHint(handle: number, id: ChainedCacheId, token: CancellationToken): Promise<IInlayHintDto | undefined>;
$releaseInlayHints(handle: number, id: number): void;
$provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise<ILinksListDto | undefined>;
$resolveDocumentLink(handle: number, id: ChainedCacheId, token: CancellationToken): Promise<ILinkDto | undefined>;
$releaseDocumentLinks(handle: number, id: number): void;
@@ -2147,15 +2159,22 @@ export interface ExtHostTestingShape {
$resolveFileCoverage(runId: string, taskId: string, fileIndex: number, token: CancellationToken): Promise<CoverageDetails[]>;
/** Configures a test run config. */
$configureRunProfile(controllerId: string, configId: number): void;
/** Asks the controller to refresh its tests */
$refreshTests(controllerId: string): Promise<void>;
}
export interface ITestControllerPatch {
label?: string;
canRefresh?: boolean;
}
export interface MainThreadTestingShape {
// --- test lifecycle:
/** Registers that there's a test controller with the given ID */
$registerTestController(controllerId: string, label: string): void;
$registerTestController(controllerId: string, label: string, canRefresh: boolean): void;
/** Updates the label of an existing test controller. */
$updateControllerLabel(controllerId: string, label: string): void;
$updateController(controllerId: string, patch: ITestControllerPatch): void;
/** Diposes of the test controller with the given ID */
$unregisterTestController(controllerId: string): void;
/** Requests tests published to VS Code. */
@@ -2260,7 +2279,7 @@ export const MainContext = {
MainThreadTheming: createMainId<MainThreadThemingShape>('MainThreadTheming'),
MainThreadTunnelService: createMainId<MainThreadTunnelServiceShape>('MainThreadTunnelService'),
MainThreadTimeline: createMainId<MainThreadTimelineShape>('MainThreadTimeline'),
MainThreadTesting: createMainId<MainThreadTestingShape>('MainThreadTesting')
MainThreadTesting: createMainId<MainThreadTestingShape>('MainThreadTesting'),
};
export const ExtHostContext = {

View File

@@ -332,8 +332,8 @@ const newCommands: ApiCommand[] = [
new ApiCommand(
'vscode.executeInlayHintProvider', '_executeInlayHintProvider', 'Execute inlay hints provider',
[ApiCommandArgument.Uri, ApiCommandArgument.Range],
new ApiCommandResult<modes.InlayHint[], vscode.InlayHint[]>('A promise that resolves to an array of Inlay objects', result => {
return result.map(typeConverters.InlayHint.to);
new ApiCommandResult<modes.InlayHint[], vscode.InlayHint[]>('A promise that resolves to an array of Inlay objects', (result, args, converter) => {
return result.map(typeConverters.InlayHint.to.bind(undefined, converter));
})
),
// --- notebooks

View File

@@ -17,7 +17,7 @@ import { ExtHostConfiguration, IExtHostConfiguration } from 'vs/workbench/api/co
import { ActivatedExtension, EmptyExtension, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator';
import { ExtHostStorage, IExtHostStorage } from 'vs/workbench/api/common/extHostStorage';
import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { MissingExtensionDependency, ActivationKind, checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { MissingExtensionDependency, ActivationKind, checkProposedApiEnabled, isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
import * as errors from 'vs/base/common/errors';
import type * as vscode from 'vscode';
@@ -424,6 +424,10 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
const that = this;
let extension: vscode.Extension<any> | undefined;
const messagePort = isProposedApiEnabled(extensionDescription, 'ipc')
? this._initData.messagePorts?.get(ExtensionIdentifier.toKey(extensionDescription.identifier))
: undefined;
return Object.freeze<vscode.ExtensionContext>({
globalState,
workspaceState,
@@ -449,7 +453,11 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
checkProposedApiEnabled(extensionDescription, 'extensionRuntime');
return that.extensionRuntime;
},
get environmentVariableCollection() { return that._extHostTerminalService.getEnvironmentVariableCollection(extensionDescription); }
get environmentVariableCollection() { return that._extHostTerminalService.getEnvironmentVariableCollection(extensionDescription); },
messagePassingProtocol: messagePort && {
onDidReceiveMessage: Event.fromDOMEventEmitter(messagePort, 'message', e => e.data),
postMessage: messagePort.postMessage.bind(messagePort) as any
}
});
});
}

View File

@@ -7,7 +7,7 @@ import { URI, UriComponents } from 'vs/base/common/uri';
import { mixin } from 'vs/base/common/objects';
import type * as vscode from 'vscode';
import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters';
import { Range, Disposable, CompletionList, SnippetString, CodeActionKind, SymbolInformation, DocumentSymbol, SemanticTokensEdits, SemanticTokens, SemanticTokensEdit } from 'vs/workbench/api/common/extHostTypes';
import { Range, Disposable, CompletionList, SnippetString, CodeActionKind, SymbolInformation, DocumentSymbol, SemanticTokensEdits, SemanticTokens, SemanticTokensEdit, InlayHintKind, Location } from 'vs/workbench/api/common/extHostTypes';
import { ISingleEditOperation } from 'vs/editor/common/model';
import * as modes from 'vs/editor/common/languages';
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
@@ -1171,15 +1171,94 @@ class SignatureHelpAdapter {
}
class InlayHintsAdapter {
private _cache = new Cache<vscode.InlayHint>('InlayHints');
private readonly _disposables = new Map<number, DisposableStore>();
constructor(
private readonly _documents: ExtHostDocuments,
private readonly _commands: CommandsConverter,
private readonly _provider: vscode.InlayHintsProvider,
) { }
async provideInlayHints(resource: URI, range: IRange, token: CancellationToken): Promise<extHostProtocol.IInlayHintsDto | undefined> {
const doc = this._documents.getDocument(resource);
const value = await this._provider.provideInlayHints(doc, typeConvert.Range.to(range), token);
return value ? { hints: value.map(typeConvert.InlayHint.from) } : undefined;
const hints = await this._provider.provideInlayHints(doc, typeConvert.Range.to(range), token);
if (!Array.isArray(hints) || hints.length === 0) {
// bad result
return undefined;
}
if (token.isCancellationRequested) {
// cancelled -> return without further ado, esp no caching
// of results as they will leak
return undefined;
}
const pid = this._cache.add(hints);
this._disposables.set(pid, new DisposableStore());
const result: extHostProtocol.IInlayHintsDto = { hints: [], cacheId: pid };
for (let i = 0; i < hints.length; i++) {
result.hints.push(this._convertInlayHint(hints[i], [pid, i]));
}
return result;
}
async resolveInlayHint(id: extHostProtocol.ChainedCacheId, token: CancellationToken) {
if (typeof this._provider.resolveInlayHint !== 'function') {
return undefined;
}
const item = this._cache.get(...id);
if (!item) {
return undefined;
}
const hint = await this._provider.resolveInlayHint!(item, token);
if (!hint) {
return undefined;
}
if (token.isCancellationRequested) {
return undefined;
}
return this._convertInlayHint(hint, id);
}
releaseHints(id: number): any {
this._disposables.get(id)?.dispose();
this._disposables.delete(id);
this._cache.delete(id);
}
private _convertInlayHint(hint: vscode.InlayHint, id: extHostProtocol.ChainedCacheId): extHostProtocol.IInlayHintDto {
const disposables = this._disposables.get(id[0]);
if (!disposables) {
throw Error('DisposableStore is missing...');
}
const result: extHostProtocol.IInlayHintDto = {
label: '', // fill-in below
cacheId: id,
tooltip: hint.tooltip && typeConvert.MarkdownString.from(hint.tooltip),
position: typeConvert.Position.from(hint.position),
kind: typeConvert.InlayHintKind.from(hint.kind ?? InlayHintKind.Other),
whitespaceBefore: hint.whitespaceBefore,
whitespaceAfter: hint.whitespaceAfter,
};
if (typeof hint.label === 'string') {
result.label = hint.label;
} else {
result.label = hint.label.map(part => {
let r: modes.InlayHintLabelPart = { label: part.label };
r.collapsible = part.collapsible;
if (Location.isLocation(part.action)) {
r.action = typeConvert.location.from(part.action);
} else if (part.action) {
r.action = this._commands.toInternal(part.action, disposables);
}
return r;
});
}
return result;
}
}
@@ -1984,9 +2063,9 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
registerInlayHintsProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.InlayHintsProvider): vscode.Disposable {
const eventHandle = typeof provider.onDidChangeInlayHints === 'function' ? this._nextHandle() : undefined;
const handle = this._addNewAdapter(new InlayHintsAdapter(this._documents, provider), extension);
const handle = this._addNewAdapter(new InlayHintsAdapter(this._documents, this._commands.converter, provider), extension);
this._proxy.$registerInlayHintsProvider(handle, this._transformDocumentSelector(selector), eventHandle);
this._proxy.$registerInlayHintsProvider(handle, this._transformDocumentSelector(selector), typeof provider.resolveInlayHint === 'function', eventHandle);
let result = this._createDisposable(handle);
if (eventHandle !== undefined) {
@@ -2000,6 +2079,14 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
return this._withAdapter(handle, InlayHintsAdapter, adapter => adapter.provideInlayHints(URI.revive(resource), range, token), undefined);
}
$resolveInlayHint(handle: number, id: extHostProtocol.ChainedCacheId, token: CancellationToken): Promise<extHostProtocol.IInlayHintDto | undefined> {
return this._withAdapter(handle, InlayHintsAdapter, adapter => adapter.resolveInlayHint(id, token), undefined);
}
$releaseInlayHints(handle: number, id: number): void {
this._withAdapter(handle, InlayHintsAdapter, adapter => adapter.releaseHints(id), undefined);
}
// --- links
registerDocumentLinkProvider(extension: IExtensionDescription | undefined, selector: vscode.DocumentSelector, provider: vscode.DocumentLinkProvider): vscode.Disposable {

View File

@@ -55,7 +55,7 @@ export class ExtHostTesting implements ExtHostTestingShape {
/**
* Implements vscode.test.registerTestProvider
*/
public createTestController(controllerId: string, label: string): vscode.TestController {
public createTestController(controllerId: string, label: string, refreshHandler?: () => Thenable<void> | void): vscode.TestController {
if (this.controllers.has(controllerId)) {
throw new Error(`Attempt to insert a duplicate controller with ID "${controllerId}"`);
}
@@ -75,7 +75,14 @@ export class ExtHostTesting implements ExtHostTestingShape {
set label(value: string) {
label = value;
collection.root.label = value;
proxy.$updateControllerLabel(controllerId, label);
proxy.$updateController(controllerId, { label });
},
get refreshHandler() {
return refreshHandler;
},
set refreshHandler(value: (() => Thenable<void> | void) | undefined) {
refreshHandler = value;
proxy.$updateController(controllerId, { canRefresh: !!value });
},
get id() {
return controllerId;
@@ -109,10 +116,7 @@ export class ExtHostTesting implements ExtHostTestingShape {
},
};
// back compat:
(controller as any).createRunConfiguration = controller.createRunProfile;
proxy.$registerTestController(controllerId, label);
proxy.$registerTestController(controllerId, label, !!refreshHandler);
disposable.add(toDisposable(() => proxy.$unregisterTestController(controllerId)));
const info: ControllerInfo = { controller, collection, profiles: profiles };
@@ -178,6 +182,11 @@ export class ExtHostTesting implements ExtHostTestingShape {
this.controllers.get(controllerId)?.profiles.get(profileId)?.configureHandler?.();
}
/** @inheritdoc */
async $refreshTests(controllerId: string) {
await this.controllers.get(controllerId)?.controller.refreshHandler?.();
}
/**
* Updates test results shown to extensions.
* @override

View File

@@ -1152,28 +1152,33 @@ export namespace SignatureHelp {
export namespace InlayHint {
export function from(hint: vscode.InlayHint): modes.InlayHint {
return {
text: hint.text,
position: Position.from(hint.position),
kind: InlayHintKind.from(hint.kind ?? types.InlayHintKind.Other),
whitespaceBefore: hint.whitespaceBefore,
whitespaceAfter: hint.whitespaceAfter
};
}
export function to(hint: modes.InlayHint): vscode.InlayHint {
export function to(converter: CommandsConverter, hint: modes.InlayHint): vscode.InlayHint {
const res = new types.InlayHint(
hint.text,
typeof hint.label === 'string' ? hint.label : hint.label.map(InlayHintLabelPart.to.bind(undefined, converter)),
Position.to(hint.position),
InlayHintKind.to(hint.kind)
);
res.tooltip = htmlContent.isMarkdownString(hint.tooltip) ? MarkdownString.to(hint.tooltip) : hint.tooltip;
res.whitespaceAfter = hint.whitespaceAfter;
res.whitespaceBefore = hint.whitespaceBefore;
return res;
}
}
export namespace InlayHintLabelPart {
export function to(converter: CommandsConverter, part: modes.InlayHintLabelPart): types.InlayHintLabelPart {
const result = new types.InlayHintLabelPart(part.label);
result.collapsible = part.collapsible;
if (modes.Command.is(part.action)) {
result.action = converter.fromInternal(part.action);
} else if (part.action) {
result.action = location.to(part.action);
}
return result;
}
}
export namespace InlayHintKind {
export function from(kind: vscode.InlayHintKind): modes.InlayHintKind {
return kind;

View File

@@ -873,7 +873,7 @@ export enum DiagnosticSeverity {
@es5ClassCompat
export class Location {
static isLocation(thing: any): thing is Location {
static isLocation(thing: any): thing is vscode.Location {
if (thing instanceof Location) {
return true;
}
@@ -1421,15 +1421,29 @@ export enum InlayHintKind {
}
@es5ClassCompat
export class InlayHint {
text: string;
export class InlayHintLabelPart {
label: string;
collapsible?: boolean;
action?: vscode.Command | Location; // invokes provider
constructor(label: string) {
this.label = label;
}
toString(): string {
return this.label;
}
}
@es5ClassCompat
export class InlayHint implements vscode.InlayHint {
label: string | InlayHintLabelPart[];
tooltip?: string | vscode.MarkdownString;
position: Position;
kind?: vscode.InlayHintKind;
whitespaceBefore?: boolean;
whitespaceAfter?: boolean;
constructor(text: string, position: Position, kind?: vscode.InlayHintKind) {
this.text = text;
constructor(label: string | InlayHintLabelPart[], position: Position, kind?: vscode.InlayHintKind) {
this.label = label;
this.position = position;
this.kind = kind;
}