Coder Social home page Coder Social logo

kataw / kataw Goto Github PK

View Code? Open in Web Editor NEW
330.0 12.0 5.0 228.91 MB

An 100% spec compliant ES2022 JavaScript toolchain

Home Page: https://kataw.github.io/kataw/kataw_ast/

License: ISC License

JavaScript 1.83% TypeScript 98.17%
estree performance cst parsing ast-nodes typescript cst-parser recovery-mode error-recovery ecma

kataw's Introduction

Kataw

An insane fast Javascript toolchain.

Kataw NPM GitHub license Meriyah NPM


WIP

Kataw is a JavaScript toolchain that aim to unify functionality that has previously been separate tools. It features everything from low-level CST manipulation to tools like linting, code analyzes, transform, and minification.

The toolchain's core is based upon a ECMAScript friendly CST that allows you to parse ECMAScript® 2022 (ECMA-262 12th Edition) language specification.

If the only goal is to perform syntactic analysis (parsing) of a Javascript program, you can do this with either kataw.parseModule or kataw.parseScript.

Noted that with ES2015 and later a Javascript program can be either a script or a module.

Here is an example on how to set up Kataw to act like for example Acorn:

 // Parse with module goal
 kataw.parseModule('x = y', { next: true }, function(source, kind, msg, line, column) {
    throw msg + '(' + line + ', ' + column + ')';
 });

 // Parse in script mode
 kataw.parseScript('x = y', { next: true }, function(source, kind, msg, line, column) {
    throw msg + '(' + line + ', ' + column + ')';
 });

The returned CST tree can now be used as an AST.

Note that the CST contains more information that can be extracted from the CST node's through public API methods.

Many of these APIs have the advantage that they allow you to "retrieve" info that is not otherwise available with a standard AST parser.

One example is that you only need to use kataw.isStatementNode to find out if the current CST node is a statement node. With an AST parser you must use a switch statement with 60 switch cases.

 // With Babel you are forced to do
 switch(node.type) {
   case 'SwitchStatement': ...
   case 'ReturnStatement': ...
 }

 // With Kataw
 kataw.isStatementNode(node); // return 'true'

A second benefit with this CST parser is that it is running in recovery mode by default and can be used in any editor. A build-in diagnostic system reports diagnostics if an error handler have been used. The diagnostics are dynamic. It means all the diagnostics are informative, and they will change based on the context you are parsing in.

These features used together gives you more options to adjust, modify and customize the CST tree compared to a regular AST parser and you can also write fewer code lines and at the same time experience insane performance.

CST nodes

All CST nodes has a kind which is a number that represents the node type. It's identical to ESTree type with the exception that Kataw doesn't do any string comparisons - everything in Kataw is a number.

Here is an example:

if (node.kind === Kataw.SyntaxKind.Identifier) {}

You need to use kataw.visitEachChild to traverse the CST tree to get access to each CST node. After that you do any kind of transformation.

Be aware that also the kind contain some additional information that you can extract through the public API - not only the NodeFlags.

For example Kataw.isKeyword, Kataw.isIdentifier, and Kataw.isFutureReserved.

This is made possible because there are no token in Kataw. Everything is a SyntaxKind - token and kind merged into one.

Kataw also exports all CST nodes so you can create your own nodes. This is handy if you want to try out new ECMA features that isn't part of the language yet, or make your own transformers as in Babel.

Here is an example on how to create an CST node:

 // creates an identifier
 kataw.createIdentifier(/* text */ 'hello', /* rawText */ 'hello', /* start */ 1,  /* end */ 5)

Some CST nodes needes additional info. This can be set using the Kataw.NodeFlags andt this bitwise mask can be set on every CST node and CST keyword node.

 // creates an string literal
 const str = kataw.createStringLiteral(
    /* text */ 'hello', /* rawText */ 'hello', /* start */ 1,  /* end */ 5
);

 // set the flag and mark it as a single quote. E.g. 'string'
 str.flag |= Kataw.NodeFlags.SingleQuote.

 // Check if the flag is set
 kataw.isSingleQuote(str); // true

CST keywords

All keywords in Kataw is it's own CST node, and you create them in almost the same way as any other CST nodes.

kataw.createToken(kataw.SyntaxKind.ForKeyword, Kataw.NodeFlags.NoChildren, /* start */ 1,  /* end */ 5);

Diagnostics

Diagnostics in Kataw can either be error, warning or lint failure.

The diagnostics have been designed like this so you can quickly understand what the problem is and correct it.

Adding a error handler as the 3rd argument will enable diagnostics. The diagnostics are flexible and let you use them together with Kataw's own reporters or you can create your own reporter or whatever is your use case.

Here is how it works:

import { parseScript } from 'kataw';

parseScript('[x', { next: true }, function(diagnosticSource, kind, message, start, end) {
});

Diagnostic arguments

Param Description
diagnosticSource Is either Lexer or Printer.
kind Is either lint, error, warning
message The diagnostic message
start The start position of the diagnostics
end The end position of the diagnostics

ESNext

Stage 3 proposals can be parsed if the next options are enabled.

Stage 1 and stage 2 proposals are not supported because the specs drafts are changing all the time.

Types

Kataw has it's own type system that is an improvement over Typescript and Flow, and it conform to the ECMAScript® 2022 (ECMA-262 12th Edition) language specification.

As everything else - it's developed for high performance and it consumes less memory.

It allows you to parse syntax like function x(y: string, z: number): string | number {} and other similiar syntax.

The type system is still WIP and will be enabled by default in the CLI together with Kataw's own type checker.

You can manually enable this if you enable the allowTypes option. It will then parse the types but it will not do any type checking.

You can use kataw.removeKatawTypes to remove Kataw's types from the CST tree

const source = kataw.parseModule('let: string', { allowTypes: true});
// Remove the types
kataw.removeKatawTypes(source);

Comments

Leading and trailing comments can be extracted at correct position with kataw.getLeadingComments and kataw.getTrailingComments.

Hello
/* I'm a comment */
  there!

Getting the trailing comment of Hello can be done like this kataw.getTrailingComments(5, 24). It get the comments from the end value of hello until the start value of there!.

If you want a 1:1 copy of the actual source code, you can do a "slice" from the start value of Hello to the end value of there!.

Linting

Rules still being added, but Kataw can go linting either through public API methods or options. Most of ESLint common or recommended rules also works for Kataw and you can either enable or disable them.

Linting with public API

It can be done like this

import { lintScript } from 'kataw';

lintScript('eval()', { reporter: aladdin }, { noEval: true});

Linting with parser options

import { parseScript } from 'kataw';

parseScript('eval()', { noEval: true});

The DiagnosticKind will be set to DiagnosticKind.Lint and you can chose to ignore this and treat the diagnostic as any other error, or for example create your own reporter.

Transformation

Kataw can act the same way asBabel and be a tool that helps you write code in the latest version of Javascript. This can be done with developing transformers to handle situations where your supported environments don't support certain features natively.

The compiler transform those features down to a supported version.

You have to use kataw.visitEachChild to traverse the CST tree. kataw.visitNodecan be used to traverse a single node, and kataw.visitNodes to visit an array of CST nodes. This API method should only be used on lists. CST nodes that is known to contain an array. There are no need to use for example Array.Array to verify if it's an array. Performance is maintained that way.

All CST nodes will be updated automatically if any changes has been detected.

Keywords can also be swapped around and the same with AssignmentExpression, BinaryExpression, UnaryExpression and UpdateExpression operands. For example !== can be changed to ===.

A WithStatement can be transformed into a WhileStatement simply by changing the value of the TokenNode.

The location of the CST node in the CST tree can also be changed if you change the values of start and end on the CST node.

Changing the NodeFlags allow you to change how the CST node should behave.

All this things gives a you better control over transformation of each CST node compared to Babel and Rome.

Here is an example on an simple transformer that will replace all identifiers with an NumericLiteral.

export function swapIdentifierWithNumeric(transform) {
  return transformSourceFile;

  function transformSourceFile(root) {
    switch (node.kind) {
      case kataw.NodeKind.Identifier:
        return kataw.createNumericLiteral(
          123,
          "123",
          kataw.NodeFlags.ExpressionNode | kataw.NodeFlags.NoChildren,
          /* start */ 1,
          /* end */ 3
        );
      default:
        return kataw.visitEachChild(transform, root, visitor);
    }
  }

  function visitor() {
    switch (node.kind) {
      default:
        return kataw.visitEachChild(transform, node, visitor);
    }
  }
}

Printing

Kataw is adjustable and allows three different ways to print your source code.

The returned source does not include any extra parenthesis or unnecessary code.

The comments are 100% correct and they will be printed in the places you expect.

API Description
print Prints a given CST tree and let you adjust the diagnostics and set your own parser options
printModule Prints the source in module goal
printScript Prints the source in script mode

Here is an example:

// Print
 kataw.print(kataw.parseModule('x = y', { next: true }, function(source, kind, msg, line, column) {
    throw msg + '(' + line + ', ' + column + ')';
 }));

 // Print with module goal
 kataw.printModule('x = y');

 // Print in script mode
 kataw.printScript('x = y');

Ignore comment

Statements, blocks and other code lines can be ignored in Kataw with a // kataw-ignore comment.

If set on a WhileStatement it will ignore the entire statement and the BlockStatement.

// kataw-ignore
while (true) {}

You can use kataw.shouldIgnoreNextNode(node); to verify if the node should be ignored.

CST parser features

  • Error recovery by default (like Acorn loose), but it reconstruct the CST tree correctly

  • Optional error reporting (require a callback as the parsers 3rd argument)

  • Dynamic error, hint and warning diagnostics (depends on the context you are parsing in)

  • Public API methods to extract info from the CST nodes

  • 100% correct comment extraction and attachment algorithm

  • Can parse types and type annotations (Kataw has it's own type system)

  • Can be used in any editors

  • Scalable

  • Performance

Current state

  • The CST parser can be used in production

Roadmap

📌v0.1

  • Parsing ECMA 262(aka JavaScript), and the cst spec be stable
  • Test 262 passes
  • Printing API (like prettier API)
  • //kataw-ignore(like //prettier-ignore)
  • Command line interface (like prettier cli)
  • Documentation & website

v0.2

  • plugin system, to make it possible to support jsx/ts/flow...
  • jsx plugin
  • ts plugin

v0.3

  • transformers: like babel
  • minify: like uglify-js
  • linter: like eslint

v1.0

Future

  • A "hook system" for adding additional rules for the linter and the grammar checker will be published.

  • Hooks to support experimental syntax and ECMA proposals in an sandboxed envirnonment

kataw's People

Contributors

aladdin-add avatar kflash avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kataw's Issues

extend test runner to print errors

With the upcoming refactoring of the Kataw parser, the error handling is an callback func. So it's needed to extend the
test runner to print in each '.md' errors if they are returned by the cb.

As of now we will never know if any error diagnostics has been thrown

TODO's

  • AST that conforms to the ECMA specs

  • TS / JS parser

  • Travers / walker

  • Transformer API

  • Public API to generate AST nodes

  • Grammar checker

  • Pretty printing

  • Linting

  • Minifier

investigate loc pos for all nodes

Looks like some node start / end values are off by 1.

This is not critical. The start / end values are only for internal usage and will only affect comment attachments.

Skip "hybrid CST" and use real CST?

In the upcoming rewrite of the parser "tokens" no longer exist and have been merged together with "nodeKind". That makes it easy to save each "token" on the CST. I have already done it in the rewrite for a few productions - conditional, unary, update etc. where the operator token has been saved.

When it comes to binary expr. The token has also been saved, and it now contains the exact same metadata both for parsing and AST nodes. It's a 80% perf gain both in a typechecker, transformer and printer.

Getting the precedence value is done like this:

operator.kind & SyntaxKind.Precedence

and we get 10.

if we need it's true identity, we can do

SyntaxLookup[operator.kind]

and we get +.

Here is an example on how the binary expr CST now looks like.

{
    "kind": 122,
    "statements": [
        {
            "kind": 120,
            "expression": {
                "kind": 198,
                "left": {
                    "kind": 16385,
                    "value": "a",
                    "flags": 768,
                    "start": 0,
                    "end": 1
                },
                "operator": {
                    "kind": 43570,
                    "flags": 0,
                    "start": 1,
                    "end": 3
                },
                "right": {
                    "kind": 16385,
                    "value": "b",
                    "flags": 768,
                    "start": 3,
                    "end": 5
                },
                "flags": 256,
                "start": 0,
                "end": 5
            },
            "flags": 128,
            "start": 0,
            "end": 5
        }
    ],
    "text": "a + b",
    "fileName": "filename",
    "flags": 0,
    "diagnostics": [],
    "start": 0,
    "end": 5
}

The point of the NodeFlags have also been changed, and nodeKind & NodeKInd.StatementNode can be used if we need to group all statement nodes. It's much better than a huge switch statement and 50% perf gain. For this we have available 27 slots.

The 2 upper slots has been used for line termination and loc tracking.

@aladdin-add Any thoughts? Easy enough to understand?

comments and comment extraction

Going to implement a way to extract comments so they can be attached in the printer. This has to be done 100% correct, so we don't suffer from Babel, Acorn, Esprima, Espree and Prettier issues.

Comments are not part of the AST by default.

@aladdin-add seems like espree have a comment issue 👎

improve performance for Kataw parser

Kataw's parser performance isn't as good as it could have been. Currently the parser is un-optimized, and I think it's performance can be improved by 10 - 20 %.

As of now the parser has an average of 40% perf gain over Acorn and around 55% perf gain over Babel parser. The goal should be 50% and 65%..

Also GC and memory usage is an key factor here.

Before optimization:

before

add benchmark result in test runner

should add benchmark result in test runner so we know how it perform. Something like:
'x test ran for 20 minutes (2 opts/sec)" with different colors or test runner time and bench result.

type error in test runner

test/cli.ts:30:111 - error TS2322: Type 'number' is not assignable to type '{ label: number; sent: () => any; trys: any[]; ops: any[]; }'.

30 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }

need to validate printer output

Need to validate printer output

  1. Normal parse

  2. If error, print diagnostic

  3. If no error, print

  4. Parse printed output and output diagnostic if errors

Implement type checker with optional type annotations

WIP

@aladdin-add We got an issue. Look at this.
So I have changed the original plans for Kataw. I ditch TS and going to implement type checker with optional type annotations that will solve the issues I linked too.

No time frame for this, but it's a WIP. The other bullet points in the readme stays the same.

Use of exit code output NPM msg if snapshot mismatch

Use of exit code gives this message now if snapshot mismatch
Output mismatch for D:\kataw\test_snapshot_/compiler/ts/contextualExpressionTypecheckingDoesntBlowStack.md
Output mismatch for D:\kataw\test_snapshot_/compiler/ts/nestedLoops.md
Running 11257 test cases. Total time: 7.180s
Mismatch: 7/11257
exit code: 1
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] test: ts-node test/cli
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:

confusing typings

export function forEachChild(node: any, visitor: (node: SyntaxKind) => SyntaxKind): any {
const kind = node.kind;
// Childless AST nodes - nodes without any children.
if (node.flags & NodeFlags.ChildLess) return node;
// Switch - Frequently used nodes first
switch (kind) {

what's the type of "node" -- SyntaxKind is just numbers, node.kind/node.flags will throw an error?

binding is undefined sometimes

I found this when fixing deepEqual edge cases:

kataw/test/runner/utils.ts

Lines 87 to 109 in f23544c

// NaN, Infinity was stringified to null.
// refs: https://github.com/kataw/kataw/issues/23
// v !== v (v = NaN)
obj1 = obj1 === Infinity || obj1 !== obj1 ? null : obj1;
obj2 = obj2 === Infinity || obj2 !== obj2 ? null : obj2;
const type1 = toString.call(obj1);
const type2 = toString.call(obj2);
if (type1 !== type2) return false;
if (type1 === '[object Array]') {
return obj1.every((_: any, idx: number) => deepEqual(obj1[idx], obj2[idx]));
}
if (type1 === '[object Object]') {
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
return keys1.every(k => keys2.includes(k)) && keys1.every((k) => deepEqual(obj1[k], obj2[k]));
}
return obj1 === obj2;

undefined is not a valid value in JSON(ECMA 404), please use null in this case.

another way is to implement its own parse and stringify, I'm not sure it's worthy.

implement transformers

Need to develop different transformers and get them running, plus update current transformer API to work with scoping, and to verify that transformers can be created as a plugin.

add CLI with report

Need to add a CLI so the parser can run on the command line like NodeJS and V8.

Should use an red line + arrow + to mark errors. Can use the start and end values of the diagnostics for that. The diagnostics are already developed for this purpose.

error TS2343: This syntax requires an imported helper named '__spreadArray' which does not exist in 'tslib'. Consider upgrading your version of 'tslib'.

➜  kataw git:(main) ✗ npm run bundle

> [email protected] bundle
> cross-env rimraf dist && node scripts/bundle.js

creating normal bundle
writing /home/weiran/repo/kataw/dist/kataw.esm.js
writing /home/weiran/repo/kataw/dist/kataw.umd.js
creating minified bundle
writing /home/weiran/repo/kataw/dist/kataw.esm.min.js
writing /home/weiran/repo/kataw/dist/kataw.umd.min.js
creating normal es5 bundle
/home/weiran/repo/kataw/node_modules/rollup/dist/shared/rollup.js:5279
        base = Object.assign(new Error(base.message), base);
                             ^

Error: src/compiler/utils.ts:37:11 - error TS2343: This syntax requires an imported helper named '__spreadArray' which does not exist in 'tslib'. Consider upgrading your version of 'tslib'.

37   return [...array1, ...array2];
             ~~~~~~~~~

    at error (/home/weiran/repo/kataw/node_modules/rollup/dist/shared/rollup.js:5279:30)
    at throwPluginError (/home/weiran/repo/kataw/node_modules/rollup/dist/shared/rollup.js:18240:12)
    at Object.error (/home/weiran/repo/kataw/node_modules/rollup/dist/shared/rollup.js:18847:24)
    at Object.error (/home/weiran/repo/kataw/node_modules/rollup/dist/shared/rollup.js:18409:38)
    at RollupContext.error (/home/weiran/repo/kataw/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:17237:30)
    at /home/weiran/repo/kataw/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:25030:19
    at arrayEach (/home/weiran/repo/kataw/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:545:11)
    at Function.forEach (/home/weiran/repo/kataw/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:9397:14)
    at printDiagnostics (/home/weiran/repo/kataw/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:25006:12)
    at Object.transform (/home/weiran/repo/kataw/node_modules/rollup-plugin-typescript2/dist/rollup-plugin-typescript2.cjs.js:29277:17) {

Printing and pretty printing

Printing in Kataw will replace the need of using Prettier for this project. It's a long, complex process because the printer also need to handle

  • transformation

  • incremental parsing

The printer will have a slightly different style set than Prettier, and because of the "hybrid" CST I fixed it so the code style will change if the end-user are using line break or not.

Example [ a, b, c, 1, 3, 4] will be printed as is. Same in Prettier.

   [
 a, b, c, 1, 3, 4]
 

will be printed as multiline. Note the line break. The output will be

[
    a,
    b,
    c,
    1,
    3,
    4
] 

For classes and decorators I'm going to keep the Prettier style so this production

 @A
      @B
      @C
      @D
      class x {
        @E@F@G@H@I@J@K@L@M@N@O@D@P@D@Q
            @R
        private readonly foo = bar;
        }

will be pretty printed as

@A
@B
@C
@D
class x {

    @E
    @F
    @G
    @H
    @I
    @J
    @K
    @L
    @M
    @N
    @O
    @D
    @P
    @D
    @Q
    @R
    private readonly foo = bar;
}

Comments are another issue. Everyone seems to have a comment issue, and Prettier have too many.

The Kataw printer will print comments 100% correct. Here is an preview. The comment
after the access modifier will be printed in wrong location with Prettier and Babel.

printer

FUTURE

The printer can already print out any part of the AST, not only the entire tree. So in the future the idea is to parse only parts of the AST on the server side and send it to client side. On client - get the end value of the parent node , print it and do incremental parsing to insert the changes into the AST.

This will save bandwidth and bytes, because there is no need to send the entire AST from client to server. This is still a early alpha locale, but will be open sourced in the future.

It will also be possible to do this with streams soon as incremental update have been open sourced.

The plans is also to incremental update a transformed node instead of how it's done today.

@aladdin-add @3cp Thoughts?

test runner doesn't work with the printer

I tried to parse an simple identifier "aladdin". It doesn't get printed in the '.md'. However. If I manually return a text string it get printed.

My guess is that there are no CST node given to the printer, or the CST node is wrong?

Kataw and Concrete Syntax Tree (CST)

Kataw have have moved forward and are now using a CST instead of AST to make it easier to print, lint and minify, and the parser are no longer using the "old concept" of tokens. In fact. There is no more tokens in the parser - the CST / AST kind have been merged into one.

SyntaxKind.Identifier is both the SyntaxKind and what is known from other parsers as token.

"kind": 122, is the SyntaxKind.Identifier.

{
    "kind": 122,
    "statements": [
        {
            "kind": 120,
            "expression": {
                "kind": 81921,
                "value": "foo",
                "raw": "foo",
                "flags": 768,
                "start": 0,
                "end": 3
            },
            "flags": 128,
            "start": 0,
            "end": 3
        }
    ],
    "isModule": false,
    "text": "foo",
    "fileName": "__root__",
    "flags": 0,
    "diagnostics": [],
    "start": 0,
    "end": 3
}

If we need to extract some CST info, it can for example be done like this node.flags & NodeFlags.IsStatement.

This is how it looks like if we parse if (x) {} else { while(y) { z = 1; } }. As we can see, the keywords are part of the CST.

{
    "kind": 122,
    "statements": [
        {
            "kind": 164,
            "ifKeyword": {
                "kind": 37757019,
                "flags": 768,
                "start": 0,
                "end": 2
            },
            "expression": {
                "kind": 81921,
                "value": "x",
                "raw": "x",
                "flags": 768,
                "start": 4,
                "end": 5
            },
            "consequent": {
                "kind": 249,
                "block": {
                    "kind": 124,
                    "statements": [],
                    "multiLine": false,
                    "flags": 128,
                    "start": 8,
                    "end": 8
                },
                "flags": 128,
                "start": 6,
                "end": 9
            },
            "elseKeyword": {
                "kind": 4194389,
                "flags": 768,
                "start": 9,
                "end": 14
            },
            "alternate": {
                "kind": 249,
                "block": {
                    "kind": 124,
                    "statements": [
                        {
                            "kind": 154,
                            "whileKeyword": {
                                "kind": 37757028,
                                "flags": 768,
                                "start": 16,
                                "end": 22
                            },
                            "expression": {
                                "kind": 81921,
                                "value": "y",
                                "raw": "y",
                                "flags": 768,
                                "start": 23,
                                "end": 24
                            },
                            "statement": {
                                "kind": 249,
                                "block": {
                                    "kind": 124,
                                    "statements": [
                                        {
                                            "kind": 120,
                                            "expression": {
                                                "kind": 125,
                                                "left": {
                                                    "kind": 81921,
                                                    "value": "z",
                                                    "raw": "z",
                                                    "flags": 768,
                                                    "start": 27,
                                                    "end": 29
                                                },
                                                "operatorToken": {
                                                    "kind": 67174402,
                                                    "flags": 768,
                                                    "start": 27,
                                                    "end": 31
                                                },
                                                "right": {
                                                    "kind": 81921,
                                                    "value": 1,
                                                    "raw": "1",
                                                    "flags": 768,
                                                    "start": 31,
                                                    "end": 33
                                                },
                                                "flags": 256,
                                                "start": 27,
                                                "end": 33
                                            },
                                            "flags": 128,
                                            "start": 27,
                                            "end": 34
                                        }
                                    ],
                                    "multiLine": false,
                                    "flags": 128,
                                    "start": 27,
                                    "end": 34
                                },
                                "flags": 128,
                                "start": 25,
                                "end": 36
                            },
                            "flags": 128,
                            "start": 16,
                            "end": 36
                        }
                    ],
                    "multiLine": false,
                    "flags": 128,
                    "start": 16,
                    "end": 36
                },
                "flags": 128,
                "start": 14,
                "end": 38
            },
            "flags": 128,
            "start": 0,
            "end": 38
        }
    ],
    "isModule": false,
    "text": "if (x) {} else { while(y) { z = 1; } }",
    "fileName": "__root__",
    "flags": 0,
    "diagnostics": [],
    "start": 0,
    "end": 38
}

Punctuators are not part of the CST too keep the CST small. Instead the concept 'lists' has been used and it conforms to the ECMA specs.

For example a(). Here we are using 5.1.5 Grammar Notation - ArgumentList, so we know the exact start and end values for this empty list.

LineBreak and trailingComma is it's own property on some of the nodes.

Number and string literal and identifiers got their own raw property .

test runner prints invalid syntax

The test runner accept CST nodes with invalid syntax to be printed. Need to use the callback here and only allow printing if valid syntax. That should be inline with Prettier

(node:18296) Warning:

(node:18296) Warning: Label 'Running 11266 test cases. Total time' already exists for console.time()

es2022 support

  • class fields
  • top-level await
  • regexp-match-indices
  • private-fields-in-in(#x in obj)

find a way to test AST walker and API

Need to find a way to test the CST walker and the public API methods. They can be used together

kataw.forEachChild(rootNode, visitor);

function visitor(node) {

   // check if the node has any children
   if (!kataw.isChildLess(node)) {
  return kataw.forEachChild(node, visitor);
  }
}

test runner isn't consistent

After adding the progress bar it will still output 'Running 18941 test cases. Total time: 7.454s'

The tests have been run so maybe change to "Ran x test cases"?

The 'Total time' is different than what you see on the progress bar.

Autogenerate files suggest ''run test:update'. That command doesn't exist

progress bar issues

Type 'typeof ProgressBar' has no construct signatures.

18 const bar = new ProgressBar('Testing snapshots [:bar] :percent, :elapseds elapsed, eta :etas,', {
~~~~~~~~~~~

test/cli.ts:6:1
6 import * as ProgressBar from 'progress';
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead.

improve test runner

feat:

  • exit code
  • test coverage (with c8)
  • parsing/printer/linter/minify options

refactor:

  • get rid of the constants and make a .md template
  • separately update snapshots

bugfix:

  • non-ascii chars and escaped chars get correctly printed in .md files

running prettier throws

Tried to run prettier

git merge-base HEAD main
git diff --name-only --diff-filter=ACMRTUB b5d3e6bb665c5ebe459a5da226798b0cb0a31b7a
node:child_process:712
throw err;
^

<ref *1> Error: spawnSync git ENOBUFS
at Object.spawnSync (node:internal/child_process:1086:20)
at spawnSync (node:child_process:676:24)
at execFileSync (node:child_process:703:15)
at Module._compile (node:internal/modules/cjs/loader:1092:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1121:10)
at Module.load (node:internal/modules/cjs/loader:972:32) {
errno: -4060,
code: 'ENOBUFS',
syscall: 'spawnSync git',
path: 'git',
spawnargs: [
'diff',
'--name-only',
'--diff-filter=ACMRTUB',
[ 'b5d3e6bb665c5ebe459a5da226798b0cb0a31b7a' ]
],
error: [Circular *1],
status: null,
signal: 'SIGTERM',
output: [
null,
'.eslintrc.js\n' +
'.gitattributes\n' +
'.npmrc\n' +
'.prettierignore\n' +
'.vscode/launch.json\n' +
'.vscode/settings.json\n' +
'LICENSE.md\n' +
'README.md\n' +
'package-lock.json\n' +
'package.json\n' +
'scripts/bump-dev-version.js\n' +
'scripts/generate-unicode.js\n' +

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.