<commit_before># TypeScriptAST
.NET port of Microsoft's TypeScript parser for simple AST manipulation.

If works with TypeScript, JavaScript and DefinitelyTyped(".d.ts") files and gives the same tree as typescriptServices.js.

## TS file modification Example

This example included in TypeScriptAstExample. It finds modules in file, collects some info, adds new function to module.

```csharp
  using Zu.TypeScript;
  using Zu.TypeScript.Change;
  using Zu.TypeScript.TsTypes;
  
            var fileName = "parser.ts";
            var source = File.ReadAllText(fileName);

            var ast = new TypeScriptAST(source, fileName);

            var change = new ChangeAST();

            foreach (var module in ast.GetDescendants().OfType<ModuleDeclaration>())
            {
                var funcs = module.Body.Children.OfType<FunctionDeclaration>().ToList();
                var enums = module.Body.Children.OfType<EnumDeclaration>();
                var moduleInfoFunc = $@"
    export function getModuleInfo() {{
        return ""Module {module.IdentifierStr} contains {funcs.Count()} functions ({funcs.Count(v => v.IdentifierStr.StartsWith("parse"))} starts with parse), {enums.Count()} enums ..."";
    }}
";
                change.InsertBefore(module.Body.Children.First(), moduleInfoFunc);
            }
            var newSource = change.GetChangedSource(ast.SourceStr);

            File.WriteAllText("parser2.ts", newSource);

```
<commit_msg>Create AST and Find Node<commit_after># TypeScriptAST
.NET port of Microsoft's TypeScript parser for simple AST manipulation.

If works with TypeScript, JavaScript and DefinitelyTyped(".d.ts") files and gives the same tree as typescriptServices.js.

## Create AST
```csharp
var ast = new TypeScriptAST(File.ReadAllText(file), file);
```
## Find Node
By SyntaxKind
```csharp
  var functions = ast.OfKind(SyntaxKind.FunctionExpression);
  var vars = functions.FirstOrDefault()?.OfKind(SyntaxKind.VariableDeclaration);
```
By Node type
```csharp
  functions = ast.GetDescendants().OfType<FunctionExpression>();
  vars = functions.FirstOrDefault()?.GetDescendants().OfType<VariableDeclaration>();
```
## File modification Example

This example included in TypeScriptAstExample. It finds modules in file, collects some info, adds new function to module.

```csharp
  using Zu.TypeScript;
  using Zu.TypeScript.Change;
  using Zu.TypeScript.TsTypes;
  
            var fileName = "parser.ts";
            var source = File.ReadAllText(fileName);

            var ast = new TypeScriptAST(source, fileName);

            var change = new ChangeAST();

            foreach (var module in ast.GetDescendants().OfType<ModuleDeclaration>())
            {
                var funcs = module.Body.Children.OfType<FunctionDeclaration>().ToList();
                var enums = module.Body.Children.OfType<EnumDeclaration>();
                var moduleInfoFunc = $@"
    export function getModuleInfo() {{
        return ""Module {module.IdentifierStr} contains {funcs.Count()} functions ({funcs.Count(v => v.IdentifierStr.StartsWith("parse"))} starts with parse), {enums.Count()} enums ..."";
    }}
";
                change.InsertBefore(module.Body.Children.First(), moduleInfoFunc);
            }
            var newSource = change.GetChangedSource(ast.SourceStr);

            File.WriteAllText("parser2.ts", newSource);

```

{'fraction_non_alphanumeric': 0.11628596855532483, 'fraction_numerical': 0.0005932957579353308, 'mean_word_length': 3.1940298507462686, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3643995', 'n_tokens_mistral': 929, 'n_tokens_neox': 893, 'n_words': 244}