generated from JoshuaKGoldberg/create-typescript-app
-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add collectVariableUsage API (#274)
## PR Checklist - [x] Addresses an existing open issue: fixes #263 - [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/ts-api-utils/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22) - [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/ts-api-utils/blob/main/.github/CONTRIBUTING.md) were taken ## Overview Directly ports the exported public `collectVariableUsage` function from `tsutils`. Adds in some unit test coverage too. I'd wanted to refactor its source to be less reliant on class hierarchies... but there's a lot going on there. Out of scope for now. I did apply a few touchups: * Changed "soft" privates to use `#`. * Renamed `VariableInfo` to `UsageInfo`. * It's used both for types and values, so referring to them as "variables" was confusing to me. * Please shout at me if you can think of a better name or believe the original name to be better! * Switches the `const enum`s to just `enum`s. * Adds test coverage for the most common cases. * It's not super thorough, so if you spot some logic you think should be tested, shout at me and I'm happy to add it in if I can
- Loading branch information
1 parent
3f3a485
commit b6a40ea
Showing
18 changed files
with
1,895 additions
and
7 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
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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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,72 @@ | ||
// Code largely based on https://github.com/ajafff/tsutils | ||
// Original license: https://github.com/ajafff/tsutils/blob/26b195358ec36d59f00333115aa3ffd9611ca78b/LICENSE | ||
|
||
import ts from "typescript"; | ||
|
||
import { isFunctionScopeBoundary } from "../scopes"; | ||
import { DeclarationDomain } from "./declarations"; | ||
import type { EnumScope, NamespaceScope } from "./scopes"; | ||
import { InternalUsageInfo, Usage, UsageInfoCallback } from "./usage"; | ||
|
||
export enum ScopeBoundary { | ||
None = 0, | ||
Function = 1, | ||
Block = 2, | ||
Type = 4, | ||
ConditionalType = 8, | ||
} | ||
|
||
export enum ScopeBoundarySelector { | ||
Function = ScopeBoundary.Function, | ||
Block = ScopeBoundarySelector.Function | ScopeBoundary.Block, | ||
Type = ScopeBoundarySelector.Block | ScopeBoundary.Type, | ||
InferType = ScopeBoundary.ConditionalType, | ||
} | ||
|
||
export interface Scope { | ||
addUse(use: Usage, scope?: Scope): void; | ||
addVariable( | ||
identifier: string, | ||
name: ts.PropertyName, | ||
selector: ScopeBoundarySelector, | ||
exported: boolean, | ||
domain: DeclarationDomain, | ||
): void; | ||
createOrReuseEnumScope(name: string, exported: boolean): EnumScope; | ||
createOrReuseNamespaceScope( | ||
name: string, | ||
exported: boolean, | ||
ambient: boolean, | ||
hasExportStatement: boolean, | ||
): NamespaceScope; | ||
end(cb: UsageInfoCallback): void; | ||
getDestinationScope(selector: ScopeBoundarySelector): Scope; | ||
getFunctionScope(): Scope; | ||
getVariables(): Map<string, InternalUsageInfo>; | ||
markExported(name: ts.Identifier, as?: ts.Identifier): void; | ||
} | ||
|
||
export function isBlockScopeBoundary(node: ts.Node): ScopeBoundary { | ||
switch (node.kind) { | ||
case ts.SyntaxKind.Block: { | ||
const parent = node.parent; | ||
return parent.kind !== ts.SyntaxKind.CatchClause && | ||
// blocks inside SourceFile are block scope boundaries | ||
(parent.kind === ts.SyntaxKind.SourceFile || | ||
// blocks that are direct children of a function scope boundary are no scope boundary | ||
// for example the FunctionBlock is part of the function scope of the containing function | ||
!isFunctionScopeBoundary(parent)) | ||
? ScopeBoundary.Block | ||
: ScopeBoundary.None; | ||
} | ||
case ts.SyntaxKind.ForStatement: | ||
case ts.SyntaxKind.ForInStatement: | ||
case ts.SyntaxKind.ForOfStatement: | ||
case ts.SyntaxKind.CaseBlock: | ||
case ts.SyntaxKind.CatchClause: | ||
case ts.SyntaxKind.WithStatement: | ||
return ScopeBoundary.Block; | ||
default: | ||
return ScopeBoundary.None; | ||
} | ||
} |
Oops, something went wrong.