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,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Navigating the AST
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Navigating the AST
|
|
6
|
+
|
|
7
|
+
Navigating the AST should be simple and straightforward.
|
|
8
|
+
|
|
9
|
+
Right now, the best way to explore what's implemented is to look at the autocompletion/intellisense results
|
|
10
|
+
or view [this report](https://github.com/dsherret/ts-morph/blob/latest/packages/ts-morph/wrapped-nodes.md).
|
|
11
|
+
|
|
12
|
+
If you can't find something that means it's most likely not implemented and you should [open an issue](https://github.com/dsherret/ts-morph/issues) on GitHub.
|
|
13
|
+
|
|
14
|
+
### General methods
|
|
15
|
+
|
|
16
|
+
Search autocomplete for methods like `.getChildren()`, `.getParent()`, `.getFirstChildBySyntaxKind(kind)`, etc...
|
|
17
|
+
|
|
18
|
+
Many exist. If you find one you would really like, then please [open an issue](https://github.com/dsherret/ts-morph/issues).
|
|
19
|
+
|
|
20
|
+
### getChildren() and forEachChild(child => ...)
|
|
21
|
+
|
|
22
|
+
In general, you can easily navigate the tree by using methods such as `.getClasses()`, `.getClass('MyClass')`, `.getModules()`, and so on, but in some cases you might want to get all the child nodes.
|
|
23
|
+
|
|
24
|
+
In the compiler API, there exists a `node.getChildren()` method and `ts.forEachChild(node, child => { })`/`node.forEachChild(child => { })` function/method.
|
|
25
|
+
|
|
26
|
+
- `.getChildren()` - Returns all the children including the all the tokens (ex. `OpenBraceToken`, `SemiColonToken` etc.).
|
|
27
|
+
- `.forEachChild(child => {})` - Iterates all the child nodes that are properties of the node.
|
|
28
|
+
|
|
29
|
+
[](http://ts-ast-viewer.com)
|
|
30
|
+
|
|
31
|
+
In ts-morph, these methods also exist and they can be used similarly to the compiler API:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
const allChildren = node.getChildren();
|
|
35
|
+
|
|
36
|
+
node.forEachChild(node => {
|
|
37
|
+
console.log(node.getText());
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const classDec = node.forEachChild(node => {
|
|
41
|
+
if (Node.isClassDeclaration(node))
|
|
42
|
+
return node; // stops iterating over the children and returns this value
|
|
43
|
+
return undefined; // return a falsy value or no value to continue iterating
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### forEachDescendant
|
|
48
|
+
|
|
49
|
+
If you wish to iterate all the descendants, then use the `forEachDescendant` method:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
node.forEachDescendant(node => console.log(node.getText()));
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
This is especially useful when writing code that implements a visitor pattern:
|
|
56
|
+
|
|
57
|
+
```ts ignore-error: 1109, setup: let sourceFiles: SourceFile[];
|
|
58
|
+
interface Visitor {
|
|
59
|
+
visit(node: Node): void;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const myVisitors: Visitor[] = ...;
|
|
63
|
+
|
|
64
|
+
for (const sourceFile of sourceFiles)
|
|
65
|
+
sourceFile.forEachDescendant(node => myVisitors.forEach(v => v.visit(node)));
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### Traversal Control
|
|
69
|
+
|
|
70
|
+
Traversal can be controlled with the second parameter:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
const result = node.forEachDescendant((node, traversal) => {
|
|
74
|
+
switch (node.getKind()) {
|
|
75
|
+
case SyntaxKind.ClassDeclaration:
|
|
76
|
+
// skips traversal of the current node's descendants
|
|
77
|
+
traversal.skip();
|
|
78
|
+
break;
|
|
79
|
+
case SyntaxKind.Parameter:
|
|
80
|
+
// skips traversal of the current node's descendants and its siblings and all their descendants
|
|
81
|
+
traversal.up();
|
|
82
|
+
break;
|
|
83
|
+
case SyntaxKind.FunctionDeclaration:
|
|
84
|
+
// stops traversal completely
|
|
85
|
+
traversal.stop();
|
|
86
|
+
break;
|
|
87
|
+
case SyntaxKind.InterfaceDeclaration:
|
|
88
|
+
// stops traversal completely and returns this value
|
|
89
|
+
return node;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return undefined;
|
|
93
|
+
});
|
|
94
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Language Service
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Language Service
|
|
6
|
+
|
|
7
|
+
Get the language service by calling:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
const languageService = project.getLanguageService();
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Underlying compiler object
|
|
14
|
+
|
|
15
|
+
The underlying `ts.LanguageService` can be retrieved as follows:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
const tsLanguageService = languageService.compilerObject;
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Use
|
|
22
|
+
|
|
23
|
+
Generally you won't need to use the language service because most of the functionality is exposed as methods on other objects.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Program
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Program
|
|
6
|
+
|
|
7
|
+
Get the program by calling:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
const program = project.getProgram();
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Underlying compiler object
|
|
14
|
+
|
|
15
|
+
The underlying `ts.Program` can be retrieved as follows:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
const tsProgram = program.compilerObject;
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Warning:** The underlying compiler object will be discared whenever manipulation occurs. For that reason, only hold onto the underlying compiler object between manipulations.
|
|
22
|
+
|
|
23
|
+
### Use
|
|
24
|
+
|
|
25
|
+
Generally you won't need to use the program because most of the functionality is exposed as methods on other objects.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Type Checker
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Type Checker
|
|
6
|
+
|
|
7
|
+
Get the type checker by calling:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
const typeChecker = project.getTypeChecker();
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Underlying compiler object
|
|
14
|
+
|
|
15
|
+
The underlying `ts.TypeChecker` can be retrieved as follows:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
const tsTypeChecker = typeChecker.compilerObject;
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Warning:** The underlying compiler object will be discared whenever manipulation occurs. For that reason, only hold onto the underlying compiler object between manipulations.
|
|
22
|
+
|
|
23
|
+
### Use
|
|
24
|
+
|
|
25
|
+
Generally you won't need to use the type checker because most of the functionality is exposed as methods on other objects.
|
|
26
|
+
|
|
27
|
+
### Signature Resolution
|
|
28
|
+
|
|
29
|
+
Get the resolved signature of a call-like expression node (ex. call expression):
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
const resolvedSignature = typeChecker.getResolvedSignature(callLikeExpression);
|
|
33
|
+
```
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Adding Source Files
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Adding Source Files
|
|
6
|
+
|
|
7
|
+
You will need to populate the `project` object with source files.
|
|
8
|
+
|
|
9
|
+
### By a _tsconfig.json_
|
|
10
|
+
|
|
11
|
+
Source files will be added when instantiating with a `tsConfigFilePath`:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { Project } from "ts-morph";
|
|
15
|
+
|
|
16
|
+
const project = new Project({
|
|
17
|
+
tsConfigFilePath: "path/to/tsconfig.json",
|
|
18
|
+
});
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
...and this can be disabled by setting `skipAddingFilesFromTsConfig: true`:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
const project = new Project({
|
|
25
|
+
tsConfigFilePath: "path/to/tsconfig.json",
|
|
26
|
+
skipAddingFilesFromTsConfig: true,
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Alternatively, populate the `project` object by calling `addSourceFilesFromTsConfig`:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
project.addSourceFilesFromTsConfig("path/to/tsconfig.json");
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
#### Source File Dependency Resolution
|
|
37
|
+
|
|
38
|
+
By default, all the source files added to the project in the constructor via a _tsconfig.json_ will automatically be analyzed to
|
|
39
|
+
include the source files they depend on. If you wish to skip this analysis step, then provide the `skipFileDependencyResolution` option:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
const project = new Project({
|
|
43
|
+
tsConfigFilePath: "path/to/tsconfig.json",
|
|
44
|
+
skipFileDependencyResolution: true,
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
If you are adding source files to a project in other ways and want to ensure the all the source files depended on by the added source files
|
|
49
|
+
are also included in the Project, then call the `.resolveSourceFileDependencies()` after adding everything:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
const project = new Project();
|
|
53
|
+
|
|
54
|
+
// add everything to the project
|
|
55
|
+
project.addSourceFilesFromTsConfig("dir1/tsconfig.json");
|
|
56
|
+
project.addSourceFilesFromTsConfig("dir2/tsconfig.json");
|
|
57
|
+
project.addSourceFilesAtPaths("dir3/**/*{.d.ts,.ts}");
|
|
58
|
+
|
|
59
|
+
// optionally call this when complete to resolve and
|
|
60
|
+
// add the dependent source files to the project
|
|
61
|
+
project.resolveSourceFileDependencies();
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### By file globs or file paths
|
|
65
|
+
|
|
66
|
+
Specify as many file globs or file paths as you wish:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
project.addSourceFilesAtPaths("folder/**/*{.d.ts,.ts}");
|
|
70
|
+
project.addSourceFilesAtPaths(["folder/file.ts", "folder/otherFile.ts"]);
|
|
71
|
+
project.addSourceFilesAtPaths(["**/*.ts", "!**/*.d.ts"]);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### By file path
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const sourceFile = project.addSourceFileAtPath("path/to/file.ts"); // or addSourceFileAtPathIfExists
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### By structure
|
|
81
|
+
|
|
82
|
+
Create source files based on an object that looks like the AST of a source file:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const sourceFile = project.createSourceFile("path/to/myStructureFile.ts", {
|
|
86
|
+
statements: [{
|
|
87
|
+
kind: StructureKind.Enum,
|
|
88
|
+
name: "MyEnum",
|
|
89
|
+
members: [{
|
|
90
|
+
name: "member",
|
|
91
|
+
}],
|
|
92
|
+
}, {
|
|
93
|
+
kind: StructureKind.Class,
|
|
94
|
+
name: "MyClass",
|
|
95
|
+
// etc...
|
|
96
|
+
}],
|
|
97
|
+
// etc...
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The above would create a source file with the following text:
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
enum MyEnum {
|
|
105
|
+
member,
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
class MyClass {
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### By string
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
const fileText = "enum MyEnum {\n}\n";
|
|
116
|
+
const sourceFile = project.createSourceFile("path/to/myNewFile.ts", fileText);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### By writer function
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
const sourceFile = project.createSourceFile("path/to/myOtherNewFile.ts", writer => {
|
|
123
|
+
writer
|
|
124
|
+
.writeLine("import * as ts from 'typescript';").blankLine()
|
|
125
|
+
.writeLine("export class MyClass {}");
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Options
|
|
130
|
+
|
|
131
|
+
`createSourceFile` will throw an error if the file already exists.
|
|
132
|
+
To not throw an error, set the `overwrite` option to true.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
const sourceFile = project.createSourceFile("path/to/myNewFile.ts", "", { overwrite: true });
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Note
|
|
139
|
+
|
|
140
|
+
Adding source files to the project from a structure, writer function, or text will act like any other source file, but they will not be saved to the disk unless you ask it to be.
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
// save it to the disk if you wish:
|
|
144
|
+
await sourceFile.save(); // or saveSync();
|
|
145
|
+
```
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: AST Viewers
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## AST Viewers
|
|
6
|
+
|
|
7
|
+
An AST viewer is a useful way to help understand the TypeScript AST for some source code.
|
|
8
|
+
|
|
9
|
+
### TypeScript AST Viewer
|
|
10
|
+
|
|
11
|
+
I've created this very basic web-based TypeScript AST viewer.
|
|
12
|
+
|
|
13
|
+
[TypeScript AST Viewer](http://ts-ast-viewer.com)
|
|
14
|
+
|
|
15
|
+
Features:
|
|
16
|
+
|
|
17
|
+
- View code on left, tree in middle, and information about selected node on right.
|
|
18
|
+
- View the type and symbol of the selected node.
|
|
19
|
+
- Toggle the tree between `node.forEachChild(...)` and `node.getChildren()`.
|
|
20
|
+
- Change compiler API versions.
|
|
21
|
+
- Use some compiler objects in the browser console.
|
|
22
|
+
|
|
23
|
+
[](http://ts-ast-viewer.com)
|
|
24
|
+
|
|
25
|
+
I will improve and add more functionality to this in the future. You can help contribute to its progress [here](https://github.com/dsherret/ts-ast-viewer).
|
|
26
|
+
|
|
27
|
+
### Atom TypeScript
|
|
28
|
+
|
|
29
|
+
This AST viewer gives an excellent view of the AST.
|
|
30
|
+
|
|
31
|
+
1. Install [Atom](https://atom.io/).
|
|
32
|
+
2. Install [atom-typescript](https://atom.io/packages/atom-typescript).
|
|
33
|
+
3. Create a new typescript file.
|
|
34
|
+
4. Paste in your typescript code.
|
|
35
|
+
|
|
36
|
+

|
|
37
|
+
|
|
38
|
+
5. Important: Ensure the current typescript document has focus.
|
|
39
|
+
6. Open the command palette (Windows/Linux: `ctrl+shift+p`, Mac: `cmd+shift+p`).
|
|
40
|
+
7. Type `TypeScript: Ast Full` and hit enter (or run `TypeScript: Ast` to get the ast without tokens).
|
|
41
|
+
|
|
42
|
+

|
|
43
|
+
|
|
44
|
+
8. A new tab will appear with the AST.
|
|
45
|
+
|
|
46
|
+
[](images/atom-ast.png)
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Diagnostics
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Diagnostics
|
|
6
|
+
|
|
7
|
+
Diagnostics (compile errors) can be retrieved on the project or on source files:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
const diagnostics = project.getPreEmitDiagnostics();
|
|
11
|
+
|
|
12
|
+
// or on a source file
|
|
13
|
+
const sourceFileDiagnostics = sourceFile.getPreEmitDiagnostics();
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The pre-emit diagnostics are the syntactic, semantic, global, options, config file parsing, and if enabled the declaration diagnostics.
|
|
17
|
+
|
|
18
|
+
### Formatting for Output
|
|
19
|
+
|
|
20
|
+
To nicely output the diagnostics, use `project.formatDiagnosticsWithColorAndContext`:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
const diagnostics = project.getPreEmitDiagnostics();
|
|
24
|
+
|
|
25
|
+
console.log(project.formatDiagnosticsWithColorAndContext(diagnostics));
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Diagnostic
|
|
29
|
+
|
|
30
|
+
#### Message text
|
|
31
|
+
|
|
32
|
+
Returned message text could be a `string` or a `DiagnosticMessageChain`:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
const message = diagnostic.getMessageText();
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
#### Source file
|
|
39
|
+
|
|
40
|
+
Source file the diagnostic occurs in:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
const sourceFile = diagnostic.getSourceFile(); // returns: SourceFile | undefined
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### Start, line number, & length
|
|
47
|
+
|
|
48
|
+
Position in the file, the line number, and length of the diagnostic:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
const start = diagnostic.getStart(); // returns: number
|
|
52
|
+
const lineNumber = diagnostic.getLineNumber(); // returns: number
|
|
53
|
+
const length = diagnostic.getLength(); // returns: number
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
#### Category
|
|
57
|
+
|
|
58
|
+
Categories can be warnings, errors, or just messages.
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const category = diagnostic.getCategory(); // returns: DiagnosticCategory
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### Code
|
|
65
|
+
|
|
66
|
+
This is the error code number:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
const code = diagnostic.getCode(); // returns: number
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### Source
|
|
73
|
+
|
|
74
|
+
todo: I don't know what this is, but it's available to get from the diagnostic.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const source = diagnostic.getSource(); // returns: string | undefined
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### DiagnosticMessageChain
|
|
81
|
+
|
|
82
|
+
A diagnostic message chain (DMC) will be returned by `diagnostic.getMessageText()` in certain scenarios.
|
|
83
|
+
|
|
84
|
+
According to the typescript compiler:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
/**
|
|
88
|
+
* A linked list of formatted diagnostic messages to be used as part of a multiline message.
|
|
89
|
+
* It is built from the bottom up, leaving the head to be the "main" diagnostic.
|
|
90
|
+
* While it seems that DiagnosticMessageChain is structurally similar to DiagnosticMessage,
|
|
91
|
+
* the difference is that messages are all preformatted in DMC.
|
|
92
|
+
*/
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The properties of a DMC are similar to a Diagnostic:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
const messageText = dmc.getMessageText(); // returns: string
|
|
99
|
+
const category = dmc.getCategory(); // returns: DiagnosticCategory
|
|
100
|
+
const code = dmc.getCode(); // returns: number
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### Next DMC in linked list
|
|
104
|
+
|
|
105
|
+
Call `.getNext()`:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
const next = dmc.getNext(); // returns: DiagnosticMessageChain | undefined
|
|
109
|
+
```
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: File System
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## File System
|
|
6
|
+
|
|
7
|
+
By default, the library will use the local file system based on the current working directory. In most scenarios, you won't have to bother with what's outlined here, but it may be useful in some scenarios (for example, using an in-memory file system is useful for mocking the file system for testing purposes).
|
|
8
|
+
|
|
9
|
+
### Current File System Object
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { Project } from "ts-morph";
|
|
13
|
+
const project = new Project();
|
|
14
|
+
|
|
15
|
+
const fs = project.getFileSystem(); // returns: FileSystemHost
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
This file system object can be used to interact with the current file system. The methods available on it are very obvious and not worth explaining
|
|
19
|
+
here (ex. `writeFile(filePath: string, fileText: string): Promise<void>`, `readFile(filePath: string): Promise<string>`, `readFileSync(filePath: string): string`, etc..).
|
|
20
|
+
|
|
21
|
+
### In-Memory File System
|
|
22
|
+
|
|
23
|
+
If you want to use a file system that is stored in memory, specify that when creating a `Project` instance:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { Project } from "ts-morph";
|
|
27
|
+
|
|
28
|
+
const project = new Project({ useInMemoryFileSystem: true });
|
|
29
|
+
const fs = project.getFileSystem();
|
|
30
|
+
|
|
31
|
+
const sourceFile = project.createSourceFile("file.ts", "console.log(5);");
|
|
32
|
+
sourceFile.saveSync();
|
|
33
|
+
console.log(fs.readFileSync("file.ts")); // outputs: "console.log(5);"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The current working directory on this file system will be `/`.
|
|
37
|
+
|
|
38
|
+
This file system can also be imported and created via the `InMemoryFileSystemHost` export.
|
|
39
|
+
|
|
40
|
+
#### Remember: The Default Script Target is `ES5`
|
|
41
|
+
|
|
42
|
+
You may wonder why certain standard types are `any` when using an in memory file system:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
const project = new Project({ useInMemoryFileSystem: true });
|
|
46
|
+
const sourceFile = project.createSourceFile(
|
|
47
|
+
"index.ts",
|
|
48
|
+
`const mySet = new Set<string>();`,
|
|
49
|
+
);
|
|
50
|
+
const mySetDecl = sourceFile.getVariableDeclarationOrThrow("mySet");
|
|
51
|
+
console.log(mySetDecl.getType().getText()); // any
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This is because, the `lib` compiler option must be specified, similar to when you use `tsc`:
|
|
55
|
+
|
|
56
|
+
```ts setup: let mySetDecl: Node;
|
|
57
|
+
const project = new Project({
|
|
58
|
+
useInMemoryFileSystem: true,
|
|
59
|
+
compilerOptions: {
|
|
60
|
+
lib: ["lib.es2015.d.ts"],
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
/// ...omitted... same as above...
|
|
64
|
+
console.log(mySetDecl.getType().getText()); // Set<string>, good
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Or you may specify a target that will implicitly load in the lib files that you need:
|
|
68
|
+
|
|
69
|
+
```ts setup: let mySetDecl: Node;
|
|
70
|
+
import { Project, ts } from "ts-morph";
|
|
71
|
+
|
|
72
|
+
const project = new Project({
|
|
73
|
+
useInMemoryFileSystem: true,
|
|
74
|
+
compilerOptions: {
|
|
75
|
+
target: ts.ScriptTarget.ES2015,
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
/// ...omitted... same as above...
|
|
79
|
+
console.log(mySetDecl.getType().getText()); // Set<string>, good
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Note that if you want to include all the lib files, you may specify `lib.esnext.full.d.ts` as a `lib` option:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const project = new Project({
|
|
86
|
+
useInMemoryFileSystem: true,
|
|
87
|
+
compilerOptions: {
|
|
88
|
+
lib: ["lib.esnext.full.d.ts"],
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Custom File System
|
|
94
|
+
|
|
95
|
+
It's possible to use your own custom file system by implementing the `FileSystemHost` interface then passing in an instance of this when creating a new `Project` instance:
|
|
96
|
+
|
|
97
|
+
```ts ignore-error: 2420, 2345, 2740
|
|
98
|
+
import { FileSystemHost, Project } from "ts-morph";
|
|
99
|
+
|
|
100
|
+
class MyCustomFileSystem implements FileSystemHost {
|
|
101
|
+
// implement it
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const fs = new MyCustomFileSystem();
|
|
105
|
+
const project = new Project({ fileSystem: fs });
|
|
106
|
+
```
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Instantiating
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Instantiating
|
|
6
|
+
|
|
7
|
+
Use the `Project` named export from `"ts-morph"`:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { Project } from "ts-morph";
|
|
11
|
+
|
|
12
|
+
const project = new Project();
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Compiler options
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { Project, ScriptTarget } from "ts-morph";
|
|
19
|
+
|
|
20
|
+
const project = new Project({
|
|
21
|
+
compilerOptions: {
|
|
22
|
+
target: ScriptTarget.ES3,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### tsconfig.json
|
|
28
|
+
|
|
29
|
+
If you would like to manually specify the path to a _tsconfig.json_ file then specify that:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
const project = new Project({
|
|
33
|
+
tsConfigFilePath: "path/to/tsconfig.json",
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
_Note:_ You can override any `tsconfig.json` options by also providing a `compilerOptions` object.
|
|
38
|
+
|
|
39
|
+
For your convenience, this will automatically add all the associated source files from the _tsconfig.json_. If you don't wish to do that, then you will need to set `skipAddingFilesFromTsConfig` to `true`:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
const project = new Project({
|
|
43
|
+
tsConfigFilePath: "path/to/tsconfig.json",
|
|
44
|
+
skipAddingFilesFromTsConfig: true,
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Custom Module Resolution
|
|
49
|
+
|
|
50
|
+
Custom module resolution can be specified by providing a resolution host factory function. This also supports providing custom type reference directive resolution.
|
|
51
|
+
|
|
52
|
+
For example:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { Project, ts } from "ts-morph";
|
|
56
|
+
|
|
57
|
+
// this is deno style module resolution (ex. `import { MyClass } from "./MyClass.ts"`)
|
|
58
|
+
const project = new Project({
|
|
59
|
+
resolutionHost: (moduleResolutionHost, getCompilerOptions) => {
|
|
60
|
+
return {
|
|
61
|
+
resolveModuleNames: (moduleNames, containingFile) => {
|
|
62
|
+
const compilerOptions = getCompilerOptions();
|
|
63
|
+
const resolvedModules: ts.ResolvedModule[] = [];
|
|
64
|
+
|
|
65
|
+
for (const moduleName of moduleNames.map(removeTsExtension)) {
|
|
66
|
+
const result = ts.resolveModuleName(moduleName, containingFile, compilerOptions, moduleResolutionHost);
|
|
67
|
+
if (result.resolvedModule)
|
|
68
|
+
resolvedModules.push(result.resolvedModule);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return resolvedModules;
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
function removeTsExtension(moduleName: string) {
|
|
76
|
+
if (moduleName.slice(-3).toLowerCase() === ".ts")
|
|
77
|
+
return moduleName.slice(0, -3);
|
|
78
|
+
return moduleName;
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### `libFolderPath`
|
|
85
|
+
|
|
86
|
+
By default, ts-morph uses a fake folder path at `/node_modules/typescript/lib` to serve the TypeScript lib.d.ts files from memory.
|
|
87
|
+
|
|
88
|
+
If you do not want this behaviour, you may specify an actual folder to get the lib files from the file system from:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
const project = new Project({
|
|
92
|
+
libFolderPath: "./node_modules/typescript/lib",
|
|
93
|
+
});
|
|
94
|
+
```
|