UNPKG

@quick-game/cli

Version:

Command line interface for rapid qg development

50 lines 2.22 kB
// Copyright 2023 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import * as Formatter from '../formatter/formatter.js'; /** * Caches scope trees for whole scripts. * * We use `SDK.Script` as a key to uniquely identify scripts. * `SDK.Script` boils down to "target" + "script ID". This duplicates work in case of * identitical script running on multiple targets (e.g. workers). */ export class ScopeTreeCache { /** If a script failed to parse, we stash null in order to prevent unnecessary re-parsing */ #scopeTrees = new WeakMap(); #pendingScopeTrees = new Map(); static #instance; static instance() { if (!ScopeTreeCache.#instance) { ScopeTreeCache.#instance = new ScopeTreeCache(); } return ScopeTreeCache.#instance; } async scopeTreeForScript(script) { const maybeCachedTree = this.#scopeTrees.get(script); if (maybeCachedTree !== undefined) { // We intentionally return `null` here if the script already failed to parse once. return maybeCachedTree; } const { content } = await script.requestContent(); if (content === null) { return null; } // We check for pending requests for this script AFTER we load the script content. // There must not be any suspension point between checking #pendingScopeTrees and // the actual call to the worker. // This is fine, since #requestContent does similar request de-duplication. const maybePromise = this.#pendingScopeTrees.get(script); if (maybePromise) { return maybePromise; } const sourceType = script.isModule ? 'module' : 'script'; const scopeTreePromise = Formatter.FormatterWorkerPool.formatterWorkerPool().javaScriptScopeTree(content, sourceType); this.#pendingScopeTrees.set(script, scopeTreePromise); const scopeTree = await scopeTreePromise; this.#pendingScopeTrees.delete(script); this.#scopeTrees.set(script, scopeTree); return scopeTree; } } //# sourceMappingURL=ScopeTreeCache.js.map