From 24360c994d9aa9944049fde81666da6369b8ec8b Mon Sep 17 00:00:00 2001 From: Victor Rubezhny Date: Tue, 25 Feb 2020 14:38:38 +0100 Subject: [PATCH] Plug-ins leaking CodeLens, etc. #4472 Fixes: #4472 Signed-off-by: Victor Rubezhny --- packages/plugin-ext/src/common/plugin-api-rpc.ts | 2 ++ .../plugin-ext/src/main/browser/languages-main.ts | 9 +++++++-- packages/plugin-ext/src/plugin/languages.ts | 9 +++++++++ packages/plugin-ext/src/plugin/languages/lens.ts | 12 +++++++++++- .../plugin-ext/src/plugin/languages/link-provider.ts | 6 ++++++ .../plugin-ext/src/plugin/tasks/task-provider.ts | 11 ++--------- 6 files changed, 37 insertions(+), 12 deletions(-) diff --git a/packages/plugin-ext/src/common/plugin-api-rpc.ts b/packages/plugin-ext/src/common/plugin-api-rpc.ts index 7d5c500590acf..abe10089d950b 100644 --- a/packages/plugin-ext/src/common/plugin-api-rpc.ts +++ b/packages/plugin-ext/src/common/plugin-api-rpc.ts @@ -1173,8 +1173,10 @@ export interface LanguagesExt { ): Promise; $provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise; $resolveDocumentLink(handle: number, link: DocumentLink, token: CancellationToken): Promise; + $releaseDocumentLinks(handle: number, ids: number[]): void; $provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise; $resolveCodeLens(handle: number, resource: UriComponents, symbol: CodeLensSymbol, token: CancellationToken): Promise; + $releaseCodeLenses(handle: number, ids: number[]): void; $provideCodeActions( handle: number, resource: UriComponents, diff --git a/packages/plugin-ext/src/main/browser/languages-main.ts b/packages/plugin-ext/src/main/browser/languages-main.ts index b89429abde8c1..8eec2f4d6e267 100644 --- a/packages/plugin-ext/src/main/browser/languages-main.ts +++ b/packages/plugin-ext/src/main/browser/languages-main.ts @@ -55,6 +55,7 @@ import { LanguageSelector } from '@theia/languages/lib/common/language-selector' import { CallHierarchyService, CallHierarchyServiceProvider, Caller, Definition } from '@theia/callhierarchy/lib/browser'; import { toDefinition, toUriComponents, fromDefinition, fromPosition, toCaller } from './callhierarchy/callhierarchy-type-converters'; import { Position, DocumentUri } from 'vscode-languageserver-types'; +import { ObjectIdentifier } from '../../common/object-identifier'; @injectable() export class LanguagesMainImpl implements LanguagesMain, Disposable { @@ -380,7 +381,9 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable { return { links: links.map(link => this.toMonacoLink(link)), dispose: () => { - // TODO this.proxy.$releaseDocumentLinks(handle, links.cacheId); + if (links && Array.isArray(links)) { + this.proxy.$releaseDocumentLinks(handle, links.map(link => ObjectIdentifier.of(link))); + } } }; } @@ -427,7 +430,9 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable { return { lenses, dispose: () => { - // TODO this.proxy.$releaseCodeLenses + if (lenses && Array.isArray(lenses)) { + this.proxy.$releaseCodeLenses(handle, lenses.map(symbol => ObjectIdentifier.of(symbol))); + } } }; } diff --git a/packages/plugin-ext/src/plugin/languages.ts b/packages/plugin-ext/src/plugin/languages.ts index 22d907cf414fc..b9ec55c390ba3 100644 --- a/packages/plugin-ext/src/plugin/languages.ts +++ b/packages/plugin-ext/src/plugin/languages.ts @@ -422,6 +422,11 @@ export class LanguagesExtImpl implements LanguagesExt { this.proxy.$registerDocumentLinkProvider(callId, pluginInfo, this.transformDocumentSelector(selector)); return this.createDisposable(callId); } + + $releaseDocumentLinks(handle: number, ids: number[]): void { + this.withAdapter(handle, LinkProviderAdapter, async adapter => adapter.releaseDocumentLinks(ids)); + } + // ### Document Link Provider end // ### Code Actions Provider begin @@ -474,6 +479,10 @@ export class LanguagesExtImpl implements LanguagesExt { $resolveCodeLens(handle: number, resource: UriComponents, symbol: CodeLensSymbol, token: theia.CancellationToken): Promise { return this.withAdapter(handle, CodeLensAdapter, adapter => adapter.resolveCodeLens(URI.revive(resource), symbol, token)); } + + $releaseCodeLenses(handle: number, ids: number[]): void { + this.withAdapter(handle, CodeLensAdapter, async adapter => adapter.releaseCodeLenses(ids)); + } // ### Code Lens Provider end // ### Code Reference Provider begin diff --git a/packages/plugin-ext/src/plugin/languages/lens.ts b/packages/plugin-ext/src/plugin/languages/lens.ts index 1900f1dc166fb..ffdd514e8e3ad 100644 --- a/packages/plugin-ext/src/plugin/languages/lens.ts +++ b/packages/plugin-ext/src/plugin/languages/lens.ts @@ -55,7 +55,6 @@ export class CodeLensAdapter { range: Converter.fromRange(lens.range)!, command: this.commands.converter.toSafeCommand(lens.command, toDispose) }, cacheId); - // TODO: invalidate caches and dispose command handlers this.cache.set(cacheId, lens); this.disposables.set(cacheId, toDispose); return lensSymbol; @@ -89,4 +88,15 @@ export class CodeLensAdapter { symbol.command = this.commands.converter.toSafeCommand(newLens.command ? newLens.command : CodeLensAdapter.BAD_CMD, disposables); return symbol; } + + releaseCodeLenses(ids: number[]): void { + ids.forEach(id => { + this.cache.delete(id); + const toDispose = this.disposables.get(id); + if (toDispose) { + toDispose.dispose(); + this.disposables.delete(id); + } + }); + } } diff --git a/packages/plugin-ext/src/plugin/languages/link-provider.ts b/packages/plugin-ext/src/plugin/languages/link-provider.ts index ae5291e42042f..e2dadf4340fea 100644 --- a/packages/plugin-ext/src/plugin/languages/link-provider.ts +++ b/packages/plugin-ext/src/plugin/languages/link-provider.ts @@ -70,4 +70,10 @@ export class LinkProviderAdapter { return undefined; }); } + + releaseDocumentLinks(ids: number[]): void { + ids.forEach(id => { + this.cache.delete(id); + }); + } } diff --git a/packages/plugin-ext/src/plugin/tasks/task-provider.ts b/packages/plugin-ext/src/plugin/tasks/task-provider.ts index 0a1e12cb8a34f..fdbaf5e0fc515 100644 --- a/packages/plugin-ext/src/plugin/tasks/task-provider.ts +++ b/packages/plugin-ext/src/plugin/tasks/task-provider.ts @@ -16,12 +16,9 @@ import * as theia from '@theia/plugin'; import * as Converter from '../type-converters'; -import { ObjectIdentifier } from '../../common/object-identifier'; import { TaskDto } from '../../common'; export class TaskProviderAdapter { - private cacheId = 0; - private cache = new Map(); constructor(private readonly provider: theia.TaskProvider) { } @@ -37,9 +34,6 @@ export class TaskProviderAdapter { continue; } - const id = this.cacheId++; - ObjectIdentifier.mixin(data, id); - this.cache.set(id, task); result.push(data); } return result; @@ -50,9 +44,8 @@ export class TaskProviderAdapter { if (typeof this.provider.resolveTask !== 'function') { return Promise.resolve(undefined); } - const id = ObjectIdentifier.of(task); - const cached = this.cache.get(id); - const item = cached ? cached : Converter.toTask(task); + + const item = Converter.toTask(task); if (!item) { return Promise.resolve(undefined); }