Add logging for MD language features (#152792)

This verbose logging will help track down inefficient calling patterns (such as recomputing stuff)
This commit is contained in:
Matt Bierner 2022-06-21 14:18:36 -07:00 committed by GitHub
parent 4ae2e2ddfd
commit d5a75f2ceb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 105 additions and 52 deletions

View file

@ -19,7 +19,7 @@ import { MdReferencesProvider, registerReferencesSupport } from './languageFeatu
import { registerRenameSupport } from './languageFeatures/rename'; import { registerRenameSupport } from './languageFeatures/rename';
import { registerSmartSelectSupport } from './languageFeatures/smartSelect'; import { registerSmartSelectSupport } from './languageFeatures/smartSelect';
import { registerWorkspaceSymbolSupport } from './languageFeatures/workspaceSymbols'; import { registerWorkspaceSymbolSupport } from './languageFeatures/workspaceSymbols';
import { Logger } from './logger'; import { ILogger, VsCodeOutputLogger } from './logging';
import { IMdParser, MarkdownItEngine, MdParsingProvider } from './markdownEngine'; import { IMdParser, MarkdownItEngine, MdParsingProvider } from './markdownEngine';
import { getMarkdownExtensionContributions } from './markdownExtensions'; import { getMarkdownExtensionContributions } from './markdownExtensions';
import { MdDocumentRenderer } from './preview/documentRenderer'; import { MdDocumentRenderer } from './preview/documentRenderer';
@ -38,7 +38,7 @@ export function activate(context: vscode.ExtensionContext) {
const contributions = getMarkdownExtensionContributions(context); const contributions = getMarkdownExtensionContributions(context);
context.subscriptions.push(contributions); context.subscriptions.push(contributions);
const logger = new Logger(); const logger = new VsCodeOutputLogger();
context.subscriptions.push(logger); context.subscriptions.push(logger);
const cspArbiter = new ExtensionContentSecurityPolicyArbiter(context.globalState, context.workspaceState); const cspArbiter = new ExtensionContentSecurityPolicyArbiter(context.globalState, context.workspaceState);
@ -47,14 +47,14 @@ export function activate(context: vscode.ExtensionContext) {
const engine = new MarkdownItEngine(contributions, githubSlugifier); const engine = new MarkdownItEngine(contributions, githubSlugifier);
const workspaceContents = new VsCodeMdWorkspaceContents(); const workspaceContents = new VsCodeMdWorkspaceContents();
const parser = new MdParsingProvider(engine, workspaceContents); const parser = new MdParsingProvider(engine, workspaceContents);
const tocProvider = new MdTableOfContentsProvider(parser, workspaceContents); const tocProvider = new MdTableOfContentsProvider(parser, workspaceContents, logger);
context.subscriptions.push(workspaceContents, parser, tocProvider); context.subscriptions.push(workspaceContents, parser, tocProvider);
const contentProvider = new MdDocumentRenderer(engine, context, cspArbiter, contributions, logger); const contentProvider = new MdDocumentRenderer(engine, context, cspArbiter, contributions, logger);
const previewManager = new MarkdownPreviewManager(contentProvider, logger, contributions, tocProvider); const previewManager = new MarkdownPreviewManager(contentProvider, logger, contributions, tocProvider);
context.subscriptions.push(previewManager); context.subscriptions.push(previewManager);
context.subscriptions.push(registerMarkdownLanguageFeatures(parser, workspaceContents, commandManager, tocProvider)); context.subscriptions.push(registerMarkdownLanguageFeatures(parser, workspaceContents, commandManager, tocProvider, logger));
context.subscriptions.push(registerMarkdownCommands(commandManager, previewManager, telemetryReporter, cspArbiter, engine, tocProvider)); context.subscriptions.push(registerMarkdownCommands(commandManager, previewManager, telemetryReporter, cspArbiter, engine, tocProvider));
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(() => { context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(() => {
@ -67,12 +67,13 @@ function registerMarkdownLanguageFeatures(
workspaceContents: MdWorkspaceContents, workspaceContents: MdWorkspaceContents,
commandManager: CommandManager, commandManager: CommandManager,
tocProvider: MdTableOfContentsProvider, tocProvider: MdTableOfContentsProvider,
logger: ILogger,
): vscode.Disposable { ): vscode.Disposable {
const selector: vscode.DocumentSelector = { language: 'markdown', scheme: '*' }; const selector: vscode.DocumentSelector = { language: 'markdown', scheme: '*' };
const linkProvider = new MdLinkProvider(parser, workspaceContents); const linkProvider = new MdLinkProvider(parser, workspaceContents, logger);
const referencesProvider = new MdReferencesProvider(parser, workspaceContents, tocProvider); const referencesProvider = new MdReferencesProvider(parser, workspaceContents, tocProvider, logger);
const symbolProvider = new MdDocumentSymbolProvider(tocProvider); const symbolProvider = new MdDocumentSymbolProvider(tocProvider, logger);
return vscode.Disposable.from( return vscode.Disposable.from(
linkProvider, linkProvider,
@ -80,9 +81,9 @@ function registerMarkdownLanguageFeatures(
// Language features // Language features
registerDefinitionSupport(selector, referencesProvider), registerDefinitionSupport(selector, referencesProvider),
registerDiagnosticSupport(selector, workspaceContents, linkProvider, commandManager, referencesProvider, tocProvider), registerDiagnosticSupport(selector, workspaceContents, linkProvider, commandManager, referencesProvider, tocProvider, logger),
registerDocumentLinkSupport(selector, linkProvider), registerDocumentLinkSupport(selector, linkProvider),
registerDocumentSymbolSupport(selector, tocProvider), registerDocumentSymbolSupport(selector, tocProvider, logger),
registerDropIntoEditorSupport(selector), registerDropIntoEditorSupport(selector),
registerFindFileReferenceSupport(commandManager, referencesProvider), registerFindFileReferenceSupport(commandManager, referencesProvider),
registerFoldingSupport(selector, parser, tocProvider), registerFoldingSupport(selector, parser, tocProvider),

View file

@ -6,10 +6,10 @@ import * as vscode from 'vscode';
import { SkinnyTextDocument } from '../workspaceContents'; import { SkinnyTextDocument } from '../workspaceContents';
import { MdReferencesProvider } from './references'; import { MdReferencesProvider } from './references';
export class MdDefinitionProvider implements vscode.DefinitionProvider { export class MdVsCodeDefinitionProvider implements vscode.DefinitionProvider {
constructor( constructor(
private readonly referencesProvider: MdReferencesProvider private readonly referencesProvider: MdReferencesProvider,
) { } ) { }
async provideDefinition(document: SkinnyTextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Definition | undefined> { async provideDefinition(document: SkinnyTextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Definition | undefined> {
@ -23,5 +23,5 @@ export function registerDefinitionSupport(
selector: vscode.DocumentSelector, selector: vscode.DocumentSelector,
referencesProvider: MdReferencesProvider, referencesProvider: MdReferencesProvider,
): vscode.Disposable { ): vscode.Disposable {
return vscode.languages.registerDefinitionProvider(selector, new MdDefinitionProvider(referencesProvider)); return vscode.languages.registerDefinitionProvider(selector, new MdVsCodeDefinitionProvider(referencesProvider));
} }

View file

@ -7,6 +7,7 @@ import * as picomatch from 'picomatch';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls'; import * as nls from 'vscode-nls';
import { CommandManager } from '../commandManager'; import { CommandManager } from '../commandManager';
import { ILogger } from '../logging';
import { MdTableOfContentsProvider } from '../tableOfContents'; import { MdTableOfContentsProvider } from '../tableOfContents';
import { MdTableOfContentsWatcher } from '../test/tableOfContentsWatcher'; import { MdTableOfContentsWatcher } from '../test/tableOfContentsWatcher';
import { Delayer } from '../util/async'; import { Delayer } from '../util/async';
@ -310,6 +311,7 @@ export class DiagnosticManager extends Disposable {
private readonly reporter: DiagnosticReporter, private readonly reporter: DiagnosticReporter,
private readonly referencesProvider: MdReferencesProvider, private readonly referencesProvider: MdReferencesProvider,
tocProvider: MdTableOfContentsProvider, tocProvider: MdTableOfContentsProvider,
private readonly logger: ILogger,
delay = 300, delay = 300,
) { ) {
super(); super();
@ -367,6 +369,8 @@ export class DiagnosticManager extends Disposable {
} }
private async recomputeDiagnosticState(doc: SkinnyTextDocument, token: vscode.CancellationToken): Promise<{ diagnostics: readonly vscode.Diagnostic[]; links: readonly MdLink[]; config: DiagnosticOptions }> { private async recomputeDiagnosticState(doc: SkinnyTextDocument, token: vscode.CancellationToken): Promise<{ diagnostics: readonly vscode.Diagnostic[]; links: readonly MdLink[]; config: DiagnosticOptions }> {
this.logger.verbose('DiagnosticManager', `recomputeDiagnosticState - ${doc.uri}`);
const config = this.configuration.getOptions(doc.uri); const config = this.configuration.getOptions(doc.uri);
if (!config.enabled) { if (!config.enabled) {
return { diagnostics: [], links: [], config }; return { diagnostics: [], links: [], config };
@ -642,6 +646,7 @@ export function registerDiagnosticSupport(
commandManager: CommandManager, commandManager: CommandManager,
referenceProvider: MdReferencesProvider, referenceProvider: MdReferencesProvider,
tocProvider: MdTableOfContentsProvider, tocProvider: MdTableOfContentsProvider,
logger: ILogger,
): vscode.Disposable { ): vscode.Disposable {
const configuration = new VSCodeDiagnosticConfiguration(); const configuration = new VSCodeDiagnosticConfiguration();
const manager = new DiagnosticManager( const manager = new DiagnosticManager(
@ -650,7 +655,8 @@ export function registerDiagnosticSupport(
configuration, configuration,
new DiagnosticCollectionReporter(), new DiagnosticCollectionReporter(),
referenceProvider, referenceProvider,
tocProvider); tocProvider,
logger);
return vscode.Disposable.from( return vscode.Disposable.from(
configuration, configuration,
manager, manager,

View file

@ -14,6 +14,7 @@ import { Disposable } from '../util/dispose';
import { getUriForLinkWithKnownExternalScheme, isOfScheme, Schemes } from '../util/schemes'; import { getUriForLinkWithKnownExternalScheme, isOfScheme, Schemes } from '../util/schemes';
import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents'; import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents';
import { MdDocumentInfoCache } from '../util/workspaceCache'; import { MdDocumentInfoCache } from '../util/workspaceCache';
import { ILogger } from '../logging';
const localize = nls.loadMessageBundle(); const localize = nls.loadMessageBundle();
@ -438,10 +439,14 @@ export class MdLinkProvider extends Disposable {
constructor( constructor(
tokenizer: IMdParser, tokenizer: IMdParser,
workspaceContents: MdWorkspaceContents, workspaceContents: MdWorkspaceContents,
logger: ILogger,
) { ) {
super(); super();
this.linkComputer = new MdLinkComputer(tokenizer); this.linkComputer = new MdLinkComputer(tokenizer);
this._linkCache = this._register(new MdDocumentInfoCache(workspaceContents, doc => this.linkComputer.getAllLinks(doc, noopToken))); this._linkCache = this._register(new MdDocumentInfoCache(workspaceContents, doc => {
logger.verbose('LinkProvider', `compute - ${doc.uri}`);
return this.linkComputer.getAllLinks(doc, noopToken);
}));
} }
public async getLinks(document: SkinnyTextDocument): Promise<{ public async getLinks(document: SkinnyTextDocument): Promise<{

View file

@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { ILogger } from '../logging';
import { MdTableOfContentsProvider, TocEntry } from '../tableOfContents'; import { MdTableOfContentsProvider, TocEntry } from '../tableOfContents';
import { SkinnyTextDocument } from '../workspaceContents'; import { SkinnyTextDocument } from '../workspaceContents';
@ -17,9 +18,11 @@ export class MdDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
constructor( constructor(
private readonly tocProvider: MdTableOfContentsProvider, private readonly tocProvider: MdTableOfContentsProvider,
private readonly logger: ILogger,
) { } ) { }
public async provideDocumentSymbolInformation(document: SkinnyTextDocument): Promise<vscode.SymbolInformation[]> { public async provideDocumentSymbolInformation(document: SkinnyTextDocument): Promise<vscode.SymbolInformation[]> {
this.logger.verbose('DocumentSymbolProvider', `provideDocumentSymbolInformation - ${document.uri}`);
const toc = await this.tocProvider.getForDocument(document); const toc = await this.tocProvider.getForDocument(document);
return toc.entries.map(entry => this.toSymbolInformation(entry)); return toc.entries.map(entry => this.toSymbolInformation(entry));
} }
@ -76,6 +79,7 @@ export class MdDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
export function registerDocumentSymbolSupport( export function registerDocumentSymbolSupport(
selector: vscode.DocumentSelector, selector: vscode.DocumentSelector,
tocProvider: MdTableOfContentsProvider, tocProvider: MdTableOfContentsProvider,
logger: ILogger,
): vscode.Disposable { ): vscode.Disposable {
return vscode.languages.registerDocumentSymbolProvider(selector, new MdDocumentSymbolProvider(tocProvider)); return vscode.languages.registerDocumentSymbolProvider(selector, new MdDocumentSymbolProvider(tocProvider, logger));
} }

View file

@ -4,14 +4,15 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as uri from 'vscode-uri'; import * as uri from 'vscode-uri';
import { ILogger } from '../logging';
import { IMdParser } from '../markdownEngine'; import { IMdParser } from '../markdownEngine';
import { MdTableOfContentsProvider, TocEntry } from '../tableOfContents'; import { MdTableOfContentsProvider, TocEntry } from '../tableOfContents';
import { noopToken } from '../util/cancellation'; import { noopToken } from '../util/cancellation';
import { Disposable } from '../util/dispose'; import { Disposable } from '../util/dispose';
import { looksLikeMarkdownPath } from '../util/file'; import { looksLikeMarkdownPath } from '../util/file';
import { MdWorkspaceInfoCache } from '../util/workspaceCache';
import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents'; import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents';
import { InternalHref, MdLink, MdLinkComputer } from './documentLinks'; import { InternalHref, MdLink, MdLinkComputer } from './documentLinks';
import { MdWorkspaceInfoCache } from '../util/workspaceCache';
/** /**
@ -71,6 +72,7 @@ export class MdReferencesProvider extends Disposable {
private readonly parser: IMdParser, private readonly parser: IMdParser,
private readonly workspaceContents: MdWorkspaceContents, private readonly workspaceContents: MdWorkspaceContents,
private readonly tocProvider: MdTableOfContentsProvider, private readonly tocProvider: MdTableOfContentsProvider,
private readonly logger: ILogger,
) { ) {
super(); super();
@ -79,6 +81,8 @@ export class MdReferencesProvider extends Disposable {
} }
public async getReferencesAtPosition(document: SkinnyTextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<MdReference[]> { public async getReferencesAtPosition(document: SkinnyTextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<MdReference[]> {
this.logger.verbose('ReferencesProvider', `getReferencesAtPosition: ${document.uri}`);
const toc = await this.tocProvider.get(document.uri); const toc = await this.tocProvider.get(document.uri);
if (token.isCancellationRequested) { if (token.isCancellationRequested) {
return []; return [];
@ -93,6 +97,8 @@ export class MdReferencesProvider extends Disposable {
} }
public async getAllReferencesToFile(resource: vscode.Uri, _token: vscode.CancellationToken): Promise<MdReference[]> { public async getAllReferencesToFile(resource: vscode.Uri, _token: vscode.CancellationToken): Promise<MdReference[]> {
this.logger.verbose('ReferencesProvider', `getAllReferencesToFile: ${resource}`);
const allLinksInWorkspace = (await this._linkCache.values()).flat(); const allLinksInWorkspace = (await this._linkCache.values()).flat();
return Array.from(this.findAllLinksToFile(resource, allLinksInWorkspace, undefined)); return Array.from(this.findAllLinksToFile(resource, allLinksInWorkspace, undefined));
} }

View file

@ -26,7 +26,11 @@ namespace Trace {
} }
} }
export class Logger extends Disposable { export interface ILogger {
verbose(title: string, message: string, data?: any): void;
}
export class VsCodeOutputLogger extends Disposable implements ILogger {
private trace?: Trace; private trace?: Trace;
private readonly outputChannel = lazy(() => this._register(vscode.window.createOutputChannel('Markdown'))); private readonly outputChannel = lazy(() => this._register(vscode.window.createOutputChannel('Markdown')));
@ -41,11 +45,11 @@ export class Logger extends Disposable {
this.updateConfiguration(); this.updateConfiguration();
} }
public log(message: string, data?: any): void { public verbose(title: string, message: string, data?: any): void {
if (this.trace === Trace.Verbose) { if (this.trace === Trace.Verbose) {
this.appendLine(`[Log - ${this.now()}] ${message}`); this.appendLine(`[Verbose ${this.now()}] ${title}: ${message}`);
if (data) { if (data) {
this.appendLine(Logger.data2String(data)); this.appendLine(VsCodeOutputLogger.data2String(data));
} }
} }
} }

View file

@ -6,7 +6,7 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls'; import * as nls from 'vscode-nls';
import * as uri from 'vscode-uri'; import * as uri from 'vscode-uri';
import { Logger } from '../logger'; import { ILogger } from '../logging';
import { MarkdownItEngine } from '../markdownEngine'; import { MarkdownItEngine } from '../markdownEngine';
import { MarkdownContributionProvider } from '../markdownExtensions'; import { MarkdownContributionProvider } from '../markdownExtensions';
import { escapeAttribute, getNonce } from '../util/dom'; import { escapeAttribute, getNonce } from '../util/dom';
@ -48,7 +48,7 @@ export class MdDocumentRenderer {
private readonly context: vscode.ExtensionContext, private readonly context: vscode.ExtensionContext,
private readonly cspArbiter: ContentSecurityPolicyArbiter, private readonly cspArbiter: ContentSecurityPolicyArbiter,
private readonly contributionProvider: MarkdownContributionProvider, private readonly contributionProvider: MarkdownContributionProvider,
private readonly logger: Logger private readonly logger: ILogger
) { ) {
this.iconPath = { this.iconPath = {
dark: vscode.Uri.joinPath(this.context.extensionUri, 'media', 'preview-dark.svg'), dark: vscode.Uri.joinPath(this.context.extensionUri, 'media', 'preview-dark.svg'),
@ -80,7 +80,7 @@ export class MdDocumentRenderer {
webviewResourceRoot: resourceProvider.asWebviewUri(markdownDocument.uri).toString(), webviewResourceRoot: resourceProvider.asWebviewUri(markdownDocument.uri).toString(),
}; };
this.logger.log('provideTextDocumentContent', initialData); this.logger.verbose('DocumentRenderer', `provideTextDocumentContent - ${markdownDocument.uri}`, initialData);
// Content Security Policy // Content Security Policy
const nonce = getNonce(); const nonce = getNonce();

View file

@ -6,7 +6,7 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as nls from 'vscode-nls'; import * as nls from 'vscode-nls';
import * as uri from 'vscode-uri'; import * as uri from 'vscode-uri';
import { Logger } from '../logger'; import { ILogger } from '../logging';
import { MarkdownContributionProvider } from '../markdownExtensions'; import { MarkdownContributionProvider } from '../markdownExtensions';
import { MdTableOfContentsProvider } from '../tableOfContents'; import { MdTableOfContentsProvider } from '../tableOfContents';
import { Disposable } from '../util/dispose'; import { Disposable } from '../util/dispose';
@ -118,7 +118,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
private readonly delegate: MarkdownPreviewDelegate, private readonly delegate: MarkdownPreviewDelegate,
private readonly _contentProvider: MdDocumentRenderer, private readonly _contentProvider: MdDocumentRenderer,
private readonly _previewConfigurations: MarkdownPreviewConfigurationManager, private readonly _previewConfigurations: MarkdownPreviewConfigurationManager,
private readonly _logger: Logger, private readonly _logger: ILogger,
private readonly _contributionProvider: MarkdownContributionProvider, private readonly _contributionProvider: MarkdownContributionProvider,
private readonly _tocProvider: MdTableOfContentsProvider, private readonly _tocProvider: MdTableOfContentsProvider,
) { ) {
@ -269,7 +269,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
return; return;
} }
this._logger.log('updateForView', { markdownFile: this._resource }); this._logger.verbose('MarkdownPreview', 'updateForView', { markdownFile: this._resource });
this.line = topLine; this.line = topLine;
this.postMessage({ this.postMessage({
type: 'updateView', type: 'updateView',
@ -502,7 +502,7 @@ export class StaticMarkdownPreview extends Disposable implements IManagedMarkdow
contentProvider: MdDocumentRenderer, contentProvider: MdDocumentRenderer,
previewConfigurations: MarkdownPreviewConfigurationManager, previewConfigurations: MarkdownPreviewConfigurationManager,
topmostLineMonitor: TopmostLineMonitor, topmostLineMonitor: TopmostLineMonitor,
logger: Logger, logger: ILogger,
contributionProvider: MarkdownContributionProvider, contributionProvider: MarkdownContributionProvider,
tocProvider: MdTableOfContentsProvider, tocProvider: MdTableOfContentsProvider,
scrollLine?: number, scrollLine?: number,
@ -518,7 +518,7 @@ export class StaticMarkdownPreview extends Disposable implements IManagedMarkdow
contentProvider: MdDocumentRenderer, contentProvider: MdDocumentRenderer,
private readonly _previewConfigurations: MarkdownPreviewConfigurationManager, private readonly _previewConfigurations: MarkdownPreviewConfigurationManager,
topmostLineMonitor: TopmostLineMonitor, topmostLineMonitor: TopmostLineMonitor,
logger: Logger, logger: ILogger,
contributionProvider: MarkdownContributionProvider, contributionProvider: MarkdownContributionProvider,
tocProvider: MdTableOfContentsProvider, tocProvider: MdTableOfContentsProvider,
scrollLine?: number, scrollLine?: number,
@ -613,7 +613,7 @@ export class DynamicMarkdownPreview extends Disposable implements IManagedMarkdo
webview: vscode.WebviewPanel, webview: vscode.WebviewPanel,
contentProvider: MdDocumentRenderer, contentProvider: MdDocumentRenderer,
previewConfigurations: MarkdownPreviewConfigurationManager, previewConfigurations: MarkdownPreviewConfigurationManager,
logger: Logger, logger: ILogger,
topmostLineMonitor: TopmostLineMonitor, topmostLineMonitor: TopmostLineMonitor,
contributionProvider: MarkdownContributionProvider, contributionProvider: MarkdownContributionProvider,
tocProvider: MdTableOfContentsProvider, tocProvider: MdTableOfContentsProvider,
@ -629,7 +629,7 @@ export class DynamicMarkdownPreview extends Disposable implements IManagedMarkdo
previewColumn: vscode.ViewColumn, previewColumn: vscode.ViewColumn,
contentProvider: MdDocumentRenderer, contentProvider: MdDocumentRenderer,
previewConfigurations: MarkdownPreviewConfigurationManager, previewConfigurations: MarkdownPreviewConfigurationManager,
logger: Logger, logger: ILogger,
topmostLineMonitor: TopmostLineMonitor, topmostLineMonitor: TopmostLineMonitor,
contributionProvider: MarkdownContributionProvider, contributionProvider: MarkdownContributionProvider,
tocProvider: MdTableOfContentsProvider, tocProvider: MdTableOfContentsProvider,
@ -650,7 +650,7 @@ export class DynamicMarkdownPreview extends Disposable implements IManagedMarkdo
input: DynamicPreviewInput, input: DynamicPreviewInput,
private readonly _contentProvider: MdDocumentRenderer, private readonly _contentProvider: MdDocumentRenderer,
private readonly _previewConfigurations: MarkdownPreviewConfigurationManager, private readonly _previewConfigurations: MarkdownPreviewConfigurationManager,
private readonly _logger: Logger, private readonly _logger: ILogger,
private readonly _topmostLineMonitor: TopmostLineMonitor, private readonly _topmostLineMonitor: TopmostLineMonitor,
private readonly _contributionProvider: MarkdownContributionProvider, private readonly _contributionProvider: MarkdownContributionProvider,
private readonly _tocProvider: MdTableOfContentsProvider, private readonly _tocProvider: MdTableOfContentsProvider,

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { Logger } from '../logger'; import { ILogger } from '../logging';
import { MarkdownContributionProvider } from '../markdownExtensions'; import { MarkdownContributionProvider } from '../markdownExtensions';
import { MdTableOfContentsProvider } from '../tableOfContents'; import { MdTableOfContentsProvider } from '../tableOfContents';
import { Disposable, disposeAll } from '../util/dispose'; import { Disposable, disposeAll } from '../util/dispose';
@ -69,7 +69,7 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
public constructor( public constructor(
private readonly _contentProvider: MdDocumentRenderer, private readonly _contentProvider: MdDocumentRenderer,
private readonly _logger: Logger, private readonly _logger: ILogger,
private readonly _contributions: MarkdownContributionProvider, private readonly _contributions: MarkdownContributionProvider,
private readonly _tocProvider: MdTableOfContentsProvider, private readonly _tocProvider: MdTableOfContentsProvider,
) { ) {

View file

@ -4,11 +4,12 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { MdDocumentInfoCache } from './util/workspaceCache'; import { ILogger } from './logging';
import { IMdParser } from './markdownEngine'; import { IMdParser } from './markdownEngine';
import { githubSlugifier, Slug, Slugifier } from './slugify'; import { githubSlugifier, Slug, Slugifier } from './slugify';
import { Disposable } from './util/dispose'; import { Disposable } from './util/dispose';
import { isMarkdownFile } from './util/file'; import { isMarkdownFile } from './util/file';
import { MdDocumentInfoCache } from './util/workspaceCache';
import { MdWorkspaceContents, SkinnyTextDocument } from './workspaceContents'; import { MdWorkspaceContents, SkinnyTextDocument } from './workspaceContents';
export interface TocEntry { export interface TocEntry {
@ -183,9 +184,11 @@ export class MdTableOfContentsProvider extends Disposable {
constructor( constructor(
parser: IMdParser, parser: IMdParser,
workspaceContents: MdWorkspaceContents, workspaceContents: MdWorkspaceContents,
private readonly logger: ILogger,
) { ) {
super(); super();
this._cache = this._register(new MdDocumentInfoCache<TableOfContents>(workspaceContents, doc => { this._cache = this._register(new MdDocumentInfoCache<TableOfContents>(workspaceContents, doc => {
this.logger.verbose('TableOfContentsProvider', `create - ${doc.uri}`);
return TableOfContents.create(parser, doc); return TableOfContents.create(parser, doc);
})); }));
} }

View file

@ -6,7 +6,7 @@
import * as assert from 'assert'; import * as assert from 'assert';
import 'mocha'; import 'mocha';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { MdDefinitionProvider } from '../languageFeatures/definitions'; import { MdVsCodeDefinitionProvider } from '../languageFeatures/definitions';
import { MdReferencesProvider } from '../languageFeatures/references'; import { MdReferencesProvider } from '../languageFeatures/references';
import { MdTableOfContentsProvider } from '../tableOfContents'; import { MdTableOfContentsProvider } from '../tableOfContents';
import { noopToken } from '../util/cancellation'; import { noopToken } from '../util/cancellation';
@ -14,13 +14,14 @@ import { InMemoryDocument } from '../util/inMemoryDocument';
import { MdWorkspaceContents } from '../workspaceContents'; import { MdWorkspaceContents } from '../workspaceContents';
import { createNewMarkdownEngine } from './engine'; import { createNewMarkdownEngine } from './engine';
import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace';
import { nulLogger } from './nulLogging';
import { joinLines, workspacePath } from './util'; import { joinLines, workspacePath } from './util';
function getDefinition(doc: InMemoryDocument, pos: vscode.Position, workspace: MdWorkspaceContents) { function getDefinition(doc: InMemoryDocument, pos: vscode.Position, workspace: MdWorkspaceContents) {
const engine = createNewMarkdownEngine(); const engine = createNewMarkdownEngine();
const referencesProvider = new MdReferencesProvider(engine, workspace, new MdTableOfContentsProvider(engine, workspace)); const referencesProvider = new MdReferencesProvider(engine, workspace, new MdTableOfContentsProvider(engine, workspace, nulLogger), nulLogger);
const provider = new MdDefinitionProvider(referencesProvider); const provider = new MdVsCodeDefinitionProvider(referencesProvider);
return provider.provideDefinition(doc, pos, noopToken); return provider.provideDefinition(doc, pos, noopToken);
} }

View file

@ -17,6 +17,7 @@ import { ResourceMap } from '../util/resourceMap';
import { MdWorkspaceContents } from '../workspaceContents'; import { MdWorkspaceContents } from '../workspaceContents';
import { createNewMarkdownEngine } from './engine'; import { createNewMarkdownEngine } from './engine';
import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace';
import { nulLogger } from './nulLogging';
import { assertRangeEqual, joinLines, workspacePath } from './util'; import { assertRangeEqual, joinLines, workspacePath } from './util';
const defaultDiagnosticsOptions = Object.freeze<DiagnosticOptions>({ const defaultDiagnosticsOptions = Object.freeze<DiagnosticOptions>({
@ -30,8 +31,8 @@ const defaultDiagnosticsOptions = Object.freeze<DiagnosticOptions>({
async function getComputedDiagnostics(doc: InMemoryDocument, workspace: MdWorkspaceContents, options: Partial<DiagnosticOptions> = {}): Promise<vscode.Diagnostic[]> { async function getComputedDiagnostics(doc: InMemoryDocument, workspace: MdWorkspaceContents, options: Partial<DiagnosticOptions> = {}): Promise<vscode.Diagnostic[]> {
const engine = createNewMarkdownEngine(); const engine = createNewMarkdownEngine();
const linkProvider = new MdLinkProvider(engine, workspace); const linkProvider = new MdLinkProvider(engine, workspace, nulLogger);
const tocProvider = new MdTableOfContentsProvider(engine, workspace); const tocProvider = new MdTableOfContentsProvider(engine, workspace, nulLogger);
const computer = new DiagnosticComputer(workspace, linkProvider, tocProvider); const computer = new DiagnosticComputer(workspace, linkProvider, tocProvider);
return ( return (
await computer.getDiagnostics(doc, { ...defaultDiagnosticsOptions, ...options, }, noopToken) await computer.getDiagnostics(doc, { ...defaultDiagnosticsOptions, ...options, }, noopToken)
@ -436,9 +437,9 @@ suite('Markdown: Diagnostics manager', () => {
reporter: DiagnosticReporter = new DiagnosticCollectionReporter(), reporter: DiagnosticReporter = new DiagnosticCollectionReporter(),
) { ) {
const engine = createNewMarkdownEngine(); const engine = createNewMarkdownEngine();
const linkProvider = new MdLinkProvider(engine, workspace); const linkProvider = new MdLinkProvider(engine, workspace, nulLogger);
const tocProvider = new MdTableOfContentsProvider(engine, workspace); const tocProvider = new MdTableOfContentsProvider(engine, workspace, nulLogger);
const referencesProvider = new MdReferencesProvider(engine, workspace, tocProvider); const referencesProvider = new MdReferencesProvider(engine, workspace, tocProvider, nulLogger);
const manager = new DiagnosticManager( const manager = new DiagnosticManager(
workspace, workspace,
new DiagnosticComputer(workspace, linkProvider, tocProvider), new DiagnosticComputer(workspace, linkProvider, tocProvider),
@ -446,6 +447,7 @@ suite('Markdown: Diagnostics manager', () => {
reporter, reporter,
referencesProvider, referencesProvider,
tocProvider, tocProvider,
nulLogger,
0); 0);
_disposables.push(manager, referencesProvider); _disposables.push(manager, referencesProvider);
return manager; return manager;

View file

@ -11,6 +11,7 @@ import { noopToken } from '../util/cancellation';
import { InMemoryDocument } from '../util/inMemoryDocument'; import { InMemoryDocument } from '../util/inMemoryDocument';
import { createNewMarkdownEngine } from './engine'; import { createNewMarkdownEngine } from './engine';
import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace';
import { nulLogger } from './nulLogging';
import { assertRangeEqual, joinLines, workspacePath } from './util'; import { assertRangeEqual, joinLines, workspacePath } from './util';
@ -19,7 +20,7 @@ function getLinksForFile(fileContents: string) {
const workspace = new InMemoryWorkspaceMarkdownDocuments([doc]); const workspace = new InMemoryWorkspaceMarkdownDocuments([doc]);
const engine = createNewMarkdownEngine(); const engine = createNewMarkdownEngine();
const linkProvider = new MdLinkProvider(engine, workspace); const linkProvider = new MdLinkProvider(engine, workspace, nulLogger);
const provider = new MdVsCodeLinkProvider(linkProvider); const provider = new MdVsCodeLinkProvider(linkProvider);
return provider.provideDocumentLinks(doc, noopToken); return provider.provideDocumentLinks(doc, noopToken);
} }

View file

@ -10,6 +10,7 @@ import { MdTableOfContentsProvider } from '../tableOfContents';
import { InMemoryDocument } from '../util/inMemoryDocument'; import { InMemoryDocument } from '../util/inMemoryDocument';
import { createNewMarkdownEngine } from './engine'; import { createNewMarkdownEngine } from './engine';
import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace';
import { nulLogger } from './nulLogging';
import { workspacePath } from './util'; import { workspacePath } from './util';
@ -17,7 +18,7 @@ function getSymbolsForFile(fileContents: string) {
const doc = new InMemoryDocument(workspacePath('test.md'), fileContents); const doc = new InMemoryDocument(workspacePath('test.md'), fileContents);
const workspace = new InMemoryWorkspaceMarkdownDocuments([doc]); const workspace = new InMemoryWorkspaceMarkdownDocuments([doc]);
const engine = createNewMarkdownEngine(); const engine = createNewMarkdownEngine();
const provider = new MdDocumentSymbolProvider(new MdTableOfContentsProvider(engine, workspace)); const provider = new MdDocumentSymbolProvider(new MdTableOfContentsProvider(engine, workspace, nulLogger), nulLogger);
return provider.provideDocumentSymbols(doc); return provider.provideDocumentSymbols(doc);
} }

View file

@ -13,12 +13,13 @@ import { InMemoryDocument } from '../util/inMemoryDocument';
import { MdWorkspaceContents } from '../workspaceContents'; import { MdWorkspaceContents } from '../workspaceContents';
import { createNewMarkdownEngine } from './engine'; import { createNewMarkdownEngine } from './engine';
import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace';
import { nulLogger } from './nulLogging';
import { joinLines, workspacePath } from './util'; import { joinLines, workspacePath } from './util';
function getFileReferences(resource: vscode.Uri, workspace: MdWorkspaceContents) { function getFileReferences(resource: vscode.Uri, workspace: MdWorkspaceContents) {
const engine = createNewMarkdownEngine(); const engine = createNewMarkdownEngine();
const computer = new MdReferencesProvider(engine, workspace, new MdTableOfContentsProvider(engine, workspace)); const computer = new MdReferencesProvider(engine, workspace, new MdTableOfContentsProvider(engine, workspace, nulLogger), nulLogger);
return computer.getAllReferencesToFile(resource, noopToken); return computer.getAllReferencesToFile(resource, noopToken);
} }

View file

@ -11,6 +11,7 @@ import { MdTableOfContentsProvider } from '../tableOfContents';
import { InMemoryDocument } from '../util/inMemoryDocument'; import { InMemoryDocument } from '../util/inMemoryDocument';
import { createNewMarkdownEngine } from './engine'; import { createNewMarkdownEngine } from './engine';
import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace';
import { nulLogger } from './nulLogging';
import { joinLines } from './util'; import { joinLines } from './util';
const testFileName = vscode.Uri.file('test.md'); const testFileName = vscode.Uri.file('test.md');
@ -222,6 +223,6 @@ async function getFoldsForDocument(contents: string) {
const doc = new InMemoryDocument(testFileName, contents); const doc = new InMemoryDocument(testFileName, contents);
const workspace = new InMemoryWorkspaceMarkdownDocuments([doc]); const workspace = new InMemoryWorkspaceMarkdownDocuments([doc]);
const engine = createNewMarkdownEngine(); const engine = createNewMarkdownEngine();
const provider = new MdFoldingProvider(engine, new MdTableOfContentsProvider(engine, workspace)); const provider = new MdFoldingProvider(engine, new MdTableOfContentsProvider(engine, workspace, nulLogger));
return await provider.provideFoldingRanges(doc, {}, new vscode.CancellationTokenSource().token); return await provider.provideFoldingRanges(doc, {}, new vscode.CancellationTokenSource().token);
} }

View file

@ -0,0 +1,12 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ILogger } from '../logging';
export const nulLogger = new class implements ILogger {
verbose(): void {
// noop
}
};

View file

@ -12,6 +12,7 @@ import { noopToken } from '../util/cancellation';
import { InMemoryDocument } from '../util/inMemoryDocument'; import { InMemoryDocument } from '../util/inMemoryDocument';
import { createNewMarkdownEngine } from './engine'; import { createNewMarkdownEngine } from './engine';
import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace';
import { nulLogger } from './nulLogging';
import { CURSOR, getCursorPositions, joinLines, workspacePath } from './util'; import { CURSOR, getCursorPositions, joinLines, workspacePath } from './util';
@ -20,7 +21,7 @@ function getCompletionsAtCursor(resource: vscode.Uri, fileContents: string) {
const workspace = new InMemoryWorkspaceMarkdownDocuments([doc]); const workspace = new InMemoryWorkspaceMarkdownDocuments([doc]);
const engine = createNewMarkdownEngine(); const engine = createNewMarkdownEngine();
const linkProvider = new MdLinkProvider(engine, workspace); const linkProvider = new MdLinkProvider(engine, workspace, nulLogger);
const provider = new MdVsCodePathCompletionProvider(engine, linkProvider); const provider = new MdVsCodePathCompletionProvider(engine, linkProvider);
const cursorPositions = getCursorPositions(fileContents, doc); const cursorPositions = getCursorPositions(fileContents, doc);
return provider.provideCompletionItems(doc, cursorPositions[0], noopToken, { return provider.provideCompletionItems(doc, cursorPositions[0], noopToken, {

View file

@ -13,12 +13,13 @@ import { InMemoryDocument } from '../util/inMemoryDocument';
import { MdWorkspaceContents } from '../workspaceContents'; import { MdWorkspaceContents } from '../workspaceContents';
import { createNewMarkdownEngine } from './engine'; import { createNewMarkdownEngine } from './engine';
import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace';
import { nulLogger } from './nulLogging';
import { joinLines, workspacePath } from './util'; import { joinLines, workspacePath } from './util';
function getReferences(doc: InMemoryDocument, pos: vscode.Position, workspace: MdWorkspaceContents) { function getReferences(doc: InMemoryDocument, pos: vscode.Position, workspace: MdWorkspaceContents) {
const engine = createNewMarkdownEngine(); const engine = createNewMarkdownEngine();
const computer = new MdReferencesProvider(engine, workspace, new MdTableOfContentsProvider(engine, workspace)); const computer = new MdReferencesProvider(engine, workspace, new MdTableOfContentsProvider(engine, workspace, nulLogger), nulLogger);
const provider = new MdVsCodeReferencesProvider(computer); const provider = new MdVsCodeReferencesProvider(computer);
return provider.provideReferences(doc, pos, { includeDeclaration: true }, noopToken); return provider.provideReferences(doc, pos, { includeDeclaration: true }, noopToken);
} }

View file

@ -15,6 +15,7 @@ import { InMemoryDocument } from '../util/inMemoryDocument';
import { MdWorkspaceContents } from '../workspaceContents'; import { MdWorkspaceContents } from '../workspaceContents';
import { createNewMarkdownEngine } from './engine'; import { createNewMarkdownEngine } from './engine';
import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace';
import { nulLogger } from './nulLogging';
import { assertRangeEqual, joinLines, workspacePath } from './util'; import { assertRangeEqual, joinLines, workspacePath } from './util';
@ -23,7 +24,7 @@ import { assertRangeEqual, joinLines, workspacePath } from './util';
*/ */
function prepareRename(doc: InMemoryDocument, pos: vscode.Position, workspace: MdWorkspaceContents): Promise<undefined | { readonly range: vscode.Range; readonly placeholder: string }> { function prepareRename(doc: InMemoryDocument, pos: vscode.Position, workspace: MdWorkspaceContents): Promise<undefined | { readonly range: vscode.Range; readonly placeholder: string }> {
const engine = createNewMarkdownEngine(); const engine = createNewMarkdownEngine();
const referenceComputer = new MdReferencesProvider(engine, workspace, new MdTableOfContentsProvider(engine, workspace)); const referenceComputer = new MdReferencesProvider(engine, workspace, new MdTableOfContentsProvider(engine, workspace, nulLogger), nulLogger);
const renameProvider = new MdVsCodeRenameProvider(workspace, referenceComputer, githubSlugifier); const renameProvider = new MdVsCodeRenameProvider(workspace, referenceComputer, githubSlugifier);
return renameProvider.prepareRename(doc, pos, noopToken); return renameProvider.prepareRename(doc, pos, noopToken);
} }
@ -33,7 +34,7 @@ function prepareRename(doc: InMemoryDocument, pos: vscode.Position, workspace: M
*/ */
function getRenameEdits(doc: InMemoryDocument, pos: vscode.Position, newName: string, workspace: MdWorkspaceContents): Promise<MdWorkspaceEdit | undefined> { function getRenameEdits(doc: InMemoryDocument, pos: vscode.Position, newName: string, workspace: MdWorkspaceContents): Promise<MdWorkspaceEdit | undefined> {
const engine = createNewMarkdownEngine(); const engine = createNewMarkdownEngine();
const referencesProvider = new MdReferencesProvider(engine, workspace, new MdTableOfContentsProvider(engine, workspace)); const referencesProvider = new MdReferencesProvider(engine, workspace, new MdTableOfContentsProvider(engine, workspace, nulLogger), nulLogger);
const renameProvider = new MdVsCodeRenameProvider(workspace, referencesProvider, githubSlugifier); const renameProvider = new MdVsCodeRenameProvider(workspace, referencesProvider, githubSlugifier);
return renameProvider.provideRenameEditsImpl(doc, pos, newName, noopToken); return renameProvider.provideRenameEditsImpl(doc, pos, newName, noopToken);
} }

View file

@ -10,6 +10,7 @@ import { MdTableOfContentsProvider } from '../tableOfContents';
import { InMemoryDocument } from '../util/inMemoryDocument'; import { InMemoryDocument } from '../util/inMemoryDocument';
import { createNewMarkdownEngine } from './engine'; import { createNewMarkdownEngine } from './engine';
import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace';
import { nulLogger } from './nulLogging';
import { CURSOR, getCursorPositions, joinLines } from './util'; import { CURSOR, getCursorPositions, joinLines } from './util';
const testFileName = vscode.Uri.file('test.md'); const testFileName = vscode.Uri.file('test.md');
@ -724,7 +725,7 @@ function getSelectionRangesForDocument(contents: string, pos?: vscode.Position[]
const doc = new InMemoryDocument(testFileName, contents); const doc = new InMemoryDocument(testFileName, contents);
const workspace = new InMemoryWorkspaceMarkdownDocuments([doc]); const workspace = new InMemoryWorkspaceMarkdownDocuments([doc]);
const engine = createNewMarkdownEngine(); const engine = createNewMarkdownEngine();
const provider = new MdSmartSelect(engine, new MdTableOfContentsProvider(engine, workspace)); const provider = new MdSmartSelect(engine, new MdTableOfContentsProvider(engine, workspace, nulLogger));
const positions = pos ? pos : getCursorPositions(contents, doc); const positions = pos ? pos : getCursorPositions(contents, doc);
return provider.provideSelectionRanges(doc, positions, new vscode.CancellationTokenSource().token); return provider.provideSelectionRanges(doc, positions, new vscode.CancellationTokenSource().token);
} }

View file

@ -13,11 +13,12 @@ import { InMemoryDocument } from '../util/inMemoryDocument';
import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents'; import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents';
import { createNewMarkdownEngine } from './engine'; import { createNewMarkdownEngine } from './engine';
import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace';
import { nulLogger } from './nulLogging';
import { workspacePath } from './util'; import { workspacePath } from './util';
function getWorkspaceSymbols(workspace: MdWorkspaceContents, query = ''): Promise<vscode.SymbolInformation[]> { function getWorkspaceSymbols(workspace: MdWorkspaceContents, query = ''): Promise<vscode.SymbolInformation[]> {
const engine = createNewMarkdownEngine(); const engine = createNewMarkdownEngine();
const symbolProvider = new MdDocumentSymbolProvider(new MdTableOfContentsProvider(engine, workspace)); const symbolProvider = new MdDocumentSymbolProvider(new MdTableOfContentsProvider(engine, workspace, nulLogger), nulLogger);
return new MdWorkspaceSymbolProvider(symbolProvider, workspace).provideWorkspaceSymbols(query); return new MdWorkspaceSymbolProvider(symbolProvider, workspace).provideWorkspaceSymbols(query);
} }