From a9570a882e92efe9b3b3fa7881001a8a6390a714 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Thu, 24 Oct 2024 15:32:56 -0400 Subject: [PATCH] More logging + the fix, I think --- src/utils/addon-api.ts | 12 +++++++++- src/utils/layout-helpers.ts | 44 +++++++++++++++++++++++++++++++++++++ src/utils/logger.ts | 18 +++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/utils/addon-api.ts b/src/utils/addon-api.ts index d3d4007df..7c818b6a1 100644 --- a/src/utils/addon-api.ts +++ b/src/utils/addon-api.ts @@ -11,7 +11,7 @@ import { } from './layout-helpers'; import { TextDocument } from 'vscode-languageserver-textdocument'; import * as path from 'path'; -import { log, logInfo, logError, safeStringify } from './logger'; +import { log, logInfo, logError, safeStringify, instrumentTime } from './logger'; import Server from '../server'; import ASTPath from './../glimmer-utils'; import DAGMap from 'dag-map'; @@ -188,7 +188,13 @@ function requireUncached(module: string) { } export async function collectProjectProviders(root: string, addons: string[]): Promise { + const time = instrumentTime(`collectProjectProviders(${root})`); + + time.log(`Starting`); const [projectAddonsRoots, projectInRepoAddonsRoots] = await Promise.all([getProjectAddonsRoots(root), getProjectInRepoAddonsRoots(root)]); + + time.log(`found roots`); + const roots = addons .concat([root]) .concat(projectAddonsRoots, projectInRepoAddonsRoots) @@ -226,6 +232,8 @@ export async function collectProjectProviders(root: string, addons: string[]): P } } + time.log(`found ELS addons`); + const result: { definitionProviders: DefinitionResolveFunction[]; referencesProviders: ReferenceResolveFunction[]; @@ -332,6 +340,8 @@ export async function collectProjectProviders(root: string, addons: string[]): P } }); + time.log(`finished crawling dagMap`); + return result; } diff --git a/src/utils/layout-helpers.ts b/src/utils/layout-helpers.ts index 6118733e7..29122550d 100644 --- a/src/utils/layout-helpers.ts +++ b/src/utils/layout-helpers.ts @@ -6,9 +6,14 @@ import { clean, coerce, valid } from 'semver'; import { BaseProject } from '../base-project'; import { fsProvider } from '../fs-provider'; import walkAsync from './walk-async'; +import { instrumentTime } from './logger'; // const GLOBAL_REGISTRY = ['primitive-name'][['relatedFiles']]; +// Don't traverse dependencies we've already seen. +// correct package graph can sort of throw us in to cycles if we don't keep track of this. +const SEEN = new Set(); + export const ADDON_CONFIG_KEY = 'ember-language-server'; export async function asyncFilter(arr: T[], predicate: (value: unknown) => Promise): Promise { @@ -196,6 +201,16 @@ export function cached(_proto: unknown, prop: string, desc: PropertyDescriptor) async function getRecursiveInRepoAddonRoots(root: string, roots: string[]) { const packageData = await asyncGetPackageJSON(root); + + // names are required for packages + if (!packageData.name) return []; + + if (SEEN.has(packageData.name)) { + return []; + } + + SEEN.add(packageData.name); + const emberAddonPaths: string[] = (packageData['ember-addon'] && packageData['ember-addon'].paths) || []; if (roots.length) { @@ -213,6 +228,15 @@ async function getRecursiveInRepoAddonRoots(root: string, roots: string[]) { for (const validRoot of validPaths) { const packInfo = await asyncGetPackageJSON(validRoot); + // names are required for packages + if (!packInfo.name) continue; + + if (SEEN.has(packInfo.name)) { + continue; + } + + SEEN.add(packInfo.name); + // we don't need to go deeper if package itself not an ember-addon or els-extension if (!isEmberAddon(packInfo) && !hasEmberLanguageServerExtension(packInfo)) { continue; @@ -234,8 +258,12 @@ async function getRecursiveInRepoAddonRoots(root: string, roots: string[]) { } export async function getProjectInRepoAddonsRoots(root: string): Promise { + const time = instrumentTime(`getProjectInRepoAddonsRoots(${root})`); + const roots: string[] = await getRecursiveInRepoAddonRoots(root, []); + time.log(`finished getRecursiveInRepoAddonRoots`); + return Array.from(new Set(roots)); } @@ -274,8 +302,16 @@ export async function isGlimmerXProject(root: string) { } export async function getProjectAddonsRoots(root: string, resolvedItems: string[] = [], packageFolderName = 'node_modules') { + const time = instrumentTime(`getProjectInRepoAddonsRoots(${root})`); + const pack = await asyncGetPackageJSON(root); + if (!pack.name) return []; + + if (SEEN.has(pack.name)) return []; + + SEEN.add(pack.name); + if (resolvedItems.length) { if (!isEmberAddon(pack)) { return []; @@ -304,6 +340,12 @@ export async function getProjectAddonsRoots(root: string, resolvedItems: string[ for (const rootItem of roots) { const packInfo = packages[roots.indexOf(rootItem)]; + if (!packInfo.name) continue; + + if (SEEN.has(packInfo.name)) continue; + + SEEN.add(packInfo.name); + // we don't need to go deeper if package itself not an ember-addon or els-extension if (!isEmberAddon(packInfo) && !hasEmberLanguageServerExtension(packInfo)) { continue; @@ -321,6 +363,8 @@ export async function getProjectAddonsRoots(root: string, resolvedItems: string[ } } + time.log(`Finished looping over ${roots.length} roots`); + return recursiveRoots; } diff --git a/src/utils/logger.ts b/src/utils/logger.ts index 26d9bd223..5274a7459 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -35,6 +35,24 @@ export function logInfo(str: string) { } } +export function instrumentTime(label: string) { + let last = Date.now(); + + return { + reset: () => { + last = Date.now(); + }, + log: (msg: string) => { + const now = Date.now(); + const diff = now - last; + + last = now; + + logInfo(`[${label}] +${diff}ms :: ${msg}`); + }, + }; +} + export function setConsole(item: RemoteConsole | null) { remoteConsole = item; }