提交 001cff3e 编写于 作者: J Johannes Rieken

know hover providers using command links, #29076

上级 e8f7ac78
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
'use strict'; 'use strict';
import { equals } from 'vs/base/common/arrays'; import { equals } from 'vs/base/common/arrays';
import { marked } from 'vs/base/common/marked/marked';
/** /**
* MarkedString can be used to render human readable text. It is either a markdown string * MarkedString can be used to render human readable text. It is either a markdown string
...@@ -38,3 +39,16 @@ export function removeMarkdownEscapes(text: string): string { ...@@ -38,3 +39,16 @@ export function removeMarkdownEscapes(text: string): string {
} }
return text.replace(/\\([\\`*_{}[\]()#+\-.!])/g, '$1'); return text.replace(/\\([\\`*_{}[\]()#+\-.!])/g, '$1');
} }
export function containsCommandLink(value: MarkedString): boolean {
let uses = false;
const renderer = new marked.Renderer();
renderer.link = (href, title, text): string => {
if (href.match(/^command:/i)) {
uses = true;
}
return 'link';
};
marked(value, { renderer });
return uses;
}
...@@ -242,7 +242,7 @@ export function createApiFactory( ...@@ -242,7 +242,7 @@ export function createApiFactory(
return languageFeatures.registerTypeDefinitionProvider(selector, provider); return languageFeatures.registerTypeDefinitionProvider(selector, provider);
}, },
registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable { registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable {
return languageFeatures.registerHoverProvider(selector, provider); return languageFeatures.registerHoverProvider(selector, provider, extension.id);
}, },
registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable { registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable {
return languageFeatures.registerDocumentHighlightProvider(selector, provider); return languageFeatures.registerDocumentHighlightProvider(selector, provider);
......
...@@ -18,10 +18,13 @@ import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHos ...@@ -18,10 +18,13 @@ import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHos
import { ExtHostDiagnostics } from 'vs/workbench/api/node/extHostDiagnostics'; import { ExtHostDiagnostics } from 'vs/workbench/api/node/extHostDiagnostics';
import { IWorkspaceSymbolProvider } from 'vs/workbench/parts/search/common/search'; import { IWorkspaceSymbolProvider } from 'vs/workbench/parts/search/common/search';
import { asWinJsPromise } from 'vs/base/common/async'; import { asWinJsPromise } from 'vs/base/common/async';
import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IRawColorFormatMap, IMainContext } from './extHost.protocol'; import { MainContext, MainThreadTelemetryShape, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IRawColorFormatMap, IMainContext } from './extHost.protocol';
import { regExpLeadsToEndlessLoop } from 'vs/base/common/strings'; import { regExpLeadsToEndlessLoop } from 'vs/base/common/strings';
import { IPosition } from 'vs/editor/common/core/position'; import { IPosition } from 'vs/editor/common/core/position';
import { IRange } from 'vs/editor/common/core/range'; import { IRange } from 'vs/editor/common/core/range';
import { containsCommandLink } from 'vs/base/common/htmlContent';
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
import { once } from 'vs/base/common/functional';
// --- adapter // --- adapter
...@@ -173,12 +176,12 @@ class TypeDefinitionAdapter { ...@@ -173,12 +176,12 @@ class TypeDefinitionAdapter {
class HoverAdapter { class HoverAdapter {
private _documents: ExtHostDocuments; constructor(
private _provider: vscode.HoverProvider; private readonly _documents: ExtHostDocuments,
private readonly _provider: vscode.HoverProvider,
constructor(documents: ExtHostDocuments, provider: vscode.HoverProvider) { private readonly _telemetryLog: (name: string, data: object) => void,
this._documents = documents; ) {
this._provider = provider; //
} }
public provideHover(resource: URI, position: IPosition): TPromise<modes.Hover> { public provideHover(resource: URI, position: IPosition): TPromise<modes.Hover> {
...@@ -187,7 +190,7 @@ class HoverAdapter { ...@@ -187,7 +190,7 @@ class HoverAdapter {
let pos = TypeConverters.toPosition(position); let pos = TypeConverters.toPosition(position);
return asWinJsPromise(token => this._provider.provideHover(doc, pos, token)).then(value => { return asWinJsPromise(token => this._provider.provideHover(doc, pos, token)).then(value => {
if (!value) { if (!value || isFalsyOrEmpty(value.contents)) {
return undefined; return undefined;
} }
if (!value.range) { if (!value.range) {
...@@ -197,7 +200,14 @@ class HoverAdapter { ...@@ -197,7 +200,14 @@ class HoverAdapter {
value.range = new Range(pos, pos); value.range = new Range(pos, pos);
} }
return TypeConverters.fromHover(value); const result = TypeConverters.fromHover(value);
// we wanna know which extension uses command links
// because that is a potential trick-attack on users
if (result.contents.some(containsCommandLink)) {
this._telemetryLog('usesCommandLink', { from: 'hover' });
}
return result;
}); });
} }
} }
...@@ -744,6 +754,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { ...@@ -744,6 +754,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
private static _handlePool: number = 0; private static _handlePool: number = 0;
private _proxy: MainThreadLanguageFeaturesShape; private _proxy: MainThreadLanguageFeaturesShape;
private _telemetry: MainThreadTelemetryShape;
private _documents: ExtHostDocuments; private _documents: ExtHostDocuments;
private _commands: ExtHostCommands; private _commands: ExtHostCommands;
private _heapService: ExtHostHeapService; private _heapService: ExtHostHeapService;
...@@ -759,6 +770,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { ...@@ -759,6 +770,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
diagnostics: ExtHostDiagnostics diagnostics: ExtHostDiagnostics
) { ) {
this._proxy = mainContext.get(MainContext.MainThreadLanguageFeatures); this._proxy = mainContext.get(MainContext.MainThreadLanguageFeatures);
this._telemetry = mainContext.get(MainContext.MainThreadTelemetry);
this._documents = documents; this._documents = documents;
this._commands = commands; this._commands = commands;
this._heapService = heapMonitor; this._heapService = heapMonitor;
...@@ -860,9 +872,12 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { ...@@ -860,9 +872,12 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
// --- extra info // --- extra info
registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable { registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider, extensionId?: string): vscode.Disposable {
const handle = this._nextHandle(); const handle = this._nextHandle();
this._adapter.set(handle, new HoverAdapter(this._documents, provider)); this._adapter.set(handle, new HoverAdapter(this._documents, provider, once((name, data) => {
data['extension'] = extensionId;
this._telemetry.$publicLog(name, data);
})));
this._proxy.$registerHoverProvider(handle, selector); this._proxy.$registerHoverProvider(handle, selector);
return this._createDisposable(handle); return this._createDisposable(handle);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册