@d-es-ign/stryker-js-instrumenter 9.6.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.
Files changed (327) hide show
  1. package/LICENSE +201 -0
  2. package/dist/src/create-instrumenter.d.ts +16 -0
  3. package/dist/src/create-instrumenter.d.ts.map +1 -0
  4. package/dist/src/create-instrumenter.js +15 -0
  5. package/dist/src/create-instrumenter.js.map +1 -0
  6. package/dist/src/disable-type-checks.d.ts +11 -0
  7. package/dist/src/disable-type-checks.d.ts.map +1 -0
  8. package/dist/src/disable-type-checks.js +125 -0
  9. package/dist/src/disable-type-checks.js.map +1 -0
  10. package/dist/src/file.d.ts +6 -0
  11. package/dist/src/file.d.ts.map +1 -0
  12. package/dist/src/file.js +2 -0
  13. package/dist/src/file.js.map +1 -0
  14. package/dist/src/frameworks/angular-ignorer.d.ts +16 -0
  15. package/dist/src/frameworks/angular-ignorer.d.ts.map +1 -0
  16. package/dist/src/frameworks/angular-ignorer.js +85 -0
  17. package/dist/src/frameworks/angular-ignorer.js.map +1 -0
  18. package/dist/src/frameworks/index.d.ts +4 -0
  19. package/dist/src/frameworks/index.d.ts.map +1 -0
  20. package/dist/src/frameworks/index.js +7 -0
  21. package/dist/src/frameworks/index.js.map +1 -0
  22. package/dist/src/index.d.ts +9 -0
  23. package/dist/src/index.d.ts.map +1 -0
  24. package/dist/src/index.js +8 -0
  25. package/dist/src/index.js.map +1 -0
  26. package/dist/src/instrument-result.d.ts +7 -0
  27. package/dist/src/instrument-result.d.ts.map +1 -0
  28. package/dist/src/instrument-result.js +2 -0
  29. package/dist/src/instrument-result.js.map +1 -0
  30. package/dist/src/instrumenter-options.d.ts +5 -0
  31. package/dist/src/instrumenter-options.d.ts.map +1 -0
  32. package/dist/src/instrumenter-options.js +2 -0
  33. package/dist/src/instrumenter-options.js.map +1 -0
  34. package/dist/src/instrumenter-tokens.d.ts +6 -0
  35. package/dist/src/instrumenter-tokens.d.ts.map +1 -0
  36. package/dist/src/instrumenter-tokens.js +6 -0
  37. package/dist/src/instrumenter-tokens.js.map +1 -0
  38. package/dist/src/instrumenter.d.ts +24 -0
  39. package/dist/src/instrumenter.d.ts.map +1 -0
  40. package/dist/src/instrumenter.js +76 -0
  41. package/dist/src/instrumenter.js.map +1 -0
  42. package/dist/src/mutant-placers/expression-mutant-placer.d.ts +10 -0
  43. package/dist/src/mutant-placers/expression-mutant-placer.d.ts.map +1 -0
  44. package/dist/src/mutant-placers/expression-mutant-placer.js +144 -0
  45. package/dist/src/mutant-placers/expression-mutant-placer.js.map +1 -0
  46. package/dist/src/mutant-placers/index.d.ts +5 -0
  47. package/dist/src/mutant-placers/index.d.ts.map +1 -0
  48. package/dist/src/mutant-placers/index.js +11 -0
  49. package/dist/src/mutant-placers/index.js.map +1 -0
  50. package/dist/src/mutant-placers/mutant-placer.d.ts +8 -0
  51. package/dist/src/mutant-placers/mutant-placer.d.ts.map +1 -0
  52. package/dist/src/mutant-placers/mutant-placer.js +2 -0
  53. package/dist/src/mutant-placers/mutant-placer.js.map +1 -0
  54. package/dist/src/mutant-placers/statement-mutant-placer.d.ts +8 -0
  55. package/dist/src/mutant-placers/statement-mutant-placer.d.ts.map +1 -0
  56. package/dist/src/mutant-placers/statement-mutant-placer.js +24 -0
  57. package/dist/src/mutant-placers/statement-mutant-placer.js.map +1 -0
  58. package/dist/src/mutant-placers/switch-case-mutant-placer.d.ts +14 -0
  59. package/dist/src/mutant-placers/switch-case-mutant-placer.d.ts.map +1 -0
  60. package/dist/src/mutant-placers/switch-case-mutant-placer.js +29 -0
  61. package/dist/src/mutant-placers/switch-case-mutant-placer.js.map +1 -0
  62. package/dist/src/mutant-placers/throw-placement-error.d.ts +5 -0
  63. package/dist/src/mutant-placers/throw-placement-error.d.ts.map +1 -0
  64. package/dist/src/mutant-placers/throw-placement-error.js +17 -0
  65. package/dist/src/mutant-placers/throw-placement-error.js.map +1 -0
  66. package/dist/src/mutant.d.ts +27 -0
  67. package/dist/src/mutant.d.ts.map +1 -0
  68. package/dist/src/mutant.js +80 -0
  69. package/dist/src/mutant.js.map +1 -0
  70. package/dist/src/mutators/arithmetic-operator-mutator.d.ts +3 -0
  71. package/dist/src/mutators/arithmetic-operator-mutator.d.ts.map +1 -0
  72. package/dist/src/mutators/arithmetic-operator-mutator.js +34 -0
  73. package/dist/src/mutators/arithmetic-operator-mutator.js.map +1 -0
  74. package/dist/src/mutators/array-declaration-mutator.d.ts +3 -0
  75. package/dist/src/mutators/array-declaration-mutator.d.ts.map +1 -0
  76. package/dist/src/mutators/array-declaration-mutator.js +26 -0
  77. package/dist/src/mutators/array-declaration-mutator.js.map +1 -0
  78. package/dist/src/mutators/arrow-function-mutator.d.ts +3 -0
  79. package/dist/src/mutators/arrow-function-mutator.d.ts.map +1 -0
  80. package/dist/src/mutators/arrow-function-mutator.js +14 -0
  81. package/dist/src/mutators/arrow-function-mutator.js.map +1 -0
  82. package/dist/src/mutators/assignment-operator-mutator.d.ts +3 -0
  83. package/dist/src/mutators/assignment-operator-mutator.d.ts.map +1 -0
  84. package/dist/src/mutators/assignment-operator-mutator.js +42 -0
  85. package/dist/src/mutators/assignment-operator-mutator.js.map +1 -0
  86. package/dist/src/mutators/block-statement-mutator.d.ts +3 -0
  87. package/dist/src/mutators/block-statement-mutator.d.ts.map +1 -0
  88. package/dist/src/mutators/block-statement-mutator.js +63 -0
  89. package/dist/src/mutators/block-statement-mutator.js.map +1 -0
  90. package/dist/src/mutators/boolean-literal-mutator.d.ts +3 -0
  91. package/dist/src/mutators/boolean-literal-mutator.d.ts.map +1 -0
  92. package/dist/src/mutators/boolean-literal-mutator.js +17 -0
  93. package/dist/src/mutators/boolean-literal-mutator.js.map +1 -0
  94. package/dist/src/mutators/conditional-expression-mutator.d.ts +3 -0
  95. package/dist/src/mutators/conditional-expression-mutator.d.ts.map +1 -0
  96. package/dist/src/mutators/conditional-expression-mutator.js +81 -0
  97. package/dist/src/mutators/conditional-expression-mutator.js.map +1 -0
  98. package/dist/src/mutators/equality-operator-mutator.d.ts +3 -0
  99. package/dist/src/mutators/equality-operator-mutator.d.ts.map +1 -0
  100. package/dist/src/mutators/equality-operator-mutator.js +28 -0
  101. package/dist/src/mutators/equality-operator-mutator.js.map +1 -0
  102. package/dist/src/mutators/index.d.ts +4 -0
  103. package/dist/src/mutators/index.d.ts.map +1 -0
  104. package/dist/src/mutators/index.js +4 -0
  105. package/dist/src/mutators/index.js.map +1 -0
  106. package/dist/src/mutators/logical-operator-mutator.d.ts +3 -0
  107. package/dist/src/mutators/logical-operator-mutator.d.ts.map +1 -0
  108. package/dist/src/mutators/logical-operator-mutator.js +21 -0
  109. package/dist/src/mutators/logical-operator-mutator.js.map +1 -0
  110. package/dist/src/mutators/method-expression-mutator.d.ts +3 -0
  111. package/dist/src/mutators/method-expression-mutator.d.ts.map +1 -0
  112. package/dist/src/mutators/method-expression-mutator.js +65 -0
  113. package/dist/src/mutators/method-expression-mutator.js.map +1 -0
  114. package/dist/src/mutators/mutate.d.ts +3 -0
  115. package/dist/src/mutators/mutate.d.ts.map +1 -0
  116. package/dist/src/mutators/mutate.js +35 -0
  117. package/dist/src/mutators/mutate.js.map +1 -0
  118. package/dist/src/mutators/mutator-options.d.ts +5 -0
  119. package/dist/src/mutators/mutator-options.d.ts.map +1 -0
  120. package/dist/src/mutators/mutator-options.js +2 -0
  121. package/dist/src/mutators/mutator-options.js.map +1 -0
  122. package/dist/src/mutators/node-mutator.d.ts +6 -0
  123. package/dist/src/mutators/node-mutator.d.ts.map +1 -0
  124. package/dist/src/mutators/node-mutator.js +2 -0
  125. package/dist/src/mutators/node-mutator.js.map +1 -0
  126. package/dist/src/mutators/object-literal-mutator.d.ts +3 -0
  127. package/dist/src/mutators/object-literal-mutator.d.ts.map +1 -0
  128. package/dist/src/mutators/object-literal-mutator.js +11 -0
  129. package/dist/src/mutators/object-literal-mutator.js.map +1 -0
  130. package/dist/src/mutators/optional-chaining-mutator.d.ts +15 -0
  131. package/dist/src/mutators/optional-chaining-mutator.d.ts.map +1 -0
  132. package/dist/src/mutators/optional-chaining-mutator.js +28 -0
  133. package/dist/src/mutators/optional-chaining-mutator.js.map +1 -0
  134. package/dist/src/mutators/regex-mutator.d.ts +3 -0
  135. package/dist/src/mutators/regex-mutator.d.ts.map +1 -0
  136. package/dist/src/mutators/regex-mutator.js +53 -0
  137. package/dist/src/mutators/regex-mutator.js.map +1 -0
  138. package/dist/src/mutators/string-literal-mutator.d.ts +3 -0
  139. package/dist/src/mutators/string-literal-mutator.d.ts.map +1 -0
  140. package/dist/src/mutators/string-literal-mutator.js +36 -0
  141. package/dist/src/mutators/string-literal-mutator.js.map +1 -0
  142. package/dist/src/mutators/unary-operator-mutator.d.ts +3 -0
  143. package/dist/src/mutators/unary-operator-mutator.d.ts.map +1 -0
  144. package/dist/src/mutators/unary-operator-mutator.js +27 -0
  145. package/dist/src/mutators/unary-operator-mutator.js.map +1 -0
  146. package/dist/src/mutators/update-operator-mutator.d.ts +3 -0
  147. package/dist/src/mutators/update-operator-mutator.d.ts.map +1 -0
  148. package/dist/src/mutators/update-operator-mutator.js +17 -0
  149. package/dist/src/mutators/update-operator-mutator.js.map +1 -0
  150. package/dist/src/parsers/create-parser.d.ts +5 -0
  151. package/dist/src/parsers/create-parser.d.ts.map +1 -0
  152. package/dist/src/parsers/create-parser.js +58 -0
  153. package/dist/src/parsers/create-parser.js.map +1 -0
  154. package/dist/src/parsers/html-parser.d.ts +4 -0
  155. package/dist/src/parsers/html-parser.d.ts.map +1 -0
  156. package/dist/src/parsers/html-parser.js +96 -0
  157. package/dist/src/parsers/html-parser.js.map +1 -0
  158. package/dist/src/parsers/index.d.ts +5 -0
  159. package/dist/src/parsers/index.d.ts.map +1 -0
  160. package/dist/src/parsers/index.js +3 -0
  161. package/dist/src/parsers/index.js.map +1 -0
  162. package/dist/src/parsers/js-parser.d.ts +4 -0
  163. package/dist/src/parsers/js-parser.d.ts.map +1 -0
  164. package/dist/src/parsers/js-parser.js +50 -0
  165. package/dist/src/parsers/js-parser.js.map +1 -0
  166. package/dist/src/parsers/parse-error.d.ts +5 -0
  167. package/dist/src/parsers/parse-error.d.ts.map +1 -0
  168. package/dist/src/parsers/parse-error.js +6 -0
  169. package/dist/src/parsers/parse-error.js.map +1 -0
  170. package/dist/src/parsers/parser-context.d.ts +6 -0
  171. package/dist/src/parsers/parser-context.d.ts.map +1 -0
  172. package/dist/src/parsers/parser-context.js +2 -0
  173. package/dist/src/parsers/parser-context.js.map +1 -0
  174. package/dist/src/parsers/parser-options.d.ts +4 -0
  175. package/dist/src/parsers/parser-options.d.ts.map +1 -0
  176. package/dist/src/parsers/parser-options.js +2 -0
  177. package/dist/src/parsers/parser-options.js.map +1 -0
  178. package/dist/src/parsers/svelte-parser.d.ts +4 -0
  179. package/dist/src/parsers/svelte-parser.d.ts.map +1 -0
  180. package/dist/src/parsers/svelte-parser.js +169 -0
  181. package/dist/src/parsers/svelte-parser.js.map +1 -0
  182. package/dist/src/parsers/ts-parser.d.ts +9 -0
  183. package/dist/src/parsers/ts-parser.d.ts.map +1 -0
  184. package/dist/src/parsers/ts-parser.js +54 -0
  185. package/dist/src/parsers/ts-parser.js.map +1 -0
  186. package/dist/src/printers/html-printer.d.ts +4 -0
  187. package/dist/src/printers/html-printer.d.ts.map +1 -0
  188. package/dist/src/printers/html-printer.js +15 -0
  189. package/dist/src/printers/html-printer.js.map +1 -0
  190. package/dist/src/printers/index.d.ts +7 -0
  191. package/dist/src/printers/index.d.ts.map +1 -0
  192. package/dist/src/printers/index.js +23 -0
  193. package/dist/src/printers/index.js.map +1 -0
  194. package/dist/src/printers/js-printer.d.ts +4 -0
  195. package/dist/src/printers/js-printer.d.ts.map +1 -0
  196. package/dist/src/printers/js-printer.js +6 -0
  197. package/dist/src/printers/js-printer.js.map +1 -0
  198. package/dist/src/printers/svelte-printer.d.ts +4 -0
  199. package/dist/src/printers/svelte-printer.d.ts.map +1 -0
  200. package/dist/src/printers/svelte-printer.js +28 -0
  201. package/dist/src/printers/svelte-printer.js.map +1 -0
  202. package/dist/src/printers/ts-printer.d.ts +4 -0
  203. package/dist/src/printers/ts-printer.d.ts.map +1 -0
  204. package/dist/src/printers/ts-printer.js +9 -0
  205. package/dist/src/printers/ts-printer.js.map +1 -0
  206. package/dist/src/syntax/index.d.ts +86 -0
  207. package/dist/src/syntax/index.d.ts.map +1 -0
  208. package/dist/src/syntax/index.js +9 -0
  209. package/dist/src/syntax/index.js.map +1 -0
  210. package/dist/src/transformers/babel-transformer.d.ts +4 -0
  211. package/dist/src/transformers/babel-transformer.d.ts.map +1 -0
  212. package/dist/src/transformers/babel-transformer.js +142 -0
  213. package/dist/src/transformers/babel-transformer.js.map +1 -0
  214. package/dist/src/transformers/directive-bookkeeper.d.ts +19 -0
  215. package/dist/src/transformers/directive-bookkeeper.d.ts.map +1 -0
  216. package/dist/src/transformers/directive-bookkeeper.js +108 -0
  217. package/dist/src/transformers/directive-bookkeeper.js.map +1 -0
  218. package/dist/src/transformers/html-transformer.d.ts +4 -0
  219. package/dist/src/transformers/html-transformer.d.ts.map +1 -0
  220. package/dist/src/transformers/html-transformer.js +6 -0
  221. package/dist/src/transformers/html-transformer.js.map +1 -0
  222. package/dist/src/transformers/ignorer-bookkeeper.d.ts +18 -0
  223. package/dist/src/transformers/ignorer-bookkeeper.d.ts.map +1 -0
  224. package/dist/src/transformers/ignorer-bookkeeper.js +29 -0
  225. package/dist/src/transformers/ignorer-bookkeeper.js.map +1 -0
  226. package/dist/src/transformers/index.d.ts +6 -0
  227. package/dist/src/transformers/index.d.ts.map +1 -0
  228. package/dist/src/transformers/index.js +4 -0
  229. package/dist/src/transformers/index.js.map +1 -0
  230. package/dist/src/transformers/mutant-collector.d.ts +19 -0
  231. package/dist/src/transformers/mutant-collector.d.ts.map +1 -0
  232. package/dist/src/transformers/mutant-collector.js +25 -0
  233. package/dist/src/transformers/mutant-collector.js.map +1 -0
  234. package/dist/src/transformers/svelte-transformer.d.ts +4 -0
  235. package/dist/src/transformers/svelte-transformer.d.ts.map +1 -0
  236. package/dist/src/transformers/svelte-transformer.js +46 -0
  237. package/dist/src/transformers/svelte-transformer.js.map +1 -0
  238. package/dist/src/transformers/transformer-options.d.ts +6 -0
  239. package/dist/src/transformers/transformer-options.d.ts.map +1 -0
  240. package/dist/src/transformers/transformer-options.js +2 -0
  241. package/dist/src/transformers/transformer-options.js.map +1 -0
  242. package/dist/src/transformers/transformer.d.ts +22 -0
  243. package/dist/src/transformers/transformer.d.ts.map +1 -0
  244. package/dist/src/transformers/transformer.js +30 -0
  245. package/dist/src/transformers/transformer.js.map +1 -0
  246. package/dist/src/util/binary-operator.d.ts +2 -0
  247. package/dist/src/util/binary-operator.d.ts.map +1 -0
  248. package/dist/src/util/binary-operator.js +2 -0
  249. package/dist/src/util/binary-operator.js.map +1 -0
  250. package/dist/src/util/index.d.ts +4 -0
  251. package/dist/src/util/index.d.ts.map +1 -0
  252. package/dist/src/util/index.js +4 -0
  253. package/dist/src/util/index.js.map +1 -0
  254. package/dist/src/util/position-converter.d.ts +16 -0
  255. package/dist/src/util/position-converter.d.ts.map +1 -0
  256. package/dist/src/util/position-converter.js +126 -0
  257. package/dist/src/util/position-converter.js.map +1 -0
  258. package/dist/src/util/syntax-helpers.d.ts +60 -0
  259. package/dist/src/util/syntax-helpers.d.ts.map +1 -0
  260. package/dist/src/util/syntax-helpers.js +217 -0
  261. package/dist/src/util/syntax-helpers.js.map +1 -0
  262. package/package.json +64 -0
  263. package/src/create-instrumenter.ts +30 -0
  264. package/src/disable-type-checks.ts +153 -0
  265. package/src/file.ts +6 -0
  266. package/src/frameworks/angular-ignorer.ts +129 -0
  267. package/src/frameworks/index.ts +9 -0
  268. package/src/index.ts +8 -0
  269. package/src/instrument-result.ts +8 -0
  270. package/src/instrumenter-options.ts +5 -0
  271. package/src/instrumenter-tokens.ts +5 -0
  272. package/src/instrumenter.ts +100 -0
  273. package/src/mutant-placers/expression-mutant-placer.ts +210 -0
  274. package/src/mutant-placers/index.ts +12 -0
  275. package/src/mutant-placers/mutant-placer.ts +9 -0
  276. package/src/mutant-placers/statement-mutant-placer.ts +39 -0
  277. package/src/mutant-placers/switch-case-mutant-placer.ts +41 -0
  278. package/src/mutant-placers/throw-placement-error.ts +34 -0
  279. package/src/mutant.ts +101 -0
  280. package/src/mutators/arithmetic-operator-mutator.ts +51 -0
  281. package/src/mutators/array-declaration-mutator.ts +36 -0
  282. package/src/mutators/arrow-function-mutator.ts +22 -0
  283. package/src/mutators/assignment-operator-mutator.ts +59 -0
  284. package/src/mutators/block-statement-mutator.ts +89 -0
  285. package/src/mutators/boolean-literal-mutator.ts +24 -0
  286. package/src/mutators/conditional-expression-mutator.ts +92 -0
  287. package/src/mutators/equality-operator-mutator.ts +35 -0
  288. package/src/mutators/index.ts +3 -0
  289. package/src/mutators/logical-operator-mutator.ts +29 -0
  290. package/src/mutators/method-expression-mutator.ts +99 -0
  291. package/src/mutators/mutate.ts +36 -0
  292. package/src/mutators/mutator-options.ts +4 -0
  293. package/src/mutators/node-mutator.ts +6 -0
  294. package/src/mutators/object-literal-mutator.ts +15 -0
  295. package/src/mutators/optional-chaining-mutator.ts +39 -0
  296. package/src/mutators/regex-mutator.ts +69 -0
  297. package/src/mutators/string-literal-mutator.ts +49 -0
  298. package/src/mutators/unary-operator-mutator.ts +39 -0
  299. package/src/mutators/update-operator-mutator.ts +26 -0
  300. package/src/parsers/create-parser.ts +78 -0
  301. package/src/parsers/html-parser.ts +138 -0
  302. package/src/parsers/index.ts +5 -0
  303. package/src/parsers/js-parser.ts +58 -0
  304. package/src/parsers/parse-error.ts +9 -0
  305. package/src/parsers/parser-context.ts +15 -0
  306. package/src/parsers/parser-options.ts +3 -0
  307. package/src/parsers/svelte-parser.ts +255 -0
  308. package/src/parsers/ts-parser.ts +69 -0
  309. package/src/printers/html-printer.ts +20 -0
  310. package/src/printers/index.ts +33 -0
  311. package/src/printers/js-printer.ts +11 -0
  312. package/src/printers/svelte-printer.ts +34 -0
  313. package/src/printers/ts-printer.ts +14 -0
  314. package/src/syntax/index.ts +97 -0
  315. package/src/transformers/babel-transformer.ts +217 -0
  316. package/src/transformers/directive-bookkeeper.ts +173 -0
  317. package/src/transformers/html-transformer.ts +13 -0
  318. package/src/transformers/ignorer-bookkeeper.ts +41 -0
  319. package/src/transformers/index.ts +6 -0
  320. package/src/transformers/mutant-collector.ts +44 -0
  321. package/src/transformers/svelte-transformer.ts +57 -0
  322. package/src/transformers/transformer-options.ts +7 -0
  323. package/src/transformers/transformer.ts +54 -0
  324. package/src/util/binary-operator.ts +23 -0
  325. package/src/util/index.ts +3 -0
  326. package/src/util/position-converter.ts +145 -0
  327. package/src/util/syntax-helpers.ts +301 -0
@@ -0,0 +1,145 @@
1
+ import { Position } from '@stryker-mutator/api/core';
2
+
3
+ /**
4
+ * A class that can convert a string offset back to line / column.
5
+ * Grabbed from TypeScript code base
6
+ * @see https://github.com/microsoft/TypeScript/blob/aa9b6953441b53f8b14072c047f0519b611150c4/src/compiler/scanner.ts#L503
7
+ */
8
+ export class PositionConverter {
9
+ private _lineStarts?: readonly number[];
10
+ private get lineStarts() {
11
+ if (!this._lineStarts) {
12
+ this._lineStarts = this.computeLineStarts(this.text);
13
+ }
14
+ return this._lineStarts;
15
+ }
16
+ constructor(private readonly text: string) {}
17
+
18
+ public positionFromOffset(offset: number): Position {
19
+ const lineNumber = this.computeLineOfPosition(offset);
20
+ return {
21
+ line: lineNumber,
22
+ column: offset - this.lineStarts[lineNumber],
23
+ };
24
+ }
25
+
26
+ private computeLineOfPosition(offset: number) {
27
+ let lineNumber = binarySearch(this.lineStarts, offset);
28
+ if (lineNumber < 0) {
29
+ // If the actual position was not found,
30
+ // the binary search returns the 2's-complement of the next line start
31
+ // e.g. if the line starts at [5, 10, 23, 80] and the position requested was 20
32
+ // then the search will return -2.
33
+ //
34
+ // We want the index of the previous line start, so we subtract 1.
35
+ // Review 2's-complement if this is confusing.
36
+ lineNumber = ~lineNumber - 1;
37
+ if (lineNumber === -1) {
38
+ throw new Error('position cannot precede the beginning of the file');
39
+ }
40
+ }
41
+ return lineNumber;
42
+ }
43
+
44
+ private computeLineStarts(text: string): number[] {
45
+ const result: number[] = [];
46
+ let pos = 0;
47
+ let lineStart = 0;
48
+ while (pos < text.length) {
49
+ const ch = text.charCodeAt(pos);
50
+ pos++;
51
+ switch (ch) {
52
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
53
+ case CharacterCodes.carriageReturn: {
54
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
55
+ if (text.charCodeAt(pos) === CharacterCodes.lineFeed) {
56
+ pos++;
57
+ }
58
+ // falls through
59
+ }
60
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
61
+ case CharacterCodes.lineFeed:
62
+ result.push(lineStart);
63
+ lineStart = pos;
64
+ break;
65
+ default:
66
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
67
+ if (ch > CharacterCodes.maxAsciiCharacter && isLineBreak(ch)) {
68
+ result.push(lineStart);
69
+ lineStart = pos;
70
+ }
71
+ break;
72
+ }
73
+ }
74
+ result.push(lineStart);
75
+ return result;
76
+ }
77
+ }
78
+
79
+ function binarySearch(array: readonly number[], value: number): number {
80
+ if (!array.length) {
81
+ return -1;
82
+ }
83
+
84
+ let low = 0;
85
+ let high = array.length - 1;
86
+ while (low <= high) {
87
+ const middle = low + ((high - low) >> 1);
88
+ const midKey = compare(array[middle], value);
89
+ switch (midKey) {
90
+ case Comparison.LessThan:
91
+ low = middle + 1;
92
+ break;
93
+ case Comparison.EqualTo:
94
+ return middle;
95
+ case Comparison.GreaterThan:
96
+ high = middle - 1;
97
+ break;
98
+ }
99
+ }
100
+
101
+ return ~low;
102
+ }
103
+ const enum Comparison {
104
+ LessThan = -1,
105
+ EqualTo = 0,
106
+ GreaterThan = 1,
107
+ }
108
+ function compare(a: number, b: number) {
109
+ return a < b
110
+ ? Comparison.LessThan
111
+ : a > b
112
+ ? Comparison.GreaterThan
113
+ : Comparison.EqualTo;
114
+ }
115
+ const enum CharacterCodes {
116
+ lineFeed = 0x0a, // \n
117
+ carriageReturn = 0x0d, // \r
118
+ maxAsciiCharacter = 0x7f,
119
+ lineSeparator = 0x2028,
120
+ paragraphSeparator = 0x2029,
121
+ }
122
+
123
+ function isLineBreak(ch: number): boolean {
124
+ // ES5 7.3:
125
+ // The ECMAScript line terminator characters are listed in Table 3.
126
+ // Table 3: Line Terminator Characters
127
+ // Code Unit Value Name Formal Name
128
+ // \u000A Line Feed <LF>
129
+ // \u000D Carriage Return <CR>
130
+ // \u2028 Line separator <LS>
131
+ // \u2029 Paragraph separator <PS>
132
+ // Only the characters in Table 3 are treated as line terminators. Other new line or line
133
+ // breaking characters are treated as white space but not as line terminators.
134
+
135
+ return (
136
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
137
+ ch === CharacterCodes.lineFeed ||
138
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
139
+ ch === CharacterCodes.carriageReturn ||
140
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
141
+ ch === CharacterCodes.lineSeparator ||
142
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
143
+ ch === CharacterCodes.paragraphSeparator
144
+ );
145
+ }
@@ -0,0 +1,301 @@
1
+ import { INSTRUMENTER_CONSTANTS as ID } from '@stryker-mutator/api/core';
2
+ import babel from '@babel/core';
3
+ import { deepFreeze, I } from '@stryker-mutator/util';
4
+
5
+ import { Mutant } from '../mutant.js';
6
+
7
+ import { MutantCollector } from '../transformers/index.js';
8
+ import { MutatorOptions } from '../mutators/index.js';
9
+
10
+ export { ID };
11
+
12
+ const STRYKER_NAMESPACE_HELPER = 'stryNS_9fa48';
13
+ const COVER_MUTANT_HELPER = 'stryCov_9fa48';
14
+ const IS_MUTANT_ACTIVE_HELPER = 'stryMutAct_9fa48';
15
+
16
+ const { types, traverse } = babel;
17
+
18
+ /**
19
+ * Returns syntax for the header if JS/TS files
20
+ */
21
+ export const instrumentationBabelHeader = deepFreeze(
22
+ // `globalThis` implementation is based on core-js's implementation. See https://github.com/stryker-mutator/stryker-js/issues/4035
23
+ babel.parse(
24
+ `function ${STRYKER_NAMESPACE_HELPER}(){
25
+ var g = typeof globalThis === 'object' && globalThis && globalThis.Math === Math && globalThis || new Function("return this")();
26
+ var ns = g.${ID.NAMESPACE} || (g.${ID.NAMESPACE} = {});
27
+ if (ns.${ID.ACTIVE_MUTANT} === undefined && g.process && g.process.env && g.process.env.${ID.ACTIVE_MUTANT_ENV_VARIABLE}) {
28
+ ns.${ID.ACTIVE_MUTANT} = g.process.env.${ID.ACTIVE_MUTANT_ENV_VARIABLE};
29
+ }
30
+ function retrieveNS(){
31
+ return ns;
32
+ }
33
+ ${STRYKER_NAMESPACE_HELPER} = retrieveNS;
34
+ return retrieveNS();
35
+ }
36
+ ${STRYKER_NAMESPACE_HELPER}();
37
+
38
+ function ${COVER_MUTANT_HELPER}() {
39
+ var ns = ${STRYKER_NAMESPACE_HELPER}();
40
+ var cov = ns.${ID.MUTATION_COVERAGE_OBJECT} || (ns.${ID.MUTATION_COVERAGE_OBJECT} = { static: {}, perTest: {} });
41
+ function cover() {
42
+ var c = cov.static;
43
+ if (ns.${ID.CURRENT_TEST_ID}) {
44
+ c = cov.perTest[ns.${ID.CURRENT_TEST_ID}] = cov.perTest[ns.${ID.CURRENT_TEST_ID}] || {};
45
+ }
46
+ var a = arguments;
47
+ for(var i=0; i < a.length; i++){
48
+ c[a[i]] = (c[a[i]] || 0) + 1;
49
+ }
50
+ }
51
+ ${COVER_MUTANT_HELPER} = cover;
52
+ cover.apply(null, arguments);
53
+ }
54
+ function ${IS_MUTANT_ACTIVE_HELPER}(id) {
55
+ var ns = ${STRYKER_NAMESPACE_HELPER}();
56
+ function isActive(id) {
57
+ if (ns.${ID.ACTIVE_MUTANT} === id) {
58
+ if (ns.${ID.HIT_COUNT} !== void 0 && ++ns.${ID.HIT_COUNT} > ns.${ID.HIT_LIMIT}) {
59
+ throw new Error('Stryker: Hit count limit reached (' + ns.${ID.HIT_COUNT} + ')');
60
+ }
61
+ return true;
62
+ }
63
+ return false;
64
+ }
65
+ ${IS_MUTANT_ACTIVE_HELPER} = isActive;
66
+ return isActive(id);
67
+ }`,
68
+ { configFile: false, browserslistConfigFile: false, env: { targets: {} } },
69
+ ) as babel.types.File,
70
+ ).program.body as readonly babel.types.Statement[]; // cast here, otherwise the thing gets unwieldy to handle
71
+
72
+ /**
73
+ * returns syntax for `global.activeMutant === $mutantId`
74
+ * @param mutantId The id of the mutant to switch
75
+ */
76
+ export function mutantTestExpression(
77
+ mutantId: string,
78
+ ): babel.types.CallExpression {
79
+ return types.callExpression(types.identifier(IS_MUTANT_ACTIVE_HELPER), [
80
+ types.stringLiteral(mutantId),
81
+ ]);
82
+ }
83
+
84
+ interface Position {
85
+ line: number;
86
+ column: number;
87
+ }
88
+
89
+ function eqLocation(
90
+ a: babel.types.SourceLocation,
91
+ b: babel.types.SourceLocation,
92
+ ): boolean {
93
+ function eqPosition(start: Position, end: Position): boolean {
94
+ return start.column === end.column && start.line === end.line;
95
+ }
96
+ return eqPosition(a.start, b.start) && eqPosition(a.end, b.end);
97
+ }
98
+
99
+ export function eqNode<T extends babel.types.Node>(
100
+ a: T,
101
+ b: babel.types.Node,
102
+ ): b is T {
103
+ return a.type === b.type && !!a.loc && !!b.loc && eqLocation(a.loc, b.loc);
104
+ }
105
+
106
+ export function offsetLocations(
107
+ file: babel.types.File,
108
+ {
109
+ position,
110
+ line,
111
+ column,
112
+ }: { position: number; line: number; column: number },
113
+ ): void {
114
+ const offsetNode = (node: babel.types.Node): void => {
115
+ node.start! += position;
116
+ node.end! += position;
117
+ // we need to subtract 1, as lines always start at 1
118
+ node.loc!.start.line += line - 1;
119
+ node.loc!.end.line += line - 1;
120
+ if (node.loc!.start.line === line) {
121
+ node.loc!.start.column += column;
122
+ }
123
+ if (node.loc!.end.line === line) {
124
+ node.loc!.end.column += column;
125
+ }
126
+ };
127
+ traverse(file, {
128
+ enter(path) {
129
+ offsetNode(path.node);
130
+ },
131
+ });
132
+ // Don't forget the file itself!
133
+ file.start! += position;
134
+ file.end! += position;
135
+ }
136
+
137
+ /**
138
+ * Returns a sequence of mutation coverage counters with an optional last expression.
139
+ *
140
+ * @example (global.__coverMutant__(0, 1), 40 + 2)
141
+ * @param mutants The mutants for which covering syntax needs to be generated
142
+ * @param targetExpression The original expression
143
+ */
144
+ export function mutationCoverageSequenceExpression(
145
+ mutants: Iterable<Mutant>,
146
+ targetExpression?: babel.types.Expression,
147
+ ): babel.types.Expression {
148
+ const mutantIds = [...mutants].map((mutant) =>
149
+ types.stringLiteral(mutant.id),
150
+ );
151
+ const sequence: babel.types.Expression[] = [
152
+ types.callExpression(types.identifier(COVER_MUTANT_HELPER), mutantIds),
153
+ ];
154
+ if (targetExpression) {
155
+ sequence.push(targetExpression);
156
+ }
157
+ return types.sequenceExpression(sequence);
158
+ }
159
+
160
+ export function isTypeNode(path: babel.NodePath): boolean {
161
+ return (
162
+ path.isTypeAnnotation() ||
163
+ flowTypeAnnotationNodeTypes.includes(path.node.type) ||
164
+ tsTypeAnnotationNodeTypes.includes(path.node.type) ||
165
+ isDeclareVariableStatement(path) ||
166
+ isDeclareModule(path)
167
+ );
168
+ }
169
+
170
+ /**
171
+ * Determines whether or not it is a declare variable statement node.
172
+ * @example
173
+ * declare const foo: 'foo';
174
+ */
175
+ function isDeclareVariableStatement(path: babel.NodePath): boolean {
176
+ return path.isVariableDeclaration() && path.node.declare === true;
177
+ }
178
+
179
+ /**
180
+ * Determines whether or not a node is a string literal that is the name of a module.
181
+ * @example
182
+ * declare module "express" {};
183
+ */
184
+ function isDeclareModule(path: babel.NodePath): boolean {
185
+ return path.isTSModuleDeclaration() && (path.node.declare ?? false);
186
+ }
187
+
188
+ const tsTypeAnnotationNodeTypes: ReadonlyArray<babel.types.Node['type']> =
189
+ Object.freeze([
190
+ 'TSAsExpression',
191
+ 'TSInterfaceDeclaration',
192
+ 'TSTypeAnnotation',
193
+ 'TSTypeAliasDeclaration',
194
+ 'TSEnumDeclaration',
195
+ 'TSDeclareFunction',
196
+ 'TSTypeParameterInstantiation',
197
+ 'TSTypeParameterDeclaration',
198
+ ]);
199
+
200
+ const flowTypeAnnotationNodeTypes: ReadonlyArray<babel.types.Node['type']> =
201
+ Object.freeze([
202
+ 'DeclareClass',
203
+ 'DeclareFunction',
204
+ 'DeclareInterface',
205
+ 'DeclareModule',
206
+ 'DeclareModuleExports',
207
+ 'DeclareTypeAlias',
208
+ 'DeclareOpaqueType',
209
+ 'DeclareVariable',
210
+ 'DeclareExportDeclaration',
211
+ 'DeclareExportAllDeclaration',
212
+ 'InterfaceDeclaration',
213
+ 'OpaqueType',
214
+ 'TypeAlias',
215
+ 'InterfaceDeclaration',
216
+ ]);
217
+
218
+ export function isImportDeclaration(path: babel.NodePath): boolean {
219
+ return (
220
+ types.isTSImportEqualsDeclaration(path.node) || path.isImportDeclaration()
221
+ );
222
+ }
223
+
224
+ /**
225
+ * A location of an ast node in a file
226
+ */
227
+ export interface SourceLocationInFile {
228
+ end: Position;
229
+ start: Position;
230
+ }
231
+
232
+ /**
233
+ * Determines if a location (needle) is included in an other location (haystack)
234
+ * @param haystack The range to look in
235
+ * @param needle the range to search for
236
+ */
237
+ export function locationIncluded(
238
+ haystack: SourceLocationInFile,
239
+ needle: SourceLocationInFile,
240
+ ): boolean {
241
+ const startIncluded =
242
+ haystack.start.line < needle.start.line ||
243
+ (haystack.start.line === needle.start.line &&
244
+ haystack.start.column <= needle.start.column);
245
+ const endIncluded =
246
+ haystack.end.line > needle.end.line ||
247
+ (haystack.end.line === needle.end.line &&
248
+ haystack.end.column >= needle.end.column);
249
+ return startIncluded && endIncluded;
250
+ }
251
+
252
+ /**
253
+ * Determines if two locations overlap with each other
254
+ */
255
+ export function locationOverlaps(
256
+ a: SourceLocationInFile,
257
+ b: SourceLocationInFile,
258
+ ): boolean {
259
+ const startIncluded =
260
+ a.start.line < b.end.line ||
261
+ (a.start.line === b.end.line && a.start.column <= b.end.column);
262
+ const endIncluded =
263
+ a.end.line > b.start.line ||
264
+ (a.end.line === b.start.line && a.end.column >= b.start.column);
265
+ return startIncluded && endIncluded;
266
+ }
267
+
268
+ /**
269
+ * Helper for `types.cloneNode(node, deep: true, withoutLocations: false);`
270
+ */
271
+ export function deepCloneNode<TNode extends babel.types.Node>(
272
+ node: TNode,
273
+ ): TNode {
274
+ return types.cloneNode(node, /* deep */ true, /* withoutLocations */ false);
275
+ }
276
+
277
+ export function placeHeaderIfNeeded(
278
+ mutantCollector: I<MutantCollector>,
279
+ originFileName: string,
280
+ options: MutatorOptions,
281
+ root: babel.types.File,
282
+ ): void {
283
+ if (mutantCollector.hasPlacedMutants(originFileName) && !options.noHeader) {
284
+ // Be sure to leave comments like `// @flow` in.
285
+ placeHeader(root);
286
+ }
287
+ }
288
+
289
+ export function placeHeader(root: babel.types.File): void {
290
+ let header = instrumentationBabelHeader;
291
+ if (Array.isArray(root.program.body[0]?.leadingComments)) {
292
+ header = [
293
+ {
294
+ ...instrumentationBabelHeader[0],
295
+ leadingComments: root.program.body[0]?.leadingComments,
296
+ },
297
+ ...instrumentationBabelHeader.slice(1),
298
+ ];
299
+ }
300
+ root.program.body.unshift(...header);
301
+ }