Convert IOutlineSupport to DocumentSymbolProvider

This commit is contained in:
Alex Dima 2016-05-19 20:22:42 +02:00
parent 3ca51f6d23
commit 1dd6ea33eb
16 changed files with 416 additions and 354 deletions

View file

@ -427,21 +427,127 @@ export interface DefinitionProvider {
provideDefinition(model:editorCommon.IReadOnlyModel, position:editorCommon.IEditorPosition, token:CancellationToken): Definition | Thenable<Definition>;
}
/**
* Interface used to compute an outline
*/
export interface IOutlineEntry {
label: string;
containerLabel?: string;
type: string;
icon?: string; // icon class or null to use the default images based on the type
range: editorCommon.IRange;
children?: IOutlineEntry[];
export enum SymbolKind {
File,
Module,
Namespace,
Package,
Class,
Method,
Property,
Field,
Constructor,
Enum,
Interface,
Function,
Variable,
Constant,
String,
Number,
Boolean,
Array,
Object,
Key,
Null
}
export namespace SymbolKind {
export interface IOutlineSupport {
getOutline(resource:URI):TPromise<IOutlineEntry[]>;
export function from(kind: number | SymbolKind): string {
switch (kind) {
case SymbolKind.Method:
return 'method';
case SymbolKind.Function:
return 'function';
case SymbolKind.Constructor:
return 'constructor';
case SymbolKind.Variable:
return 'variable';
case SymbolKind.Class:
return 'class';
case SymbolKind.Interface:
return 'interface';
case SymbolKind.Namespace:
return 'namespace';
case SymbolKind.Package:
return 'package';
case SymbolKind.Module:
return 'module';
case SymbolKind.Property:
return 'property';
case SymbolKind.Enum:
return 'enum';
case SymbolKind.String:
return 'string';
case SymbolKind.File:
return 'file';
case SymbolKind.Array:
return 'array';
case SymbolKind.Number:
return 'number';
case SymbolKind.Boolean:
return 'boolean';
case SymbolKind.Object:
return 'object';
case SymbolKind.Key:
return 'key';
case SymbolKind.Null:
return 'null';
}
return 'property';
}
export function to(type: string): SymbolKind {
switch (type) {
case 'method':
return SymbolKind.Method;
case 'function':
return SymbolKind.Function;
case 'constructor':
return SymbolKind.Constructor;
case 'variable':
return SymbolKind.Variable;
case 'class':
return SymbolKind.Class;
case 'interface':
return SymbolKind.Interface;
case 'namespace':
return SymbolKind.Namespace;
case 'package':
return SymbolKind.Package;
case 'module':
return SymbolKind.Module;
case 'property':
return SymbolKind.Property;
case 'enum':
return SymbolKind.Enum;
case 'string':
return SymbolKind.String;
case 'file':
return SymbolKind.File;
case 'array':
return SymbolKind.Array;
case 'number':
return SymbolKind.Number;
case 'boolean':
return SymbolKind.Boolean;
case 'object':
return SymbolKind.Object;
case 'key':
return SymbolKind.Key;
case 'null':
return SymbolKind.Null;
}
return SymbolKind.Property;
}
}
export interface SymbolInformation {
name: string;
containerName?: string;
kind: SymbolKind;
location: Location;
}
export interface DocumentSymbolProvider {
provideDocumentSymbols(model:editorCommon.IReadOnlyModel, token: CancellationToken): SymbolInformation[] | Thenable<SymbolInformation[]>;
}
/**
@ -691,7 +797,7 @@ export const SignatureHelpProviderRegistry = new LanguageFeatureRegistry<Signatu
export const HoverProviderRegistry = new LanguageFeatureRegistry<HoverProvider>();
export const OutlineRegistry = new LanguageFeatureRegistry<IOutlineSupport>();
export const DocumentSymbolProviderRegistry = new LanguageFeatureRegistry<DocumentSymbolProvider>();
export const DocumentHighlightProviderRegistry = new LanguageFeatureRegistry<DocumentHighlightProvider>();

View file

@ -12,10 +12,10 @@ import {IDisposable, dispose} from 'vs/base/common/lifecycle';
import {TPromise} from 'vs/base/common/winjs.base';
import {Range} from 'vs/editor/common/core/range';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {IOutlineEntry, OutlineRegistry} from 'vs/editor/common/modes';
import {SymbolInformation, SymbolKind, DocumentSymbolProviderRegistry} from 'vs/editor/common/modes';
import {ICodeEditor, IViewZone, IViewZoneChangeAccessor} from 'vs/editor/browser/editorBrowser';
import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions';
import {getOutlineEntries, IOutline} from 'vs/editor/contrib/quickOpen/common/quickOpen';
import {getDocumentSymbols, IOutline} from 'vs/editor/contrib/quickOpen/common/quickOpen';
class OutlineViewZone implements IViewZone {
@ -25,15 +25,14 @@ class OutlineViewZone implements IViewZone {
public domNode:HTMLElement;
constructor(range:editorCommon.IRange, outlineType:string)
{
constructor(range:editorCommon.IRange, outlineType:SymbolKind) {
this.afterLineNumber = range.startLineNumber-1;
this.heightInPx = 4;
this.suppressMouseDown = true;
this.domNode = document.createElement('div');
var hr = document.createElement('hr');
hr.className = 'outlineRule ' + outlineType;
hr.className = 'outlineRule ' + SymbolKind.from(outlineType);
this.domNode.appendChild(hr);
}
}
@ -78,8 +77,7 @@ class OutlineMarker {
private _editor:ICodeEditor;
public constructor(range:editorCommon.IRange, outlineType:string, _editor:ICodeEditor, helper:OutlineMarkerHelper, viewZoneChangeAccessor:IViewZoneChangeAccessor)
{
public constructor(range:editorCommon.IRange, outlineType:SymbolKind, _editor:ICodeEditor, helper:OutlineMarkerHelper, viewZoneChangeAccessor:IViewZoneChangeAccessor) {
this._editor = _editor;
this._viewZone = new OutlineViewZone(range, outlineType);
this._viewZoneId = viewZoneChangeAccessor.addZone(this._viewZone);
@ -177,7 +175,7 @@ export class OutlineMarkerContribution implements editorCommon.IEditorContributi
return;
}
if (!OutlineRegistry.has(model)) {
if (!DocumentSymbolProviderRegistry.has(model)) {
return;
}
@ -186,7 +184,7 @@ export class OutlineMarkerContribution implements editorCommon.IEditorContributi
this._currentOutlinePromise.cancel();
}
this._currentOutlinePromise = getOutlineEntries(model);
this._currentOutlinePromise = getDocumentSymbols(model);
this._currentOutlinePromise.then((result) => {
this.renderOutlines(result.entries);
@ -224,7 +222,7 @@ export class OutlineMarkerContribution implements editorCommon.IEditorContributi
scheduler.schedule();
}
private renderOutlines(entries: IOutlineEntry[]): void {
private renderOutlines(entries: SymbolInformation[]): void {
var centeredRange = this._editor.getCenteredRangeInViewport();
var oldMarkersCount = this._markers.length;
this._editor.changeDecorations((decorationsAccessor) => {
@ -244,18 +242,16 @@ export class OutlineMarkerContribution implements editorCommon.IEditorContributi
}
}
private renderOutlinesRecursive(entries: IOutlineEntry[], helper:OutlineMarkerHelper, viewZoneChangeAccessor:IViewZoneChangeAccessor): void {
private renderOutlinesRecursive(entries: SymbolInformation[], helper:OutlineMarkerHelper, viewZoneChangeAccessor:IViewZoneChangeAccessor): void {
if (entries) {
entries.forEach((outline) => {
if (outline.type === 'class' || outline.type === 'method' || outline.type === 'function') {
var range = Range.lift(outline.range);
if (outline.kind === SymbolKind.Class || outline.kind === SymbolKind.Method || outline.kind === SymbolKind.Function) {
var range = Range.lift(outline.location.range);
if (!this.alreadyHasMarkerAtRange(range)) {
var marker = new OutlineMarker(range, outline.type, this._editor, helper, viewZoneChangeAccessor);
var marker = new OutlineMarker(range, outline.kind, this._editor, helper, viewZoneChangeAccessor);
this._markers.push(marker);
}
}
this.renderOutlinesRecursive(outline.children, helper, viewZoneChangeAccessor);
});
}
}

View file

@ -8,7 +8,6 @@
import 'vs/css!./quickOutline';
import * as nls from 'vs/nls';
import * as arrays from 'vs/base/common/arrays';
import {onUnexpectedError} from 'vs/base/common/errors';
import {matchesFuzzy} from 'vs/base/common/filters';
import * as strings from 'vs/base/common/strings';
@ -17,9 +16,9 @@ import {IContext, IHighlight, QuickOpenEntryGroup, QuickOpenModel} from 'vs/base
import {IAutoFocus, Mode} from 'vs/base/parts/quickopen/common/quickOpen';
import {Behaviour} from 'vs/editor/common/editorActionEnablement';
import {ICommonCodeEditor, IEditorActionDescriptorData, IRange} from 'vs/editor/common/editorCommon';
import {IOutlineEntry, OutlineRegistry} from 'vs/editor/common/modes';
import {SymbolInformation, SymbolKind, DocumentSymbolProviderRegistry} from 'vs/editor/common/modes';
import {BaseEditorQuickOpenAction, IDecorator} from './editorQuickOpen';
import {getOutlineEntries, IOutline} from 'vs/editor/contrib/quickOpen/common/quickOpen';
import {getDocumentSymbols, IOutline} from 'vs/editor/contrib/quickOpen/common/quickOpen';
let SCOPE_PREFIX = ':';
@ -108,19 +107,11 @@ class SymbolEntry extends QuickOpenEntryGroup {
}
}
interface OutlineNode {
label: string;
type: string;
range: IRange;
children?: OutlineNode[];
parentScope?: string[];
}
export class QuickOutlineAction extends BaseEditorQuickOpenAction {
public static ID = 'editor.action.quickOutline';
private cachedResult: IOutlineEntry[];
private cachedResult: SymbolInformation[];
constructor(descriptor: IEditorActionDescriptorData, editor: ICommonCodeEditor) {
super(descriptor, editor, nls.localize('QuickOutlineAction.label', "Go to Symbol..."), Behaviour.WidgetFocus | Behaviour.ShowInContextMenu);
@ -131,18 +122,18 @@ export class QuickOutlineAction extends BaseEditorQuickOpenAction {
}
public isSupported(): boolean {
return (OutlineRegistry.has(this.editor.getModel()) && super.isSupported());
return (DocumentSymbolProviderRegistry.has(this.editor.getModel()) && super.isSupported());
}
public run(): TPromise<boolean> {
let model = this.editor.getModel();
if (!OutlineRegistry.has(model)) {
if (!DocumentSymbolProviderRegistry.has(model)) {
return null;
}
// Resolve outline
let promise = getOutlineEntries(model);
let promise = getDocumentSymbols(model);
return promise.then((result: IOutline) => {
if (result.entries.length > 0) {
@ -180,15 +171,9 @@ export class QuickOutlineAction extends BaseEditorQuickOpenAction {
return nls.localize('quickOutlineActionInput', "Type the name of an identifier you wish to navigate to");
}
private toQuickOpenEntries(outline: OutlineNode[], searchValue: string): SymbolEntry[] {
private toQuickOpenEntries(flattened: SymbolInformation[], searchValue: string): SymbolEntry[] {
let results: SymbolEntry[] = [];
// Flatten
let flattened: OutlineNode[] = [];
if (outline) {
this.flatten(outline, flattened);
}
// Convert to Entries
let normalizedSearchValue = searchValue;
if (searchValue.indexOf(SCOPE_PREFIX) === 0) {
@ -197,7 +182,7 @@ export class QuickOutlineAction extends BaseEditorQuickOpenAction {
for (let i = 0; i < flattened.length; i++) {
let element = flattened[i];
let label = strings.trim(element.label);
let label = strings.trim(element.name);
// Check for meatch
let highlights = matchesFuzzy(normalizedSearchValue, label);
@ -205,12 +190,12 @@ export class QuickOutlineAction extends BaseEditorQuickOpenAction {
// Show parent scope as description
let description: string = null;
if (element.parentScope) {
description = arrays.tail(element.parentScope);
if (element.containerName) {
description = element.containerName;
}
// Add
results.push(new SymbolEntry(label, element.type, description, element.range, highlights, this.editor, this));
results.push(new SymbolEntry(label, SymbolKind.from(element.kind), description, element.location.range, highlights, this.editor, this));
}
}
@ -284,27 +269,6 @@ export class QuickOutlineAction extends BaseEditorQuickOpenAction {
return type;
}
private flatten(outline: OutlineNode[], flattened: OutlineNode[], parentScope?: string[]): void {
for (let i = 0; i < outline.length; i++) {
let element = outline[i];
flattened.push(element);
if (parentScope) {
element.parentScope = parentScope;
}
if (element.children) {
let elementScope: string[] = [];
if (parentScope) {
elementScope = parentScope.slice(0);
}
elementScope.push(element.label);
this.flatten(element.children, flattened, elementScope);
}
}
}
private sortNormal(searchValue: string, elementA: SymbolEntry, elementB: SymbolEntry): number {
let elementAName = elementA.getLabel().toLowerCase();
let elementBName = elementB.getLabel().toLowerCase();

View file

@ -11,20 +11,23 @@ import {TPromise} from 'vs/base/common/winjs.base';
import {Range} from 'vs/editor/common/core/range';
import {IModel} from 'vs/editor/common/editorCommon';
import {CommonEditorRegistry} from 'vs/editor/common/editorCommonExtensions';
import {IOutlineEntry, OutlineRegistry} from 'vs/editor/common/modes';
import {SymbolInformation, DocumentSymbolProviderRegistry} from 'vs/editor/common/modes';
import {IModelService} from 'vs/editor/common/services/modelService';
import {asWinJsPromise} from 'vs/base/common/async';
export interface IOutline {
entries: IOutlineEntry[];
entries: SymbolInformation[];
}
export function getOutlineEntries(model: IModel): TPromise<IOutline> {
export function getDocumentSymbols(model: IModel): TPromise<IOutline> {
let entries: IOutlineEntry[] = [];
let entries: SymbolInformation[] = [];
let promises = OutlineRegistry.all(model).map(support => {
let promises = DocumentSymbolProviderRegistry.all(model).map(support => {
return support.getOutline(model.getAssociatedResource()).then(result => {
return asWinJsPromise((token) => {
return support.provideDocumentSymbols(model, token);
}).then(result => {
if (Array.isArray(result)) {
entries.push(...result);
}
@ -34,7 +37,7 @@ export function getOutlineEntries(model: IModel): TPromise<IOutline> {
});
return TPromise.join(promises).then(() => {
let flatEntries: IOutlineEntry[] = [];
let flatEntries: SymbolInformation[] = [];
flatten(flatEntries, entries, '');
flatEntries.sort(compareEntriesUsingStart);
@ -44,22 +47,18 @@ export function getOutlineEntries(model: IModel): TPromise<IOutline> {
});
}
function compareEntriesUsingStart(a: IOutlineEntry, b: IOutlineEntry): number{
return Range.compareRangesUsingStarts(Range.lift(a.range), Range.lift(b.range));
function compareEntriesUsingStart(a: SymbolInformation, b: SymbolInformation): number{
return Range.compareRangesUsingStarts(Range.lift(a.location.range), Range.lift(b.location.range));
}
function flatten(bucket: IOutlineEntry[], entries: IOutlineEntry[], overrideContainerLabel: string): void {
function flatten(bucket: SymbolInformation[], entries: SymbolInformation[], overrideContainerLabel: string): void {
for (let entry of entries) {
bucket.push({
type: entry.type,
range: entry.range,
label: entry.label,
icon: entry.icon,
containerLabel: entry.containerLabel || overrideContainerLabel
kind: entry.kind,
location: entry.location,
name: entry.name,
containerName: entry.containerName || overrideContainerLabel
});
if (entry.children) {
flatten(bucket, entry.children, entry.label);
}
}
}
@ -73,5 +72,5 @@ CommonEditorRegistry.registerLanguageCommand('_executeDocumentSymbolProvider', f
if (!model) {
throw illegalArgument('resource');
}
return getOutlineEntries(model);
return getDocumentSymbols(model);
});

View file

@ -345,7 +345,11 @@ export class CSSMode extends AbstractMode {
// }
// });
modes.OutlineRegistry.register(this.getId(), this);
modes.DocumentSymbolProviderRegistry.register(this.getId(), {
provideDocumentSymbols: (model, token): Thenable<modes.SymbolInformation[]> => {
return wireCancellationToken(token, this._provideDocumentSymbols(model.getAssociatedResource()));
}
});
// modes.DefinitionProviderRegistry.register(this.getId(), {
// provideDefinition: (model, position, token): Thenable<modes.Definition> => {
@ -423,9 +427,9 @@ export class CSSMode extends AbstractMode {
return this._worker((w) => w.provideReferences(resource, position));
}
static $getOutline = OneWorkerAttr(CSSMode, CSSMode.prototype.getOutline);
public getOutline(resource:URI):WinJS.TPromise<modes.IOutlineEntry[]> {
return this._worker((w) => w.getOutline(resource));
static $_provideDocumentSymbols = OneWorkerAttr(CSSMode, CSSMode.prototype._provideDocumentSymbols);
private _provideDocumentSymbols(resource:URI):WinJS.TPromise<modes.SymbolInformation[]> {
return this._worker((w) => w.provideDocumentSymbols(resource));
}
static $findColorDeclarations = OneWorkerAttr(CSSMode, CSSMode.prototype.findColorDeclarations);

View file

@ -211,42 +211,44 @@ export class CSSWorker {
}
public getOutline(resource:URI):winjs.TPromise<modes.IOutlineEntry[]> {
public provideDocumentSymbols(resource:URI):winjs.TPromise<modes.SymbolInformation[]> {
return this.languageService.join().then(() => {
let model = this.resourceService.get(resource),
stylesheet = this.languageService.getStylesheet(resource),
result:modes.IOutlineEntry[] = [];
result:modes.SymbolInformation[] = [];
stylesheet.accept((node) => {
let entry:modes.IOutlineEntry = {
label: null,
type: 'rule',
range: null,
children: []
let entry:modes.SymbolInformation = {
name: null,
kind: modes.SymbolKind.Class, // TODO@Martin: find a good SymbolKind
location: null
};
if(node instanceof nodes.Selector) {
entry.label = node.getText();
entry.name = node.getText();
} else if(node instanceof nodes.VariableDeclaration) {
entry.label = (<nodes.VariableDeclaration> node).getName();
entry.type = 'letiable';
entry.name = (<nodes.VariableDeclaration> node).getName();
entry.kind = modes.SymbolKind.Variable;
} else if(node instanceof nodes.MixinDeclaration) {
entry.label = (<nodes.MixinDeclaration> node).getName();
entry.type = 'method';
entry.name = (<nodes.MixinDeclaration> node).getName();
entry.kind = modes.SymbolKind.Method;
} else if(node instanceof nodes.FunctionDeclaration) {
entry.label = (<nodes.FunctionDeclaration> node).getName();
entry.type = 'function';
entry.name = (<nodes.FunctionDeclaration> node).getName();
entry.kind = modes.SymbolKind.Function;
} else if(node instanceof nodes.Keyframe) {
entry.label = nls.localize('literal.keyframes', "@keyframes {0}", (<nodes.Keyframe> node).getName());
entry.name = nls.localize('literal.keyframes', "@keyframes {0}", (<nodes.Keyframe> node).getName());
} else if(node instanceof nodes.FontFace) {
entry.label = nls.localize('literal.fontface', "@font-face");
entry.name = nls.localize('literal.fontface', "@font-face");
}
if(entry.label) {
entry.range = this._range(node, model, true);
if(entry.name) {
entry.location = {
uri: resource,
range: this._range(node, model, true)
};
result.push(entry);
}

View file

@ -19,7 +19,7 @@ import {IInstantiationService} from 'vs/platform/instantiation/common/instantiat
import {RichEditSupport} from 'vs/editor/common/modes/supports/richEditSupport';
import {wireCancellationToken} from 'vs/base/common/async';
export class JSONMode extends AbstractMode implements modes.IOutlineSupport {
export class JSONMode extends AbstractMode {
public tokenizationSupport: modes.ITokenizationSupport;
public richEditSupport: modes.IRichEditSupport;
@ -74,7 +74,11 @@ export class JSONMode extends AbstractMode implements modes.IOutlineSupport {
this.configSupport = this;
// Initialize Outline support
modes.OutlineRegistry.register(this.getId(), this);
modes.DocumentSymbolProviderRegistry.register(this.getId(), {
provideDocumentSymbols: (model, token): Thenable<modes.SymbolInformation[]> => {
return wireCancellationToken(token, this._provideDocumentSymbols(model.getAssociatedResource()));
}
});
modes.FormatRegistry.register(this.getId(), this);
@ -150,9 +154,9 @@ export class JSONMode extends AbstractMode implements modes.IOutlineSupport {
return this._worker((w) => w.provideHover(resource, position));
}
static $getOutline = OneWorkerAttr(JSONMode, JSONMode.prototype.getOutline);
public getOutline(resource:URI):WinJS.TPromise<modes.IOutlineEntry[]> {
return this._worker((w) => w.getOutline(resource));
static $_provideDocumentSymbols = OneWorkerAttr(JSONMode, JSONMode.prototype._provideDocumentSymbols);
private _provideDocumentSymbols(resource:URI):WinJS.TPromise<modes.SymbolInformation[]> {
return this._worker((w) => w.provideDocumentSymbols(resource));
}
static $formatDocument = OneWorkerAttr(JSONMode, JSONMode.prototype.formatDocument);

View file

@ -344,7 +344,7 @@ export class JSONWorker {
}
public getOutline(resource:URI):WinJS.TPromise<Modes.IOutlineEntry[]> {
public provideDocumentSymbols(resource:URI):WinJS.TPromise<Modes.SymbolInformation[]> {
var modelMirror = this.resourceService.get(resource);
var parser = new Parser.JSONParser();
@ -358,13 +358,20 @@ export class JSONWorker {
var resourceString = resource.toString();
if ((resourceString === 'vscode://defaultsettings/keybindings.json') || Strings.endsWith(resourceString.toLowerCase(), '/user/keybindings.json')) {
if (root.type === 'array') {
var result : Modes.IOutlineEntry[] = [];
var result : Modes.SymbolInformation[] = [];
(<Parser.ArrayASTNode> root).items.forEach((item) => {
if (item.type === 'object') {
var property = (<Parser.ObjectASTNode> item).getFirstProperty('key');
if (property && property.value) {
var range = modelMirror.getRangeFromOffsetAndLength(item.start, item.end - item.start);
result.push({ label: property.value.getValue(), icon: 'function', type: 'string', range: range, children: []});
result.push({
name: property.value.getValue(),
kind: Modes.SymbolKind.String,
location: {
uri: resource,
range: range
}
});
}
}
});
@ -372,10 +379,10 @@ export class JSONWorker {
}
}
function collectOutlineEntries(result: Modes.IOutlineEntry[], node: Parser.ASTNode): Modes.IOutlineEntry[] {
function collectOutlineEntries(result: Modes.SymbolInformation[], node: Parser.ASTNode, containerName: string): Modes.SymbolInformation[] {
if (node.type === 'array') {
(<Parser.ArrayASTNode>node).items.forEach((node:Parser.ASTNode) => {
collectOutlineEntries(result, node);
collectOutlineEntries(result, node, containerName);
});
} else if (node.type === 'object') {
var objectNode = <Parser.ObjectASTNode>node;
@ -384,15 +391,23 @@ export class JSONWorker {
var range = modelMirror.getRangeFromOffsetAndLength(property.start, property.end - property.start);
var valueNode = property.value;
if (valueNode) {
var children = collectOutlineEntries([], valueNode);
var icon = valueNode.type === 'object' ? 'module' : valueNode.type;
result.push({ label: property.key.getValue(), icon: icon, type: valueNode.type, range: range, children: children});
let childContainerName = containerName ? containerName + '.' + property.key.name : property.key.name;
result.push({
name: property.key.getValue(),
kind: getSymbolKind(valueNode.type),
location: {
uri: resource,
range: range,
},
containerName: containerName
});
collectOutlineEntries(result, valueNode, childContainerName);
}
});
}
return result;
}
var result = collectOutlineEntries([], root);
var result = collectOutlineEntries([], root, void 0);
return WinJS.TPromise.as(result);
}
@ -401,3 +416,20 @@ export class JSONWorker {
return WinJS.TPromise.as(JSONFormatter.format(model, range, options));
}
}
function getSymbolKind(nodeType: string): Modes.SymbolKind {
switch (nodeType) {
case 'object':
return Modes.SymbolKind.Module;
case 'string':
return Modes.SymbolKind.String;
case 'number':
return Modes.SymbolKind.Number;
case 'array':
return Modes.SymbolKind.Array;
case 'boolean':
return Modes.SymbolKind.Boolean;
default: // 'null'
return Modes.SymbolKind.Variable;
}
}

View file

@ -18,18 +18,24 @@ import EditorCommon = require('vs/editor/common/editorCommon');
import Modes = require('vs/editor/common/modes');
import WinJS = require('vs/base/common/winjs.base');
interface RelaxedSymbolInformation {
name: string;
containerName?: string;
kind: Modes.SymbolKind;
}
suite('JSON - Worker', () => {
var assertOutline:any = function(actual: Modes.IOutlineEntry[], expected: any[], message: string) {
assert.equal(actual.length, expected.length, message);
for (var i = 0; i < expected.length; i++) {
assert.equal(actual[i].label, expected[i].label, message);
assert.equal(actual[i].type, expected[i].type, message);
var childrenExpected = expected[i].children || [];
var childrenActual = actual[i].children || [];
assertOutline(childrenExpected, childrenActual, message);
}
function toRelaxedSymbolInformation(a: RelaxedSymbolInformation): RelaxedSymbolInformation {
return {
name: a.name,
containerName: a.containerName,
kind: a.kind
};
}
var assertOutline = function(actual: Modes.SymbolInformation[], expected: RelaxedSymbolInformation[], message?: string) {
assert.deepEqual(actual.map(toRelaxedSymbolInformation), expected.map(toRelaxedSymbolInformation), message);
};
function mockWorkerEnv(url: URI, content: string): { worker: jsonworker.JSONWorker; model: EditorCommon.IMirrorModel; } {
@ -80,10 +86,10 @@ suite('JSON - Worker', () => {
return env.worker.navigateValueSet(url, range, up);
};
function getOutline(content: string):WinJS.TPromise<Modes.IOutlineEntry[]> {
function getOutline(content: string):WinJS.TPromise<Modes.SymbolInformation[]> {
var url = URI.parse('test');
var workerEnv = mockWorkerEnv(url, content);
return workerEnv.worker.getOutline(url);
return workerEnv.worker.provideDocumentSymbols(url);
};
var assertSuggestion= function(completion:Modes.ISuggestResult, label:string, documentationLabel?: string) {
@ -96,13 +102,13 @@ suite('JSON - Worker', () => {
test('JSON outline - base types', function(testDone) {
var content= '{ "key1": 1, "key2": "foo", "key3" : true }';
var expected= [
{ label: 'key1', type: 'number'},
{ label: 'key2', type: 'string'},
{ label: 'key3', type: 'boolean'},
var expected = [
{ name: 'key1', kind: Modes.SymbolKind.Number},
{ name: 'key2', kind: Modes.SymbolKind.String},
{ name: 'key3', kind: Modes.SymbolKind.Boolean},
];
getOutline(content).then((entries: Modes.IOutlineEntry[]) => {
getOutline(content).then((entries: Modes.SymbolInformation[]) => {
assertOutline(entries, expected);
}).done(() => testDone(), (error) => {
testDone(error);
@ -113,12 +119,14 @@ suite('JSON - Worker', () => {
var content= '{ "key1": 1, "key2": [ 1, 2, 3 ], "key3" : [ { "k1": 1 }, {"k2": 2 } ] }';
var expected= [
{ label: 'key1', type: 'number'},
{ label: 'key2', type: 'array'},
{ label: 'key3', type: 'array', children : [ { label: 'k1', type: 'number'}, { label: 'k2', type: 'number'} ]},
{ name: 'key1', kind: Modes.SymbolKind.Number},
{ name: 'key2', kind: Modes.SymbolKind.Array},
{ name: 'key3', kind: Modes.SymbolKind.Array},
{ name: 'k1', kind: Modes.SymbolKind.Number, containerName: 'key3'},
{ name: 'k2', kind: Modes.SymbolKind.Number, containerName: 'key3'},
];
getOutline(content).then((entries: Modes.IOutlineEntry[]) => {
getOutline(content).then((entries: Modes.SymbolInformation[]) => {
assertOutline(entries, expected);
}).done(() => testDone(), (error) => {
testDone(error);
@ -129,11 +137,13 @@ suite('JSON - Worker', () => {
var content= '{ "key1": { "key2": true }, "key3" : { "k1": { } }';
var expected= [
{ label: 'key1', type: 'object', children : [ { label: 'key2', type: 'boolean'} ] },
{ label: 'key3', type: 'object', children : [ { label: 'k1', type: 'object'} ] }
{ name: 'key1', kind: Modes.SymbolKind.Module},
{ name: 'key2', kind: Modes.SymbolKind.Boolean, containerName: 'key1' },
{ name: 'key3', kind: Modes.SymbolKind.Module},
{ name: 'k1', kind: Modes.SymbolKind.Module, containerName: 'key3'}
];
getOutline(content).then((entries: Modes.IOutlineEntry[]) => {
getOutline(content).then((entries: Modes.SymbolInformation[]) => {
assertOutline(entries, expected);
}).done(() => testDone(), (error) => {
testDone(error);
@ -144,10 +154,12 @@ suite('JSON - Worker', () => {
var content= '{ "key1": { "key2": true, "key3":, "key4": false } }';
var expected= [
{ label: 'key1', type: 'object', children : [ { label: 'key2', type: 'boolean'}, { label: 'key4', type: 'boolean'} ] },
{ name: 'key1', kind: Modes.SymbolKind.Module },
{ name: 'key2', kind: Modes.SymbolKind.Boolean, containerName: 'key1'},
{ name: 'key4', kind: Modes.SymbolKind.Boolean, containerName: 'key1'},
];
getOutline(content).then((entries: Modes.IOutlineEntry[]) => {
getOutline(content).then((entries: Modes.SymbolInformation[]) => {
assertOutline(entries, expected);
}).done(() => testDone(), (error) => {
testDone(error);

View file

@ -176,7 +176,7 @@ export var language: Types.ILanguage = <Types.ILanguage> {
}
};
export class LESSMode extends AbstractMode implements modes.IOutlineSupport {
export class LESSMode extends AbstractMode {
public inplaceReplaceSupport:modes.IInplaceReplaceSupport;
public configSupport:modes.IConfigurationSupport;
@ -225,7 +225,11 @@ export class LESSMode extends AbstractMode implements modes.IOutlineSupport {
}
});
modes.OutlineRegistry.register(this.getId(), this);
modes.DocumentSymbolProviderRegistry.register(this.getId(), {
provideDocumentSymbols: (model, token): Thenable<modes.SymbolInformation[]> => {
return wireCancellationToken(token, this._provideDocumentSymbols(model.getAssociatedResource()));
}
});
modes.SuggestRegistry.register(this.getId(), {
triggerCharacters: [],
@ -289,9 +293,9 @@ export class LESSMode extends AbstractMode implements modes.IOutlineSupport {
return this._worker((w) => w.provideHover(resource, position));
}
static $getOutline = OneWorkerAttr(LESSMode, LESSMode.prototype.getOutline);
public getOutline(resource:URI):winjs.TPromise<modes.IOutlineEntry[]> {
return this._worker((w) => w.getOutline(resource));
static $_provideDocumentSymbols = OneWorkerAttr(LESSMode, LESSMode.prototype._provideDocumentSymbols);
private _provideDocumentSymbols(resource:URI):winjs.TPromise<modes.SymbolInformation[]> {
return this._worker((w) => w.provideDocumentSymbols(resource));
}
static $_provideDefinition = OneWorkerAttr(LESSMode, LESSMode.prototype._provideDefinition);

View file

@ -278,7 +278,7 @@ export var language = <Types.ILanguage>{
}
};
export class SASSMode extends AbstractMode implements modes.IOutlineSupport {
export class SASSMode extends AbstractMode {
public inplaceReplaceSupport:modes.IInplaceReplaceSupport;
public configSupport:modes.IConfigurationSupport;
@ -326,14 +326,19 @@ export class SASSMode extends AbstractMode implements modes.IOutlineSupport {
}
});
modes.OutlineRegistry.register(this.getId(), this);
modes.DocumentSymbolProviderRegistry.register(this.getId(), {
provideDocumentSymbols: (model, token): Thenable<modes.SymbolInformation[]> => {
return wireCancellationToken(token, this._provideDocumentSymbols(model.getAssociatedResource()));
}
});
modes.SuggestRegistry.register(this.getId(), {
triggerCharacters: [],
shouldAutotriggerSuggest: true,
provideCompletionItems: (model, position, token): Thenable<modes.ISuggestResult[]> => {
return wireCancellationToken(token, this._provideCompletionItems(model.getAssociatedResource(), position));
} });
}
});
this.tokenizationSupport = createTokenizationSupport(modeService, this, lexer);
@ -389,9 +394,9 @@ export class SASSMode extends AbstractMode implements modes.IOutlineSupport {
return this._worker((w) => w.provideHover(resource, position));
}
static $getOutline = OneWorkerAttr(SASSMode, SASSMode.prototype.getOutline);
public getOutline(resource:URI):winjs.TPromise<modes.IOutlineEntry[]> {
return this._worker((w) => w.getOutline(resource));
static $_provideDocumentSymbols = OneWorkerAttr(SASSMode, SASSMode.prototype._provideDocumentSymbols);
private _provideDocumentSymbols(resource:URI):winjs.TPromise<modes.SymbolInformation[]> {
return this._worker((w) => w.provideDocumentSymbols(resource));
}
static $_provideDefinition = OneWorkerAttr(SASSMode, SASSMode.prototype._provideDefinition);

View file

@ -28,7 +28,7 @@ export function register(modelService: IModelService, markerService: IMarkerServ
disposables.push(modes.DocumentHighlightProviderRegistry.register(selector, new OccurrencesAdapter(modelService, worker)));
disposables.push(modes.DefinitionProviderRegistry.register(selector, new DefinitionAdapter(modelService, worker)));
disposables.push(modes.ReferenceProviderRegistry.register(selector, new ReferenceAdapter(modelService, worker)));
disposables.push(modes.OutlineRegistry.register(selector, new OutlineAdapter(modelService, worker)));
disposables.push(modes.DocumentSymbolProviderRegistry.register(selector, new OutlineAdapter(modelService, worker)));
disposables.push(modes.FormatRegistry.register(selector, new FormatAdapter(modelService, worker)));
disposables.push(modes.FormatOnTypeRegistry.register(selector, new FormatAdapter(modelService, worker)));
disposables.push(new DiagnostcsAdapter(defaults, selector, markerService, modelService, worker));
@ -394,28 +394,90 @@ class ReferenceAdapter extends Adapter implements modes.ReferenceProvider {
// --- outline ------
class OutlineAdapter extends Adapter implements modes.IOutlineSupport {
class OutlineAdapter extends Adapter implements modes.DocumentSymbolProvider {
getOutline(resource: URI): TPromise<modes.IOutlineEntry[]> {
return this._worker(resource).then(worker => worker.getNavigationBarItems(resource.toString())).then(items => {
public provideDocumentSymbols(model:editorCommon.IReadOnlyModel, token: CancellationToken): Thenable<modes.SymbolInformation[]> {
const resource = model.getAssociatedResource();
return wireCancellationToken(token, this._worker(resource).then(worker => worker.getNavigationBarItems(resource.toString())).then(items => {
if (!items) {
return;
}
const convert = (item: ts.NavigationBarItem): modes.IOutlineEntry => {
return {
label: item.text,
type: item.kind,
range: this._textSpanToRange(resource, item.spans[0]),
children: item.childItems && item.childItems.map(convert)
function convert(bucket: modes.SymbolInformation[], item: ts.NavigationBarItem, containerLabel?: string): void {
let result: modes.SymbolInformation = {
name: item.text,
kind: outlineTypeTable[item.kind] || modes.SymbolKind.Variable,
location: {
uri: resource,
range: this._textSpanToRange(resource, item.spans[0])
},
containerName: containerLabel
};
};
return items.map(convert);
});
if (item.childItems && item.childItems.length > 0) {
for (let child of item.childItems) {
convert(bucket, child, result.name);
}
}
bucket.push(result);
}
let result: modes.SymbolInformation[] = [];
items.forEach(item => convert(result, item));
return result;
}));
}
}
export class Kind {
public static unknown:string = '';
public static keyword:string = 'keyword';
public static script:string = 'script';
public static module:string = 'module';
public static class:string = 'class';
public static interface:string = 'interface';
public static type:string = 'type';
public static enum:string = 'enum';
public static variable:string = 'var';
public static localVariable:string = 'local var';
public static function:string = 'function';
public static localFunction:string = 'local function';
public static memberFunction:string = 'method';
public static memberGetAccessor:string = 'getter';
public static memberSetAccessor:string = 'setter';
public static memberVariable:string = 'property';
public static constructorImplementation:string = 'constructor';
public static callSignature:string = 'call';
public static indexSignature:string = 'index';
public static constructSignature:string = 'construct';
public static parameter:string = 'parameter';
public static typeParameter:string = 'type parameter';
public static primitiveType:string = 'primitive type';
public static label:string = 'label';
public static alias:string = 'alias';
public static const:string = 'const';
public static let:string = 'let';
public static warning:string = 'warning';
}
let outlineTypeTable: { [kind: string]: modes.SymbolKind } = Object.create(null);
outlineTypeTable[Kind.module] = modes.SymbolKind.Module;
outlineTypeTable[Kind.class] = modes.SymbolKind.Class;
outlineTypeTable[Kind.enum] = modes.SymbolKind.Enum;
outlineTypeTable[Kind.interface] = modes.SymbolKind.Interface;
outlineTypeTable[Kind.memberFunction] = modes.SymbolKind.Method;
outlineTypeTable[Kind.memberVariable] = modes.SymbolKind.Property;
outlineTypeTable[Kind.memberGetAccessor] = modes.SymbolKind.Property;
outlineTypeTable[Kind.memberSetAccessor] = modes.SymbolKind.Property;
outlineTypeTable[Kind.variable] = modes.SymbolKind.Variable;
outlineTypeTable[Kind.const] = modes.SymbolKind.Variable;
outlineTypeTable[Kind.localVariable] = modes.SymbolKind.Variable;
outlineTypeTable[Kind.variable] = modes.SymbolKind.Variable;
outlineTypeTable[Kind.function] = modes.SymbolKind.Function;
outlineTypeTable[Kind.localFunction] = modes.SymbolKind.Function;
// --- formatting ----
class FormatAdapter extends Adapter implements modes.IFormattingSupport {

View file

@ -22,7 +22,7 @@ import {CancellationToken} from 'vs/base/common/cancellation';
// --- adapter
class OutlineAdapter implements modes.IOutlineSupport {
class OutlineAdapter {
private _documents: ExtHostModelService;
private _provider: vscode.DocumentSymbolProvider;
@ -32,7 +32,7 @@ class OutlineAdapter implements modes.IOutlineSupport {
this._provider = provider;
}
getOutline(resource: URI): TPromise<modes.IOutlineEntry[]> {
provideDocumentSymbols(resource: URI): TPromise<modes.SymbolInformation[]> {
let doc = this._documents.getDocumentData(resource).document;
return asWinJsPromise(token => this._provider.provideDocumentSymbols(doc, token)).then(value => {
if (Array.isArray(value)) {
@ -643,8 +643,8 @@ export class ExtHostLanguageFeatures {
return this._createDisposable(handle);
}
$getOutline(handle: number, resource: URI): TPromise<modes.IOutlineEntry[]> {
return this._withAdapter(handle, OutlineAdapter, adapter => adapter.getOutline(resource));
$provideDocumentSymbols(handle: number, resource: URI): TPromise<modes.SymbolInformation[]> {
return this._withAdapter(handle, OutlineAdapter, adapter => adapter.provideDocumentSymbols(resource));
}
// --- code lens
@ -847,9 +847,9 @@ export class MainThreadLanguageFeatures {
// --- outline
$registerOutlineSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> {
this._registrations[handle] = modes.OutlineRegistry.register(selector, <modes.IOutlineSupport>{
getOutline: (resource: URI): TPromise<modes.IOutlineEntry[]> => {
return this._proxy.$getOutline(handle, resource);
this._registrations[handle] = modes.DocumentSymbolProviderRegistry.register(selector, <modes.DocumentSymbolProvider>{
provideDocumentSymbols: (model:IReadOnlyModel, token: CancellationToken): Thenable<modes.SymbolInformation[]> => {
return wireCancellationToken(token, this._proxy.$provideDocumentSymbols(handle, model.getAssociatedResource()));
}
});
return undefined;

View file

@ -15,6 +15,7 @@ import {IPosition, ISelection, IRange, IRangeWithMessage, ISingleEditOperation}
import {IHTMLContentElement} from 'vs/base/common/htmlContent';
import {ITypeBearing} from 'vs/workbench/parts/search/common/search';
import * as vscode from 'vscode';
import URI from 'vs/base/common/uri';
export interface PositionLike {
line: number;
@ -194,114 +195,27 @@ export const TextEdit = {
}
};
export namespace SymbolKind {
export function from(kind: number | types.SymbolKind): string {
switch (kind) {
case types.SymbolKind.Method:
return 'method';
case types.SymbolKind.Function:
return 'function';
case types.SymbolKind.Constructor:
return 'constructor';
case types.SymbolKind.Variable:
return 'variable';
case types.SymbolKind.Class:
return 'class';
case types.SymbolKind.Interface:
return 'interface';
case types.SymbolKind.Namespace:
return 'namespace';
case types.SymbolKind.Package:
return 'package';
case types.SymbolKind.Module:
return 'module';
case types.SymbolKind.Property:
return 'property';
case types.SymbolKind.Enum:
return 'enum';
case types.SymbolKind.String:
return 'string';
case types.SymbolKind.File:
return 'file';
case types.SymbolKind.Array:
return 'array';
case types.SymbolKind.Number:
return 'number';
case types.SymbolKind.Boolean:
return 'boolean';
case types.SymbolKind.Object:
return 'object';
case types.SymbolKind.Key:
return 'key';
case types.SymbolKind.Null:
return 'null';
}
return 'property';
}
export function to(type: string): types.SymbolKind {
switch (type) {
case 'method':
return types.SymbolKind.Method;
case 'function':
return types.SymbolKind.Function;
case 'constructor':
return types.SymbolKind.Constructor;
case 'variable':
return types.SymbolKind.Variable;
case 'class':
return types.SymbolKind.Class;
case 'interface':
return types.SymbolKind.Interface;
case 'namespace':
return types.SymbolKind.Namespace;
case 'package':
return types.SymbolKind.Package;
case 'module':
return types.SymbolKind.Module;
case 'property':
return types.SymbolKind.Property;
case 'enum':
return types.SymbolKind.Enum;
case 'string':
return types.SymbolKind.String;
case 'file':
return types.SymbolKind.File;
case 'array':
return types.SymbolKind.Array;
case 'number':
return types.SymbolKind.Number;
case 'boolean':
return types.SymbolKind.Boolean;
case 'object':
return types.SymbolKind.Object;
case 'key':
return types.SymbolKind.Key;
case 'null':
return types.SymbolKind.Null;
}
return types.SymbolKind.Property;
}
}
export namespace SymbolInformation {
export function fromOutlineEntry(entry: modes.IOutlineEntry): types.SymbolInformation {
return new types.SymbolInformation(entry.label,
SymbolKind.to(entry.type),
toRange(entry.range),
undefined,
entry.containerLabel);
export function fromOutlineEntry(entry: modes.SymbolInformation): types.SymbolInformation {
return new types.SymbolInformation(
entry.name,
entry.kind,
toRange(entry.location.range),
entry.location.uri,
entry.containerName
);
}
export function toOutlineEntry(symbol: vscode.SymbolInformation): modes.IOutlineEntry {
return <modes.IOutlineEntry>{
type: SymbolKind.from(symbol.kind),
range: fromRange(symbol.location.range),
containerLabel: symbol.containerName,
label: symbol.name,
icon: undefined,
export function toOutlineEntry(symbol: vscode.SymbolInformation): modes.SymbolInformation {
return <modes.SymbolInformation>{
name: symbol.name,
kind: symbol.kind,
containerName: symbol.containerName,
location: {
uri: <URI>symbol.location.uri,
range: fromRange(symbol.location.range)
}
};
}
}

View file

@ -8,7 +8,6 @@
import 'vs/css!./media/gotoSymbolHandler';
import {TPromise} from 'vs/base/common/winjs.base';
import nls = require('vs/nls');
import arrays = require('vs/base/common/arrays');
import errors = require('vs/base/common/errors');
import types = require('vs/base/common/types');
import strings = require('vs/base/common/strings');
@ -24,8 +23,8 @@ import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/edito
import {IQuickOpenService} from 'vs/workbench/services/quickopen/common/quickOpenService';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {Position} from 'vs/platform/editor/common/editor';
import {getOutlineEntries} from 'vs/editor/contrib/quickOpen/common/quickOpen';
import {OutlineRegistry} from 'vs/editor/common/modes';
import {getDocumentSymbols} from 'vs/editor/contrib/quickOpen/common/quickOpen';
import {DocumentSymbolProviderRegistry, SymbolInformation, SymbolKind} from 'vs/editor/common/modes';
export const GOTO_SYMBOL_PREFIX = '@';
export const SCOPE_PREFIX = ':';
@ -205,7 +204,7 @@ class OutlineModel extends QuickOpenModel {
private renderGroupLabel(type: string, count: number, outline: Outline): string {
let pattern = outline.outlineGroupLabel[type] || OutlineModel.getDefaultGroupLabelPatterns()[type];
let pattern = OutlineModel.getDefaultGroupLabelPatterns()[type];
if (pattern) {
return strings.format(pattern, count);
}
@ -361,18 +360,7 @@ class SymbolEntry extends EditorQuickOpenEntryGroup {
}
interface Outline {
entries: OutlineNode[];
outlineGroupLabel?: { [name: string]: string; };
}
interface OutlineNode {
label: string;
containerLabel?: string;
type: string;
icon?: string;
range: IRange;
children?: OutlineNode[];
parentScope?: string[];
entries: SymbolInformation[];
}
interface IEditorLineDecoration {
@ -439,7 +427,7 @@ export class GotoSymbolHandler extends QuickOpenHandler {
}
if (model && types.isFunction((<ITokenizedModel>model).getMode)) {
canRun = OutlineRegistry.has(<IModel>model);
canRun = DocumentSymbolProviderRegistry.has(<IModel>model);
}
}
@ -460,54 +448,24 @@ export class GotoSymbolHandler extends QuickOpenHandler {
};
}
private toQuickOpenEntries(outline: Outline): SymbolEntry[] {
private toQuickOpenEntries(flattened: SymbolInformation[]): SymbolEntry[] {
let results: SymbolEntry[] = [];
// Flatten
let flattened: OutlineNode[] = [];
if (outline) {
this.flatten(outline.entries, flattened);
}
for (let i = 0; i < flattened.length; i++) {
let element = flattened[i];
let label = strings.trim(element.label);
let label = strings.trim(element.name);
// Show parent scope as description
let description: string = element.containerLabel;
if (element.parentScope) {
description = arrays.tail(element.parentScope);
}
let description: string = element.containerName;
// Add
let icon = element.icon || element.type;
results.push(new SymbolEntry(i, label, element.type, description, icon, element.range, null, this.editorService, this));
let icon = SymbolKind.from(element.kind);
results.push(new SymbolEntry(i, label, SymbolKind.from(element.kind), description, icon, element.location.range, null, this.editorService, this));
}
return results;
}
private flatten(outline: OutlineNode[], flattened: OutlineNode[], parentScope?: string[]): void {
for (let i = 0; i < outline.length; i++) {
let element = outline[i];
flattened.push(element);
if (parentScope) {
element.parentScope = parentScope;
}
if (element.children) {
let elementScope: string[] = [];
if (parentScope) {
elementScope = parentScope.slice(0);
}
elementScope.push(element.label);
this.flatten(element.children, flattened, elementScope);
}
}
}
private getActiveOutline(): TPromise<OutlineModel> {
if (!this.activeOutlineRequest) {
this.activeOutlineRequest = this.doGetActiveOutline();
@ -533,9 +491,9 @@ export class GotoSymbolHandler extends QuickOpenHandler {
return TPromise.as(this.outlineToModelCache[modelId]);
}
return getOutlineEntries(<IModel>model).then(outline => {
return getDocumentSymbols(<IModel>model).then(outline => {
let model = new OutlineModel(outline, this.toQuickOpenEntries(outline));
let model = new OutlineModel(outline, this.toQuickOpenEntries(outline.entries));
this.outlineToModelCache = {}; // Clear cache, only keep 1 outline
this.outlineToModelCache[modelId] = model;

View file

@ -21,8 +21,8 @@ import {IThreadService} from 'vs/platform/thread/common/thread';
import {ExtHostLanguageFeatures, MainThreadLanguageFeatures} from 'vs/workbench/api/node/extHostLanguageFeatures';
import {ExtHostCommands, MainThreadCommands} from 'vs/workbench/api/node/extHostCommands';
import {ExtHostModelService} from 'vs/workbench/api/node/extHostDocuments';
import {getOutlineEntries} from 'vs/editor/contrib/quickOpen/common/quickOpen';
import {OutlineRegistry, DocumentHighlightKind} from 'vs/editor/common/modes';
import {getDocumentSymbols} from 'vs/editor/contrib/quickOpen/common/quickOpen';
import {DocumentSymbolProviderRegistry, DocumentHighlightKind} from 'vs/editor/common/modes';
import {getCodeLensData} from 'vs/editor/contrib/codelens/common/codelens';
import {getDeclarationsAtPosition} from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration';
import {provideHover} from 'vs/editor/contrib/hover/common/hover';
@ -105,7 +105,7 @@ suite('ExtHostLanguageFeatures', function() {
// --- outline
test('DocumentSymbols, register/deregister', function() {
assert.equal(OutlineRegistry.all(model).length, 0);
assert.equal(DocumentSymbolProviderRegistry.all(model).length, 0);
let d1 = extHost.registerDocumentSymbolProvider(defaultSelector, <vscode.DocumentSymbolProvider>{
provideDocumentSymbols() {
return [];
@ -113,7 +113,7 @@ suite('ExtHostLanguageFeatures', function() {
});
return threadService.sync().then(() => {
assert.equal(OutlineRegistry.all(model).length, 1);
assert.equal(DocumentSymbolProviderRegistry.all(model).length, 1);
d1.dispose();
return threadService.sync();
});
@ -134,7 +134,7 @@ suite('ExtHostLanguageFeatures', function() {
return threadService.sync().then(() => {
return getOutlineEntries(model).then(value => {
return getDocumentSymbols(model).then(value => {
assert.equal(value.entries.length, 1);
});
});
@ -149,12 +149,12 @@ suite('ExtHostLanguageFeatures', function() {
return threadService.sync().then(() => {
return getOutlineEntries(model).then(value => {
return getDocumentSymbols(model).then(value => {
assert.equal(value.entries.length, 1);
let entry = value.entries[0];
assert.equal(entry.label, 'test');
assert.deepEqual(entry.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
assert.equal(entry.name, 'test');
assert.deepEqual(entry.location.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
});
});
});