fcis 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.plans/001-fcis-analyzer.md +832 -0
- package/.plans/002-fcis-analyzer-improvements.md +205 -0
- package/README.md +272 -0
- package/TECHNICAL.md +386 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1836 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +709 -0
- package/dist/index.js +1845 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -0
- package/pnpm-workspace.yaml +0 -0
- package/src/analyzer.ts +266 -0
- package/src/classification/classifier.ts +156 -0
- package/src/classification/derive-status.ts +171 -0
- package/src/classification/quality-scorer.ts +481 -0
- package/src/cli.ts +286 -0
- package/src/detection/detect-markers.ts +480 -0
- package/src/detection/markers.ts +332 -0
- package/src/extraction/extract-functions.ts +570 -0
- package/src/extraction/extractor.ts +188 -0
- package/src/index.ts +111 -0
- package/src/reporting/report-console.ts +416 -0
- package/src/reporting/report-json.ts +232 -0
- package/src/scoring/scorer.ts +504 -0
- package/src/types.ts +248 -0
- package/tests/classifier.test.ts +480 -0
- package/tests/derive-status.test.ts +464 -0
- package/tests/detect-markers.test.ts +639 -0
- package/tests/extractor.test.ts +155 -0
- package/tests/integration.test.ts +706 -0
- package/tests/quality-scorer.test.ts +650 -0
- package/tests/scorer.test.ts +768 -0
- package/tsconfig.json +34 -0
- package/tsup.config.ts +17 -0
- package/vendor/ts-morph/.editorconfig +10 -0
- package/vendor/ts-morph/.gitattributes +11 -0
- package/vendor/ts-morph/.github/CODE_OF_CONDUCT.md +77 -0
- package/vendor/ts-morph/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
- package/vendor/ts-morph/.github/ISSUE_TEMPLATE/custom.md +4 -0
- package/vendor/ts-morph/.github/ISSUE_TEMPLATE/feature_request.md +18 -0
- package/vendor/ts-morph/.github/workflows/ci.yml +50 -0
- package/vendor/ts-morph/.github/workflows/publish.yml +53 -0
- package/vendor/ts-morph/.vscode/settings.json +10 -0
- package/vendor/ts-morph/CONTRIBUTING.md +23 -0
- package/vendor/ts-morph/DEVELOPMENT.md +32 -0
- package/vendor/ts-morph/LICENSE +21 -0
- package/vendor/ts-morph/deno.json +8 -0
- package/vendor/ts-morph/deno.lock +1233 -0
- package/vendor/ts-morph/docs/CNAME +1 -0
- package/vendor/ts-morph/docs/Gemfile +2 -0
- package/vendor/ts-morph/docs/_config.yml +5 -0
- package/vendor/ts-morph/docs/_layouts/default.html +159 -0
- package/vendor/ts-morph/docs/_script-templates/main.ts +116 -0
- package/vendor/ts-morph/docs/assets/css/style.scss +212 -0
- package/vendor/ts-morph/docs/details/ambient.md +38 -0
- package/vendor/ts-morph/docs/details/async.md +31 -0
- package/vendor/ts-morph/docs/details/classes.md +314 -0
- package/vendor/ts-morph/docs/details/comment-ranges.md +7 -0
- package/vendor/ts-morph/docs/details/comments.md +122 -0
- package/vendor/ts-morph/docs/details/decorators.md +119 -0
- package/vendor/ts-morph/docs/details/documentation.md +73 -0
- package/vendor/ts-morph/docs/details/enums.md +117 -0
- package/vendor/ts-morph/docs/details/exports.md +308 -0
- package/vendor/ts-morph/docs/details/expressions.md +46 -0
- package/vendor/ts-morph/docs/details/functions.md +150 -0
- package/vendor/ts-morph/docs/details/generators.md +27 -0
- package/vendor/ts-morph/docs/details/identifiers.md +79 -0
- package/vendor/ts-morph/docs/details/imports.md +191 -0
- package/vendor/ts-morph/docs/details/index.md +52 -0
- package/vendor/ts-morph/docs/details/initializers.md +40 -0
- package/vendor/ts-morph/docs/details/interfaces.md +218 -0
- package/vendor/ts-morph/docs/details/literals.md +20 -0
- package/vendor/ts-morph/docs/details/modifiers.md +38 -0
- package/vendor/ts-morph/docs/details/modules.md +113 -0
- package/vendor/ts-morph/docs/details/namespaces.md +7 -0
- package/vendor/ts-morph/docs/details/object-literal-expressions.md +106 -0
- package/vendor/ts-morph/docs/details/parameters.md +64 -0
- package/vendor/ts-morph/docs/details/signatures.md +41 -0
- package/vendor/ts-morph/docs/details/source-files.md +292 -0
- package/vendor/ts-morph/docs/details/type-aliases.md +34 -0
- package/vendor/ts-morph/docs/details/type-parameters.md +72 -0
- package/vendor/ts-morph/docs/details/types.md +254 -0
- package/vendor/ts-morph/docs/details/variables.md +110 -0
- package/vendor/ts-morph/docs/emitting.md +151 -0
- package/vendor/ts-morph/docs/index.md +25 -0
- package/vendor/ts-morph/docs/manipulation/code-writer.md +20 -0
- package/vendor/ts-morph/docs/manipulation/formatting.md +76 -0
- package/vendor/ts-morph/docs/manipulation/index.md +136 -0
- package/vendor/ts-morph/docs/manipulation/order.md +14 -0
- package/vendor/ts-morph/docs/manipulation/performance.md +222 -0
- package/vendor/ts-morph/docs/manipulation/removing.md +31 -0
- package/vendor/ts-morph/docs/manipulation/renaming.md +106 -0
- package/vendor/ts-morph/docs/manipulation/settings.md +76 -0
- package/vendor/ts-morph/docs/manipulation/structures.md +117 -0
- package/vendor/ts-morph/docs/manipulation/transforms.md +84 -0
- package/vendor/ts-morph/docs/metrics/performance.json +4 -0
- package/vendor/ts-morph/docs/navigation/ambient-modules.md +22 -0
- package/vendor/ts-morph/docs/navigation/compiler-nodes.md +82 -0
- package/vendor/ts-morph/docs/navigation/directories.md +287 -0
- package/vendor/ts-morph/docs/navigation/example.md +50 -0
- package/vendor/ts-morph/docs/navigation/finding-references.md +53 -0
- package/vendor/ts-morph/docs/navigation/getting-source-files.md +59 -0
- package/vendor/ts-morph/docs/navigation/images/getChildrenVsForEachChild.gif +0 -0
- package/vendor/ts-morph/docs/navigation/index.md +94 -0
- package/vendor/ts-morph/docs/navigation/language-service.md +23 -0
- package/vendor/ts-morph/docs/navigation/program.md +25 -0
- package/vendor/ts-morph/docs/navigation/type-checker.md +33 -0
- package/vendor/ts-morph/docs/setup/adding-source-files.md +145 -0
- package/vendor/ts-morph/docs/setup/ast-viewers.md +46 -0
- package/vendor/ts-morph/docs/setup/diagnostics.md +109 -0
- package/vendor/ts-morph/docs/setup/file-system.md +106 -0
- package/vendor/ts-morph/docs/setup/images/atom-ast.png +0 -0
- package/vendor/ts-morph/docs/setup/images/atom-ast_small.png +0 -0
- package/vendor/ts-morph/docs/setup/images/atom-command-palette.png +0 -0
- package/vendor/ts-morph/docs/setup/images/atom-file.png +0 -0
- package/vendor/ts-morph/docs/setup/images/ts-ast-viewer.png +0 -0
- package/vendor/ts-morph/docs/setup/index.md +94 -0
- package/vendor/ts-morph/docs/utilities.md +55 -0
- package/vendor/ts-morph/dprint.json +23 -0
- package/vendor/ts-morph/package.json +30 -0
- package/vendor/ts-morph/packages/bootstrap/LICENSE +21 -0
- package/vendor/ts-morph/packages/bootstrap/lib/ts-morph-bootstrap.d.ts +397 -0
- package/vendor/ts-morph/packages/bootstrap/package.json +46 -0
- package/vendor/ts-morph/packages/bootstrap/readme.md +200 -0
- package/vendor/ts-morph/packages/common/LICENSE +21 -0
- package/vendor/ts-morph/packages/common/lib/ts-morph-common.d.ts +1082 -0
- package/vendor/ts-morph/packages/common/lib/typescript.d.ts +11439 -0
- package/vendor/ts-morph/packages/common/package.json +65 -0
- package/vendor/ts-morph/packages/common/readme.md +5 -0
- package/vendor/ts-morph/packages/scripts/changeTypeScriptVersion.ts +28 -0
- package/vendor/ts-morph/packages/scripts/createDeclarationProject.ts +47 -0
- package/vendor/ts-morph/packages/scripts/deps.ts +2 -0
- package/vendor/ts-morph/packages/scripts/execScript.ts +31 -0
- package/vendor/ts-morph/packages/scripts/folders.ts +11 -0
- package/vendor/ts-morph/packages/scripts/getDevCompilerVersions.ts +19 -0
- package/vendor/ts-morph/packages/scripts/mod.ts +7 -0
- package/vendor/ts-morph/packages/scripts/utils/Memoize.ts +36 -0
- package/vendor/ts-morph/packages/scripts/utils/forEachTypeText.ts +23 -0
- package/vendor/ts-morph/packages/scripts/utils/makeConstructorsPrivate.ts +26 -0
- package/vendor/ts-morph/packages/scripts/utils/mod.ts +4 -0
- package/vendor/ts-morph/packages/scripts/utils/printDiagnostics.ts +10 -0
- package/vendor/ts-morph/packages/ts-morph/LICENSE +21 -0
- package/vendor/ts-morph/packages/ts-morph/lib/ts-morph.d.ts +11198 -0
- package/vendor/ts-morph/packages/ts-morph/package.json +78 -0
- package/vendor/ts-morph/packages/ts-morph/readme.md +111 -0
- package/vendor/ts-morph/readme.md +14 -0
- package/vendor/ts-morph/rfcs/README.md +13 -0
- package/vendor/ts-morph/rfcs/RFC-0001 - Inserting Into Statements Handling Comments.md +181 -0
- package/vendor/ts-morph/tsconfig.common.json +17 -0
- package/vitest.config.ts +16 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Transforms
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Transforms
|
|
6
|
+
|
|
7
|
+
It is possible to transform the AST using the compiler API, though this is not a typical scenario.
|
|
8
|
+
|
|
9
|
+
For example:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { ts } from "ts-morph";
|
|
13
|
+
|
|
14
|
+
const project = new Project();
|
|
15
|
+
const sourceFile = project.createSourceFile("Example.ts", "1; 2; 3;");
|
|
16
|
+
|
|
17
|
+
// this can be done starting on any node and not just the root node
|
|
18
|
+
sourceFile.transform(traversal => {
|
|
19
|
+
const node = traversal.visitChildren(); // return type is `ts.Node`
|
|
20
|
+
|
|
21
|
+
if (ts.isNumericLiteral(node)) {
|
|
22
|
+
const incrementedValue = parseInt(node.text, 10) + 1;
|
|
23
|
+
return traversal.factory.createNumericLiteral(incrementedValue.toString());
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return node;
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// outputs: 2; 3; 4;
|
|
30
|
+
console.log(sourceFile.getFullText());
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Doing this is more performant, but you won't have type checking, symbols, and you'll be dealing directly with the TypeScript compiler API nodes. Additionally, all previously wrapped descendant nodes of transformed nodes will be forgotten (using them will result in an error being thrown).
|
|
34
|
+
|
|
35
|
+
### Conditionally visiting children
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { ts } from "ts-morph";
|
|
39
|
+
|
|
40
|
+
const project = new Project();
|
|
41
|
+
const sourceFile = project.createSourceFile(
|
|
42
|
+
"Example.ts",
|
|
43
|
+
`
|
|
44
|
+
class C1 {
|
|
45
|
+
myMethod() {
|
|
46
|
+
function nestedFunction() {
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
class C2 {
|
|
52
|
+
prop1: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function f1() {
|
|
56
|
+
console.log("1");
|
|
57
|
+
|
|
58
|
+
function nestedFunction() {
|
|
59
|
+
}
|
|
60
|
+
}`,
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
sourceFile.transform(traversal => {
|
|
64
|
+
// this will skip visiting the children of the classes
|
|
65
|
+
if (ts.isClassDeclaration(traversal.currentNode))
|
|
66
|
+
return traversal.currentNode;
|
|
67
|
+
|
|
68
|
+
const node = traversal.visitChildren();
|
|
69
|
+
if (ts.isFunctionDeclaration(node)) {
|
|
70
|
+
return traversal.factory.updateFunctionDeclaration(
|
|
71
|
+
node,
|
|
72
|
+
[],
|
|
73
|
+
[],
|
|
74
|
+
undefined,
|
|
75
|
+
traversal.factory.createIdentifier("newName"),
|
|
76
|
+
[],
|
|
77
|
+
[],
|
|
78
|
+
undefined,
|
|
79
|
+
traversal.factory.createBlock([]),
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
return node;
|
|
83
|
+
});
|
|
84
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Ambient Modules
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Ambient Modules
|
|
6
|
+
|
|
7
|
+
The ambient module symbols can be retrieved by calling:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
const ambientModules = project.getAmbientModules();
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This will return the ambient modules resolved by the compiler (ex. ambient modules in `@types` or `node_modules`).
|
|
14
|
+
|
|
15
|
+
### Getting by name
|
|
16
|
+
|
|
17
|
+
Get an ambient module symbol based on its name:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
const jQuerySymbol = project.getAmbientModule("jquery"); // returns: Symbol | undefined
|
|
21
|
+
const momentSymbol = project.getAmbientModuleOrThrow("moment"); // returns: Symbol
|
|
22
|
+
```
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Underlying Compiler Nodes
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Underlying Compiler Nodes
|
|
6
|
+
|
|
7
|
+
Sometimes it might be useful to get the node from the TypeScript compiler.
|
|
8
|
+
|
|
9
|
+
They're accessible via the `.compilerNode` property that's found on all node objects:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
const compilerNode = interfaceDeclaration.compilerNode;
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Warning:** When manipulating the AST via this library, the underlying TypeScript AST tree is regenerated each time. For this reason, it's important not
|
|
16
|
+
to hold on to TypeScript compiler nodes between manipulations or you could end up working with out of date information.
|
|
17
|
+
|
|
18
|
+
### Compiler node properties
|
|
19
|
+
|
|
20
|
+
Sometimes there isn't a helper function in this library for accessing certain properties on the underlying compiler node.
|
|
21
|
+
|
|
22
|
+
In these situations, you can access any underlying compiler node property by using the `.getNodeProperty(propName)` method:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
const nameNode = propertyAccessExpression.getNodeProperty("name"); // returns: PropertyName
|
|
26
|
+
// also works with arrays and possibly undefined properties
|
|
27
|
+
const typeParameters = classDeclaration.getNodeProperty("typeParameters"); // returns: TypeParameterDeclaration[] | undefined
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
...and then please open an issue so that I can implement something I forgot to implement.
|
|
31
|
+
|
|
32
|
+
## Navigating Existing Compiler Nodes
|
|
33
|
+
|
|
34
|
+
Sometimes you might want to easily navigate an existing compiler node.
|
|
35
|
+
|
|
36
|
+
Do that by using the `createWrappedNode` function:
|
|
37
|
+
|
|
38
|
+
```ts ignore-error: 1109
|
|
39
|
+
import { createWrappedNode, ClassDeclaration, ts, SyntaxKind } from "ts-morph";
|
|
40
|
+
|
|
41
|
+
// some code that creates a class declaration using the ts object
|
|
42
|
+
const classNode: ts.ClassDeclaration = ...;
|
|
43
|
+
|
|
44
|
+
// create and use a wrapped node
|
|
45
|
+
const classDec = createWrappedNode(classNode).asKindOrThrow(SyntaxKind.ClassDeclaration);
|
|
46
|
+
const firstProperty = classDec.getProperties()[0];
|
|
47
|
+
|
|
48
|
+
// ... do more stuff here ...
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Note:** This is a lightweight way to navigate a node, but there are certian functionalities which will throw an error since there is no
|
|
52
|
+
language service, type checker, or program. For example, finding references will not work because that requires a language service.
|
|
53
|
+
|
|
54
|
+
### Providing Type Checker
|
|
55
|
+
|
|
56
|
+
If you would like to easily get the type information of the types in the provided source file, then provide a type checker:
|
|
57
|
+
|
|
58
|
+
```ts ignore-error: 1109
|
|
59
|
+
// given an existing node and type checker
|
|
60
|
+
const classNode: ts.ClassDeclaration = ...;
|
|
61
|
+
const compilerTypeChecker: ts.TypeChecker = ...;
|
|
62
|
+
|
|
63
|
+
// create and use a wrapped node
|
|
64
|
+
const classDec = createWrappedNode(classNode, { typeChecker: compilerTypeChecker }).asKindOrThrow(SyntaxKind.ClassDeclaration);
|
|
65
|
+
console.log(classDec.getPropertyOrThrow("propName").getType().getText()); // ok, because a type checker was provided
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Important: Using both the TypeScript API and ts-morph
|
|
69
|
+
|
|
70
|
+
It is highly recommended to always use the `ts` named export from ts-morph when
|
|
71
|
+
needing to use the TypeScript Compiler API and ts-morph at the same time:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
// do this
|
|
75
|
+
import { ts } from "ts-morph";
|
|
76
|
+
// not this
|
|
77
|
+
import * as ts from "typescript";
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
They're almost identical and the `ts` named export from ts-morph should serve your needs.
|
|
81
|
+
|
|
82
|
+
There's lots of reasons why this is done and it's outlined in [#333](https://github.com/dsherret/ts-morph/issues/333#issuecomment-391182952).
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Directories
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Directories
|
|
6
|
+
|
|
7
|
+
Based on the source files created, appropriate directory objects will be created. These objects hold source files and directories that have been added.
|
|
8
|
+
|
|
9
|
+
Note that it's completely fine to ignore the concept of directories and only deal with source files. This is an advanced feature that
|
|
10
|
+
only needs to be used if it will help make solving your problem easier.
|
|
11
|
+
|
|
12
|
+
### Retrieving
|
|
13
|
+
|
|
14
|
+
Directories can be retrieved from a source file:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
const directory = sourceFile.getDirectory();
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
From other directories:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
directory.getDirectory("childDir");
|
|
24
|
+
directory.getDirectoryOrThrow("childDir");
|
|
25
|
+
// child directories
|
|
26
|
+
directory.getDirectories();
|
|
27
|
+
// parent directory, if it exists
|
|
28
|
+
directory.getParent();
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Or from the main `project` object:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
project.getRootDirectories(); // gets directories without a parent
|
|
35
|
+
project.getDirectories(); // gets all the directories
|
|
36
|
+
project.getDirectory("path/to/directory");
|
|
37
|
+
project.getDirectoryOrThrow("path/to/directory");
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Adding
|
|
41
|
+
|
|
42
|
+
On a directory:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
const childDirectory = directory.addDirectoryAtPath("childDir"); // or addDirectoryAtPathIfExists
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Or main `project` object:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
const directory = project.addDirectoryAtPath("path/to/dir"); // or addDirectoryAtPathIfExists
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Creating
|
|
55
|
+
|
|
56
|
+
On a directory
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
const childDir = directory.createDirectory("childDir");
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Or main `project` object:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
const directory = project.createDirectory("path/to/dir");
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Directory
|
|
69
|
+
|
|
70
|
+
### Path and name
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
// returns the full path (ex. /home/david/project/)
|
|
74
|
+
const path = directory.getPath();
|
|
75
|
+
|
|
76
|
+
// returns only the directory name (ex. project)
|
|
77
|
+
const baseName = directory.getBaseName();
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Parent directory
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
const parentDir = directory.getParent(); // or getParentOrThrow()
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Child directories
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
const childDirs = directory.getDirectories();
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Ancestor / Descendant
|
|
93
|
+
|
|
94
|
+
Check if a directory is an ancestor or descendant of another directory:
|
|
95
|
+
|
|
96
|
+
```ts setup: let grandParentDir: Directory, childDir: Directory;
|
|
97
|
+
grandParentDir.isAncestorOf(childDir); // true
|
|
98
|
+
childDir.isDescendantOf(grandParentDir); // true
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Or if a directory is an ancestor of a source file:
|
|
102
|
+
|
|
103
|
+
```ts setup: let grandParentDir: Directory, parentDir: Directory, childSourceFile: SourceFile;
|
|
104
|
+
grandParentDir.isAncestorOf(childSourceFile); // true
|
|
105
|
+
parentDir.isAncestorOf(childSourceFile); // true
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Source files
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
const sourceFiles = directory.getSourceFiles();
|
|
112
|
+
const sourceFile = directory.getSourceFile("someFile.ts"); // or getSourceFileOrThrow
|
|
113
|
+
const indexFile = directory.addSourceFileAtPath("index.ts"); // or addSourceFileAtPathIfExists
|
|
114
|
+
const descendantSourceFiles = directory.getDescendantSourceFiles();
|
|
115
|
+
|
|
116
|
+
directory.createSourceFile("someFile.ts");
|
|
117
|
+
directory.createSourceFile("someFile2.ts", "// some text");
|
|
118
|
+
directory.createSourceFile("someFile3.ts", writer => writer.writeLine("// some text"));
|
|
119
|
+
directory.createSourceFile("someFile4.ts", { statements: [{ kind: StructureKind.Enum, name: "MyEnum" }] });
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Saving
|
|
123
|
+
|
|
124
|
+
Save the directory to the disk and all the unsaved source files:
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
await directory.save();
|
|
128
|
+
directory.saveSync(); // slow
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Emitting
|
|
132
|
+
|
|
133
|
+
It's possible to only specific directories:
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
// always check result.getEmitSkipped() to make sure the emit was successful
|
|
137
|
+
const result = await directory.emit();
|
|
138
|
+
directory.emitSync(); // slow
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Or specify the output directories (specify a path relative from the directory or an absolute paths):
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
directory.emit({
|
|
145
|
+
outDir: "out",
|
|
146
|
+
declarationDir: "declarations",
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
And of course, specify to only emit declaration files:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
directory.emit({ emitOnlyDtsFiles: true });
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Moving
|
|
157
|
+
|
|
158
|
+
Move the directory to a new directory:
|
|
159
|
+
|
|
160
|
+
```ts setup: const otherDir: Directory;
|
|
161
|
+
// ex. moves C:\MyProject\dir to C:\MyProject\newDir if working directory is C:\MyProject
|
|
162
|
+
directory.move("./newDir");
|
|
163
|
+
// ex. moves C:\MyProject\newDir to C:\MyProject\otherDir using a relative path
|
|
164
|
+
directory.move("../otherDir", { overwrite: true }); // allows overwriting (otherwise it will throw)
|
|
165
|
+
// or specify an absolute path
|
|
166
|
+
directory.move("C:\\finalDir");
|
|
167
|
+
// or specify the directory to move to
|
|
168
|
+
directory.moveToDirectory("some/directory");
|
|
169
|
+
directory.moveToDirectory(otherDir);
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Moving Immediately
|
|
173
|
+
|
|
174
|
+
Moving a directory immediately can be done by using one of the following methods:
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
await directory.moveImmediately("../newDir");
|
|
178
|
+
// or
|
|
179
|
+
directory.moveImmediatelySync("../newDir2");
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Copying
|
|
183
|
+
|
|
184
|
+
Copy the directory to a new directory:
|
|
185
|
+
|
|
186
|
+
```ts setup: const otherDir: Directory;
|
|
187
|
+
// ex. copies C:\MyProject\dir to C:\MyProject\newDir
|
|
188
|
+
directory.copy("../newDir");
|
|
189
|
+
// allows overwriting (otherwise it will throw)
|
|
190
|
+
directory.copy("../nextDir", { overwrite: true });
|
|
191
|
+
// or specify an absolute path
|
|
192
|
+
directory.copy("C:\\test");
|
|
193
|
+
// or specify the directory to copy to
|
|
194
|
+
directory.copyToDirectory("some/directory");
|
|
195
|
+
directory.copyToDirectory(otherDir);
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Note that the directory and source files, in all these cases, won't be created until calling save on the project.
|
|
199
|
+
|
|
200
|
+
#### Not including untracked files
|
|
201
|
+
|
|
202
|
+
When moving a directory, it will queue up a file system copy for the directory from to the directory to. If you only wish to copy the source files that are found in memory within the directory, then set the `includeUntrackedFiles` option to false:
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
directory.copy("../finalDir", { includeUntrackedFiles: false });
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Copying Immediately
|
|
209
|
+
|
|
210
|
+
Copying a directory immediately can be done by using one of the following methods:
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
await directory.copyImmediately("../otherDir");
|
|
214
|
+
// or
|
|
215
|
+
directory.copyImmediatelySync("../otherDir2");
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Deleting
|
|
219
|
+
|
|
220
|
+
Call:
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
directory.delete();
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
This will remove the directory object and all its descendant source files and directories from the main `project` object and queue it up for deletion to the file system.
|
|
227
|
+
|
|
228
|
+
When you're all done your other manipulations, call `project.save()` and at that point the directory will be deleted.
|
|
229
|
+
|
|
230
|
+
#### Deleting immediately
|
|
231
|
+
|
|
232
|
+
If you want to delete a directory immediately from the file system, then use the following:
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
await directory.deleteImmediately();
|
|
236
|
+
// or
|
|
237
|
+
directory.deleteImmediatelySync();
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
This isn't recommended though because it could possibly leave the file system in a halfway state if your code errors before it's done.
|
|
241
|
+
|
|
242
|
+
### Clearing
|
|
243
|
+
|
|
244
|
+
Call:
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
directory.clear();
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
This will delete the directory's descendants in memory and queue a delete and mkdir operation to the file system.
|
|
251
|
+
|
|
252
|
+
#### Clearing immediately
|
|
253
|
+
|
|
254
|
+
If you want to do this operation immediatley to the file system, then use the following:
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
await directory.clearImmediately();
|
|
258
|
+
// or
|
|
259
|
+
directory.clearImmediatelySync();
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
This isn't recommended though because it could possibly leave the file system in a halfway state if your code errors before it's done.
|
|
263
|
+
|
|
264
|
+
### Forgetting
|
|
265
|
+
|
|
266
|
+
Forgets the directory from main project object without deleting it:
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
directory.forget();
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Note that after doing this, the directory object and all its descendant source files and directories will not be available. If you want to use them again,
|
|
273
|
+
then you will need to re-add them.
|
|
274
|
+
|
|
275
|
+
### Relative File Paths
|
|
276
|
+
|
|
277
|
+
It might be useful to get the relative path from one directory to another source file or directory.
|
|
278
|
+
|
|
279
|
+
```ts setup: let directoryFrom: Directory, sourceFileTo: SourceFile;
|
|
280
|
+
const relativePath = directoryFrom.getRelativePathTo(sourceFileTo);
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Or to get the module specifier text from one directory to another source file or directory.
|
|
284
|
+
|
|
285
|
+
```ts setup: let directoryFrom: Directory, sourceFileTo: SourceFile;
|
|
286
|
+
const moduleSpecifier = directoryFrom.getRelativePathAsModuleSpecifierTo(sourceFileTo);
|
|
287
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Navigation example
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Example - Navigating Within Source Files
|
|
6
|
+
|
|
7
|
+
### Setup
|
|
8
|
+
|
|
9
|
+
Given the following file:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
// Person.ts
|
|
13
|
+
|
|
14
|
+
interface Person {
|
|
15
|
+
name: string;
|
|
16
|
+
age: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default Person;
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
And setup:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { Project } from "ts-morph";
|
|
26
|
+
|
|
27
|
+
const project = new Project();
|
|
28
|
+
project.addSourceFilesAtPaths("**/*.ts");
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Use
|
|
32
|
+
|
|
33
|
+
First you need to get the source file you would like to look at:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
const sourceFile = project.getSourceFileOrThrow("Person.ts");
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Now inspect what's inside... here's a few examples:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
const hasClasses = sourceFile.getClasses().length > 0;
|
|
43
|
+
const interfaces = sourceFile.getInterfaces();
|
|
44
|
+
|
|
45
|
+
// person interface
|
|
46
|
+
const personInterface = sourceFile.getInterface("Person")!;
|
|
47
|
+
personInterface.isDefaultExport(); // returns true
|
|
48
|
+
personInterface.getName(); // returns "Person"
|
|
49
|
+
personInterface.getProperties(); // returns the properties
|
|
50
|
+
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Finding References
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Finding References
|
|
6
|
+
|
|
7
|
+
Find all the references of a node by calling `.findReferences()` on an identifier or named/nameable declaration.
|
|
8
|
+
|
|
9
|
+
### Example
|
|
10
|
+
|
|
11
|
+
Simple example:
|
|
12
|
+
|
|
13
|
+
```ts ignore-error: 1109
|
|
14
|
+
const classDeclaration = ...; // get a class or some other declaration somehow
|
|
15
|
+
const referencedSymbols = classDeclaration.findReferences();
|
|
16
|
+
|
|
17
|
+
for (const referencedSymbol of referencedSymbols) {
|
|
18
|
+
for (const reference of referencedSymbol.getReferences()) {
|
|
19
|
+
console.log("---------")
|
|
20
|
+
console.log("REFERENCE")
|
|
21
|
+
console.log("---------")
|
|
22
|
+
console.log("File path: " + reference.getSourceFile().getFilePath());
|
|
23
|
+
console.log("Start: " + reference.getTextSpan().getStart());
|
|
24
|
+
console.log("Length: " + reference.getTextSpan().getLength());
|
|
25
|
+
console.log("Parent kind: " + reference.getNode().getParentOrThrow().getKindName());
|
|
26
|
+
console.log("\n");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Finding Referencing Nodes
|
|
32
|
+
|
|
33
|
+
The `.findReferences()` method returns back a lot of information that might not be necessary.
|
|
34
|
+
If you just want the nodes that reference the named/nameable declaration, then use the
|
|
35
|
+
following method:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
const nodes = classDeclaration.findReferencesAsNodes();
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## "Go to Definition"
|
|
42
|
+
|
|
43
|
+
Similar to finding references, you can also go to an identifier's definitions:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
const definitions = identifier.getDefinitions();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Or just get the nodes:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
const nodes = identifier.getDefinitionNodes();
|
|
53
|
+
```
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Getting Source Files
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Getting Source Files
|
|
6
|
+
|
|
7
|
+
After source files are added, you will need to get them in order to navigate or make changes.
|
|
8
|
+
|
|
9
|
+
### All
|
|
10
|
+
|
|
11
|
+
Get all the source files:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const sourceFiles = project.getSourceFiles();
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Or filter by glob:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
// single
|
|
21
|
+
const testSourceFiles = project.getSourceFiles("src/test/**/*.ts");
|
|
22
|
+
// or multiple
|
|
23
|
+
const nonTestSourceFiles = project.getSourceFiles([
|
|
24
|
+
"src/**/*.ts",
|
|
25
|
+
"!src/test/**/*.ts",
|
|
26
|
+
]);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Note that the path resolution and matching is done relative to the current working directory.
|
|
30
|
+
|
|
31
|
+
For example, if you load a project from another directory...
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
const project = new Project({
|
|
35
|
+
tsConfigFilePath: `/someDirectory/notCurrent/tsconfig.json`,
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
...to match a file from that directory you need to specify a glob that matches based on the current working directory or absolute path...
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
const sourceFile = project.getSourceFiles(`/someDirectory/notCurrent/**/config/index.ts`);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### By file path
|
|
46
|
+
|
|
47
|
+
Will return the first source file that matches the end of the provided file path:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
const personFile = project.getSourceFile("Models/Person.ts");
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### By condition
|
|
54
|
+
|
|
55
|
+
Will return the first source file that matches the provided condition:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
const fileWithFiveClasses = project.getSourceFile(f => f.getClasses().length === 5);
|
|
59
|
+
```
|