update proposed API to DocumentSymbol-type, #34968

This commit is contained in:
Johannes Rieken 2018-06-12 12:47:15 +02:00
parent 7fa40d8a12
commit cecfdcde22
7 changed files with 83 additions and 46 deletions

View file

@ -51,7 +51,7 @@ class TypeScriptDocumentSymbolProvider implements vscode.DocumentSymbolProvider
// The root represents the file. Ignore this when showing in the UI
const tree = response.body;
if (tree.childItems) {
const result = new Array<vscode.SymbolInformation2>();
const result = new Array<vscode.DocumentSymbol>();
tree.childItems.forEach(item => TypeScriptDocumentSymbolProvider.convertNavTree(resource.uri, result, item));
return result;
}
@ -89,12 +89,12 @@ class TypeScriptDocumentSymbolProvider implements vscode.DocumentSymbolProvider
}
}
private static convertNavTree(resource: vscode.Uri, bucket: vscode.SymbolInformation[], item: Proto.NavigationTree): boolean {
const symbolInfo = new vscode.SymbolInformation2(
private static convertNavTree(resource: vscode.Uri, bucket: vscode.DocumentSymbol[], item: Proto.NavigationTree): boolean {
const symbolInfo = new vscode.DocumentSymbol(
item.text,
getSymbolKind(item.kind),
'', // no container name
typeConverters.Location.fromTextSpan(resource, item.spans[0]),
typeConverters.Range.fromTextSpan(item.spans[0]),
typeConverters.Range.fromTextSpan(item.spans[0]),
);
let shouldInclude = TypeScriptDocumentSymbolProvider.shouldInclueEntry(item);

View file

@ -377,13 +377,47 @@ declare module 'vscode' {
//#region Joh: hierarchical document symbols, https://github.com/Microsoft/vscode/issues/34968
export class SymbolInformation2 extends SymbolInformation {
definingRange: Range;
children: SymbolInformation2[];
export class DocumentSymbol {
/**
* The name of this symbol.
*/
name: string;
/**
* The kind of this symbol.
*/
kind: SymbolKind;
/**
* The full range of this symbol not including leading/trailing whitespace but everything else.
*/
fullRange: Range;
/**
* The range that should be revealed when this symbol is being selected, e.g the name of a function.
* Must be contained by the [`fullRange`](#DocumentSymbol.fullRange).
*/
gotoRange: Range;
/**
* Children of this symbol, e.g. properties of a class.
*/
children: DocumentSymbol[];
/**
* Creates a new document symbol.
*
* @param name The name of the symbol.
* @param kind The kind of the symbol.
* @param fullRange The full range of the symbol.
* @param gotoRange The range that should be reveal.
*/
constructor(name: string, kind: SymbolKind, fullRange: Range, gotoRange: Range);
}
export interface DocumentSymbolProvider {
provideDocumentSymbols(document: TextDocument, token: CancellationToken): ProviderResult<SymbolInformation[] | SymbolInformation2[]>;
provideDocumentSymbols(document: TextDocument, token: CancellationToken): ProviderResult<SymbolInformation[] | DocumentSymbol[]>;
}
//#endregion

View file

@ -692,12 +692,7 @@ export function createApiFactory(
SourceBreakpoint: extHostTypes.SourceBreakpoint,
StatusBarAlignment: extHostTypes.StatusBarAlignment,
SymbolInformation: extHostTypes.SymbolInformation,
SymbolInformation2: class extends extHostTypes.SymbolInformation2 {
constructor(name, kind, containerName, location) {
checkProposedApiEnabled(extension);
super(name, kind, containerName, location);
}
},
DocumentSymbol: extHostTypes.DocumentSymbol,
SymbolKind: extHostTypes.SymbolKind,
SourceControlInputBoxValidationType: extHostTypes.SourceControlInputBoxValidationType,
TextDocumentSaveReason: extHostTypes.TextDocumentSaveReason,

View file

@ -403,7 +403,7 @@ export class ExtHostApiCommands {
});
}
private _executeDocumentSymbolProvider(resource: URI): Thenable<vscode.SymbolInformation2[]> {
private _executeDocumentSymbolProvider(resource: URI): Thenable<vscode.DocumentSymbol[]> {
const args = {
resource
};

View file

@ -9,7 +9,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { mixin } from 'vs/base/common/objects';
import * as vscode from 'vscode';
import * as typeConvert from 'vs/workbench/api/node/extHostTypeConverters';
import { Range, Disposable, CompletionList, SnippetString, CodeActionKind, SymbolInformation, SymbolInformation2 } from 'vs/workbench/api/node/extHostTypes';
import { Range, Disposable, CompletionList, SnippetString, CodeActionKind, SymbolInformation, DocumentSymbol } from 'vs/workbench/api/node/extHostTypes';
import { ISingleEditOperation } from 'vs/editor/common/model';
import * as modes from 'vs/editor/common/modes';
import { ExtHostHeapService } from 'vs/workbench/api/node/extHostHeapService';
@ -20,7 +20,7 @@ import { asWinJsPromise } from 'vs/base/common/async';
import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IMainContext, IdObject, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, ISerializedLanguageConfiguration, WorkspaceSymbolDto, SuggestResultDto, WorkspaceSymbolsDto, SuggestionDto, CodeActionDto, ISerializedDocumentFilter } from './extHost.protocol';
import { regExpLeadsToEndlessLoop } from 'vs/base/common/strings';
import { IPosition } from 'vs/editor/common/core/position';
import { IRange } from 'vs/editor/common/core/range';
import { IRange, Range as EditorRange } from 'vs/editor/common/core/range';
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
import { isObject } from 'vs/base/common/types';
import { ISelection, Selection } from 'vs/editor/common/core/selection';
@ -43,15 +43,15 @@ class OutlineAdapter {
if (isFalsyOrEmpty(value)) {
return undefined;
}
let [probe] = value;
if (!(probe instanceof SymbolInformation2)) {
value = OutlineAdapter._asSymbolHierarchy(resource, <SymbolInformation[]>value);
if (value[0] instanceof DocumentSymbol) {
return (<DocumentSymbol[]>value).map(typeConvert.DocumentSymbol.from);
} else {
return OutlineAdapter._asDocumentSymbolTree(resource, <SymbolInformation[]>value);
}
return (<SymbolInformation2[]>value).map(typeConvert.DocumentSymbol.from);
});
}
private static _asSymbolHierarchy(resource: URI, info: SymbolInformation[]): vscode.SymbolInformation2[] {
private static _asDocumentSymbolTree(resource: URI, info: SymbolInformation[]): modes.DocumentSymbol[] {
// first sort by start (and end) and then loop over all elements
// and build a tree based on containment.
info = info.slice(0).sort((a, b) => {
@ -61,13 +61,17 @@ class OutlineAdapter {
}
return res;
});
let res: SymbolInformation2[] = [];
let parentStack: SymbolInformation2[] = [];
let res: modes.DocumentSymbol[] = [];
let parentStack: modes.DocumentSymbol[] = [];
for (let i = 0; i < info.length; i++) {
let element = new SymbolInformation2(info[i].name, info[i].kind, '', info[i].location);
element.containerName = info[i].containerName;
element.location = info[i].location; // todo@joh make this proper
element.location.uri = element.location.uri || resource;
let element = <modes.DocumentSymbol>{
name: info[i].name,
kind: typeConvert.SymbolKind.from(info[i].kind),
containerName: info[i].containerName,
fullRange: typeConvert.Range.from(info[i].location.range),
identifierRange: typeConvert.Range.from(info[i].location.range),
children: []
};
while (true) {
if (parentStack.length === 0) {
@ -76,7 +80,7 @@ class OutlineAdapter {
break;
}
let parent = parentStack[parentStack.length - 1];
if (parent.definingRange.contains(element.definingRange) && !parent.definingRange.isEqual(element.definingRange)) {
if (EditorRange.containsRange(parent.fullRange, element.fullRange) && !EditorRange.equalsRange(parent.fullRange, element.fullRange)) {
parent.children.push(element);
parentStack.push(element);
break;

View file

@ -376,25 +376,24 @@ export namespace WorkspaceSymbol {
}
export namespace DocumentSymbol {
export function from(info: vscode.SymbolInformation2): modes.DocumentSymbol {
export function from(info: vscode.DocumentSymbol): modes.DocumentSymbol {
let result: modes.DocumentSymbol = {
name: info.name,
fullRange: Range.from(info.definingRange),
identifierRange: Range.from(info.location.range),
kind: SymbolKind.from(info.kind),
containerName: info.containerName
fullRange: Range.from(info.fullRange),
identifierRange: Range.from(info.gotoRange),
kind: SymbolKind.from(info.kind)
};
if (info.children) {
result.children = info.children.map(from);
}
return result;
}
export function to(info: modes.DocumentSymbol): vscode.SymbolInformation2 {
let result = new types.SymbolInformation2(
export function to(info: modes.DocumentSymbol): vscode.DocumentSymbol {
let result = new types.DocumentSymbol(
info.name,
SymbolKind.to(info.kind),
info.containerName,
new types.Location(undefined, Range.to(info.identifierRange))
Range.to(info.fullRange),
Range.to(info.identifierRange),
);
if (info.children) {
result.children = info.children.map(to) as any;

View file

@ -881,18 +881,23 @@ export class SymbolInformation {
}
}
export class SymbolInformation2 extends SymbolInformation {
definingRange: Range;
children: SymbolInformation2[];
constructor(name: string, kind: SymbolKind, containerName: string, location: Location) {
super(name, kind, containerName, location);
export class DocumentSymbol {
name: string;
kind: SymbolKind;
fullRange: Range;
gotoRange: Range;
children: DocumentSymbol[];
constructor(name: string, kind: SymbolKind, fullRange: Range, gotoRange: Range) {
this.name = name;
this.kind = kind;
this.fullRange = fullRange;
this.gotoRange = gotoRange;
this.children = [];
this.definingRange = location.range;
}
}
export enum CodeActionTrigger {
Automatic = 1,
Manual = 2,