-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d6c374b
commit 555815e
Showing
5 changed files
with
280 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'renoun': minor | ||
--- | ||
|
||
Adds a cache to the `<ExportSource>.getType` method to prevent unnecessary processing of types since this is an expensive operation. Types will now only be resolved the first time they are requested and then cached for subsequent requests unless one of the file dependencies has changed. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import type { Project } from 'ts-morph' | ||
import { statSync } from 'node:fs' | ||
|
||
import { | ||
resolveType, | ||
type ResolvedType, | ||
type SymbolFilter, | ||
} from './resolve-type.js' | ||
|
||
const resolvedTypeCache = new Map< | ||
string, | ||
{ | ||
resolvedType?: ResolvedType | ||
dependencies: Map<string, number> | ||
} | ||
>() | ||
|
||
/** Process all properties of a given type including their default values. */ | ||
export function resolveTypeAtLocation( | ||
project: Project, | ||
filePath: string, | ||
position: number, | ||
filter?: SymbolFilter | ||
) { | ||
const typeId = `${filePath}:${position}` | ||
const sourceFile = project.addSourceFileAtPath(filePath) | ||
const declaration = sourceFile.getDescendantAtPos(position) | ||
|
||
if (!declaration) { | ||
throw new Error( | ||
`[renoun] Could not resolve type at position: ${position}. Try restarting the server or file an issue if you continue to encounter this error.` | ||
) | ||
} | ||
|
||
const exportDeclaration = declaration.getParentOrThrow() | ||
const exportDeclarationType = exportDeclaration.getType() | ||
const cacheEntry = resolvedTypeCache.get(typeId) | ||
|
||
if (cacheEntry) { | ||
let dependenciesChanged = false | ||
|
||
for (const [ | ||
depFilePath, | ||
cachedDepLastModified, | ||
] of cacheEntry.dependencies) { | ||
let depLastModified: number | ||
try { | ||
depLastModified = statSync(depFilePath).mtimeMs | ||
} catch { | ||
// File might have been deleted; invalidate the cache | ||
dependenciesChanged = true | ||
break | ||
} | ||
if (depLastModified !== cachedDepLastModified) { | ||
dependenciesChanged = true | ||
break | ||
} | ||
} | ||
|
||
if (!dependenciesChanged) { | ||
return cacheEntry.resolvedType | ||
} | ||
} | ||
|
||
const dependencies = new Set<string>([filePath]) | ||
const resolvedType = resolveType( | ||
exportDeclarationType, | ||
exportDeclaration, | ||
filter, | ||
true, | ||
undefined, | ||
false, | ||
dependencies | ||
) | ||
|
||
resolvedTypeCache.set(typeId, { | ||
resolvedType, | ||
dependencies: new Map( | ||
Array.from(dependencies).map((filePath) => [ | ||
filePath, | ||
statSync(filePath).mtimeMs, | ||
]) | ||
), | ||
}) | ||
|
||
dependencies.clear() | ||
|
||
return resolvedType | ||
} |
Oops, something went wrong.