diff --git a/extensions/typescript-language-features/src/features/documentSymbolProvider.ts b/extensions/typescript-language-features/src/features/documentSymbolProvider.ts index 4da363be0b823a2856a0432041aede8d685d946d..82a23b34cf6d2cb84c95188709bb139047001517 100644 --- a/extensions/typescript-language-features/src/features/documentSymbolProvider.ts +++ b/extensions/typescript-language-features/src/features/documentSymbolProvider.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { DocumentSymbolProvider, SymbolInformation, SymbolKind, TextDocument, CancellationToken, Uri, HierarchicalSymbolInformation } from 'vscode'; +import { DocumentSymbolProvider, SymbolInformation, SymbolKind, TextDocument, CancellationToken, Uri, Hierarchy, SymbolInformation2 } from 'vscode'; import * as Proto from '../protocol'; import * as PConst from '../protocol.const'; @@ -31,7 +31,7 @@ export default class TypeScriptDocumentSymbolProvider implements DocumentSymbolP public constructor( private readonly client: ITypeScriptServiceClient) { } - public async provideDocumentSymbols(resource: TextDocument, token: CancellationToken): Promise { // todo@joh `any[]` temporary hack to make typescript happy... + public async provideDocumentSymbols(resource: TextDocument, token: CancellationToken): Promise { // todo@joh `any[]` temporary hack to make typescript happy... const filepath = this.client.normalizePath(resource.uri); if (!filepath) { return []; @@ -41,24 +41,27 @@ export default class TypeScriptDocumentSymbolProvider implements DocumentSymbolP }; try { - const result: SymbolInformation[] | HierarchicalSymbolInformation[] = []; if (this.client.apiVersion.has206Features()) { const response = await this.client.execute('navtree', args, token); if (response.body) { // The root represents the file. Ignore this when showing in the UI let tree = response.body; if (tree.childItems) { - tree.childItems.forEach(item => TypeScriptDocumentSymbolProvider.convertNavTree(resource.uri, result as HierarchicalSymbolInformation[], item)); + let result = new Array>(); + tree.childItems.forEach(item => TypeScriptDocumentSymbolProvider.convertNavTree(resource.uri, result, item)); + return result; } } } else { const response = await this.client.execute('navbar', args, token); if (response.body) { + let result = new Array(); let foldingMap: ObjectMap = Object.create(null); response.body.forEach(item => TypeScriptDocumentSymbolProvider.convertNavBar(resource.uri, 0, foldingMap, result as SymbolInformation[], item)); + return result; } } - return result; + return []; } catch (e) { return []; } @@ -82,24 +85,25 @@ export default class TypeScriptDocumentSymbolProvider implements DocumentSymbolP } } - private static convertNavTree(resource: Uri, bucket: HierarchicalSymbolInformation[], item: Proto.NavigationTree): void { - const result = new HierarchicalSymbolInformation( + private static convertNavTree(resource: Uri, bucket: Hierarchy[], item: Proto.NavigationTree): void { + if (!TypeScriptDocumentSymbolProvider.shouldInclueEntry(item.text)) { + return; + } + const symbolInfo = new SymbolInformation2( item.text, - '', // detail, e.g. signature etc + '', // todo@joh detail outlineTypeTable[item.kind as string] || SymbolKind.Variable, + typeConverters.Range.fromTextSpan(item.spans[0]), typeConverters.Location.fromTextSpan(resource, item.spans[0]), - typeConverters.Range.fromTextSpan(item.spans[0]) ); + const hierarchy = new Hierarchy(symbolInfo); if (item.childItems && item.childItems.length > 0) { - result.children = []; for (const child of item.childItems) { - TypeScriptDocumentSymbolProvider.convertNavTree(resource, result.children, child); + TypeScriptDocumentSymbolProvider.convertNavTree(resource, hierarchy.children, child); } } + bucket.push(hierarchy); - if (TypeScriptDocumentSymbolProvider.shouldInclueEntry(result.name)) { - bucket.push(result); - } } private static shouldInclueEntry(name: string): boolean { diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 1fe873d9e4e6633176e697ddbbd54d097f7bb499..71389801e4263c919da08e9794db90dbc2cd3d61 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -571,19 +571,20 @@ declare module 'vscode' { //#region Joh: hierarchical document symbols, https://github.com/Microsoft/vscode/issues/34968 - export class HierarchicalSymbolInformation { - name: string; - kind: SymbolKind; + export class Hierarchy { + parent: T; + children: Hierarchy[]; + constructor(element: T); + } + + export class SymbolInformation2 extends SymbolInformation { detail: string; - location: Location; range: Range; - children: HierarchicalSymbolInformation[]; - - constructor(name: string, detail: string, kind: SymbolKind, location: Location, range: Range); + constructor(name: string, detail: string, kind: SymbolKind, range: Range, location: Location); } export interface DocumentSymbolProvider { - provideDocumentSymbols(document: TextDocument, token: CancellationToken): ProviderResult; + provideDocumentSymbols(document: TextDocument, token: CancellationToken): ProviderResult[]>; } //#endregion diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index c36ad62d00fb65fafe3cd2f6c65c27d45da7862e..79da560b9d3ca98dad28fd484a45346763bffce1 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -700,10 +700,16 @@ export function createApiFactory( SourceBreakpoint: extHostTypes.SourceBreakpoint, StatusBarAlignment: extHostTypes.StatusBarAlignment, SymbolInformation: extHostTypes.SymbolInformation, - HierarchicalSymbolInformation: class extends extHostTypes.HierarchicalSymbolInformation { - constructor(name, detail, kind, keyof, range) { + SymbolInformation2: class extends extHostTypes.SymbolInformation2 { + constructor(name, detail, kind, range, location) { checkProposedApiEnabled(extension); - super(name, detail, kind, keyof, range); + super(name, detail, kind, range, location); + } + }, + Hierarchy: class extends extHostTypes.Hierarchy { + constructor(parent: T) { + checkProposedApiEnabled(extension); + super(parent); } }, SymbolKind: extHostTypes.SymbolKind, diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index 5bafe2ef604212c9cd0970075f05971efdb58465..2b777c8a1cd9b57994b9d45d833fdfbcbba3b7ee 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -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, HierarchicalSymbolInformation, SymbolInformation } from 'vs/workbench/api/node/extHostTypes'; +import { Range, Disposable, CompletionList, SnippetString, CodeActionKind, SymbolInformation, Hierarchy, SymbolInformation2 } 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'; @@ -44,14 +44,14 @@ class OutlineAdapter { return undefined; } let [probe] = value; - if (!(probe instanceof HierarchicalSymbolInformation)) { - value = OutlineAdapter._asSymbolTree(value); + if (!(probe instanceof Hierarchy)) { + value = OutlineAdapter._asSymbolHierarchy(value); } - return (value).map(typeConvert.HierarchicalSymbolInformation.from); + return ([]>value).map(typeConvert.HierarchicalSymbolInformation.from); }); } - private static _asSymbolTree(info: SymbolInformation[]): vscode.HierarchicalSymbolInformation[] { + private static _asSymbolHierarchy(info: SymbolInformation[]): vscode.Hierarchy[] { // 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,10 +61,10 @@ class OutlineAdapter { } return res; }); - let res: HierarchicalSymbolInformation[] = []; - let parentStack: HierarchicalSymbolInformation[] = []; + let res: Hierarchy[] = []; + let parentStack: Hierarchy[] = []; for (let i = 0; i < info.length; i++) { - let element = new HierarchicalSymbolInformation(info[i].name, '', info[i].kind, info[i].location, info[i].location.range); + let element = new Hierarchy(new SymbolInformation2(info[i].name, '', info[i].kind, info[i].location.range, info[i].location)); while (true) { if (parentStack.length === 0) { parentStack.push(element); @@ -72,7 +72,7 @@ class OutlineAdapter { break; } let parent = parentStack[parentStack.length - 1]; - if (parent.range.contains(element.range)) { + if (parent.parent.range.contains(element.parent.range)) { parent.children.push(element); parentStack.push(element); break; diff --git a/src/vs/workbench/api/node/extHostTypeConverters.ts b/src/vs/workbench/api/node/extHostTypeConverters.ts index b9e560e598c8cb3ed70aa4ce755095edb0a55588..1112265e3059f04df563386b4f485693c970005a 100644 --- a/src/vs/workbench/api/node/extHostTypeConverters.ts +++ b/src/vs/workbench/api/node/extHostTypeConverters.ts @@ -364,27 +364,27 @@ export namespace SymbolInformation { } export namespace HierarchicalSymbolInformation { - export function from(info: vscode.HierarchicalSymbolInformation): modes.SymbolInformation { + export function from(info: vscode.Hierarchy): modes.SymbolInformation { let result: modes.SymbolInformation = { - name: info.name, - detail: info.detail, - location: location.from(info.location), - definingRange: Range.from(info.range), - kind: SymbolKind.from(info.kind) + name: info.parent.name, + detail: info.parent.detail, + location: location.from(info.parent.location), + definingRange: Range.from(info.parent.range), + kind: SymbolKind.from(info.parent.kind) }; if (info.children) { result.children = info.children.map(from); } return result; } - export function to(info: modes.SymbolInformation): types.HierarchicalSymbolInformation { - let result = new types.HierarchicalSymbolInformation( + export function to(info: modes.SymbolInformation): types.Hierarchy { + let result = new types.Hierarchy(new types.SymbolInformation2( info.name, info.detail, SymbolKind.to(info.kind), + Range.to(info.definingRange), location.to(info.location), - Range.to(info.definingRange) - ); + )); if (info.children) { result.children = info.children.map(to); } diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts index c348fd76cb68172e61398a88af6d0d8a5cdc3f70..32b718698e925422e0a90b19480f0535ba0f0dfc 100644 --- a/src/vs/workbench/api/node/extHostTypes.ts +++ b/src/vs/workbench/api/node/extHostTypes.ts @@ -876,19 +876,24 @@ export class SymbolInformation { } } -export class HierarchicalSymbolInformation { - name: string; - location: Location; +export class SymbolInformation2 extends SymbolInformation { + detail: string; - kind: SymbolKind; range: Range; - children: HierarchicalSymbolInformation[]; - constructor(name: string, detail: string, kind: SymbolKind, location: Location, range: Range) { - this.name = name; - this.kind = kind; - this.location = location; + constructor(name: string, detail: string, kind: SymbolKind, range: Range, location: Location) { + super(name, kind, undefined, location); + this.detail = detail; this.range = range; + } +} + +export class Hierarchy { + parent: T; + children: Hierarchy[]; + + constructor(parent: T) { + this.parent = parent; this.children = []; } }