Stryker: [rfc idea] unify JavaScript & TypeScript mutators

Created on 26 Nov 2019  路  10Comments  路  Source: stryker-mutator/stryker

While working on the additional mutations I proposed in PR #1891, I started wondering if it might be practical to consider combine the JavaScript & TypeScript mutators together.

I can think of a couple of possible approaches:

  • Prettier is able to have a unified "estree" format from Babel and from TypeScript using @typescript-eslint/typescript-estree package. Prettier is also able to use Babel to parse TypeScript, with some known limitations at this point, as proposed in prettier/prettier#6400.
  • It would also be possible to use the TypeScript parser to parse both JavaScript and TypeScript, an idea discussed in prettier/prettier#6888.

Another thing that can probably help some parsing beginners like myself is: https://astexplorer.net/

P.S. I can think of some important points that should be summarized here in the description as well:

  • My idea to use @typescript-eslint/typescript-estree is there to help bridge the differences in syntax tree output from Babel and typescript parsers, as I explained in multiple comments below.
  • I am now thinking that the parser could be moved into its own pluggable stage
  • The next challenge is how to deal with things like JSX, TSX, Vue with JavaScript, and Vue with TypeScript. (Prettier seems to already have a solution to deal with these formats.)

Please, if anything is not clear in this descriptions or in the comments below, ask.

All 10 comments

From a quick look, I noticed that the arrow function mutator only exists on the TypeScript mutator, also seems to be missing here: https://github.com/stryker-mutator/stryker-handbook/blob/master/mutator-types.md

I would also very likely favor just using the TypeScript parser to parse both JavaScript and TypeScript. When working on PR #1891, the TypeScript mutators seemed to be much easier to write and update.

It would be really nice feature I guess. People could use Babel + typescript and everything within one configuration <3 the problem is Vue xD it has its own mutator :x

People could use Babel + typescript and everything within one configuration

Yes

https://iamturns.com/typescript-babel/

The one thing is that the Babel ESTree mutators for JavaScript do not seem to be as clean or easy to write as the TypeScript mutators. I would like to take a look at this at some point.

the problem is Vue xD it has its own mutator

Right. I suspect we should be able to switch from using vue-template-compiler to putting Vue sources through the Babel pipeline.

the problem is that typescript and babel produce different syntax trees (as I remember), so it might need to rewrite quite a bit of code (mostly tests tho) and to test it properly again.

typescript and babel produce different syntax trees

Yes. I think you know that existing JavaScript mutator deals with the syntax tree from Babel, and the existing TypeScript mutator deals with the syntax tree from TypeScript, and they seem to use mostly the same test suite.

I think it should also be clear that the main point of this issue is to move towards a more converged solution for parsing and mutating JavaScript and TypeScript, and even Vue, if possible. This should be more consistent with similar tools such as ESLint and Prettier.

Is there anything else not clear?

P.S. I think I need to explain my response more directly. Quoting from a response below:

One of my ideas, which I should have explained more clearly, is that @typescript-eslint/typescript-estree can be used to invoke the installed typescript package to parse the TypeScript, and get the parsed syntax tree in an "estree" format that is _similar_ to the format returned by the Babel parser. The typescript-eslint & Prettier tool packages already use this kind of solution.

This is how I think we should be able to bridge over the difference between the syntax trees from typescript and Babel. Please ask if anything is still not clear here.

So for review, my general idea right now would be to handle JavaScript, TypeScript, Vue, JSX, etc. by using the existing JavaScript mutator implementation, which we know is already using Babel to do the parsing. I think this would give us very nice consistency with other tools in the ecosystem such as ESLint and Prettier.

I raised PR #1898 to improve the quality of the existing JavaScript mutator and add the missing arrow function mutator.

Please let me know if there are any more questions or concerns. I wouldn't mind if anyone wants to start working on this idea.

I'd prefer just having one mutator instead of making the code more complicated (in my eyes) by trying to share some logic between the two mutators.

EDIT: mutating typescript with babel should be possible, but the plugins may be a bit tricky because with the typescript mutator we can just use the user's typescript version and run with that setup.

I'd prefer just having one mutator

That is what I was trying to imply, guess it was not clear enough.

I had been thinking it should be possible to just use Babel with its TypeScript plugin to parse TypeScript, if needed. As I said before, here is a nice article on the subject: https://iamturns.com/typescript-babel/

EDIT: mutating typescript with babel should be possible, but the plugins may be a bit tricky [...]

I was afraid of this kind of thing, which is why I had already listed multiple alternative ideas.

[...] with the typescript mutator we can just use the user's typescript version and run with that setup.

Yes.

One of my ideas, which I should have explained more clearly, is that @typescript-eslint/typescript-estree can be used to invoke the installed typescript package to parse the TypeScript, and get the parsed syntax tree in an "estree" format that is similar to the format returned by the Babel parser. The typescript-eslint & Prettier tool packages already use this kind of solution.

I am now thinking we should consider making the parser part into a separate, pluggable stage. Then the parser would output some kind of "estree" syntax tree format that can be used by the mutator to generate the output with the desired mutations.

The next challenge is how to deal with things like JSX, TSX, Vue with JavaScript _and Vue with TypeScript_. Prettier seems to already have a solution to deal with these formats.

I hope this is clear, please feel free to ask if not clear for any reason.

I believe it is solved right now 馃

@kmdrGroch I think you are right because of the mutation switching feature. Unfortunately I really do not understand the mutation switching update right now. But I think it can be closed. Thanks.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

trollepierre picture trollepierre  路  18Comments

nicojs picture nicojs  路  33Comments

Lakitna picture Lakitna  路  42Comments

anthony-telljohann picture anthony-telljohann  路  19Comments

simondel picture simondel  路  25Comments