ReviewOS

also looking at this

stacks/dtsx

fix(scanner): leave line comments out when collapsing multi-line generics

#3119
Open mkantautas wants to merge fix/generics-line-comment into main
2 files +67 -9
packages/dtsx/test/generic-parameter-comments.test.tsadded+45-0
Changes to packages/dtsx/test/generic-parameter-comments.test.ts
@@ -0,0 +1,45 @@
1/**
2 * A `//` comment inside a multi-line type parameter list commented out the rest
3 * of the declaration. Multi-line `<...>` is collapsed onto one line, so
4 *
5 * export function defineComponent<
6 * // props
7 * TypeProps,
8 * ...
9 * >(options: ...): ...
10 *
11 * came out as `defineComponent<// props TypeProps, ...` and everything after
12 * the comment, closing `>` included, was gone. Vue's `defineComponent`,
13 * vue-router's `RouteRecordInfo` and Pinia's store types are all written this
14 * way; their `.d.ts` did not parse.
15 */
16import { describe, expect, it } from 'bun:test'
17import { processCode } from './test-utils'
18
19const transpiler = new Bun.Transpiler({ loader: 'ts', target: 'bun' })
20
21describe('comments in a multi-line type parameter list', () => {
22 it.each([
23 ['function', 'export function f<\n // first\n A,\n B = string, // second\n>(a: A, b: B): void {}\n', 'f<A, B = string,>(a: A, b: B): void;'],
24 ['type alias', 'export type T<\n // note\n A = 1,\n> = A\n', 'type T<A = 1,> = A'],
25 ['interface', 'export interface I<\n // note\n A extends string = string,\n> { a: A }\n', 'interface I<A extends string = string,>'],
26 ['class', 'export class C<\n // note\n T,\n> { v!: T }\n', 'class C<T,>'],
27 ])('leaves the comment out: %s', (_label, code, expected) => {
28 const output = processCode(code)
29 expect(() => transpiler.transformSync(output)).not.toThrow()
30 expect(output).toContain(expected)
31 expect(output).not.toContain('//')
32 })
33
34 it('copies strings and block comments as they are', () => {
35 const output = processCode('export type S<\n /* see http://example.com */ A extends \'//\' | \'a b\' = \'//\',\n> = A\n')
36 expect(() => transpiler.transformSync(output)).not.toThrow()
37 expect(output).toContain('/* see http://example.com */ A extends \'//\' | \'a b\' = \'//\'')
38 })
39
40 it('keeps a multi-line template literal type as written', () => {
41 const output = processCode('export type F<\n // note\n T = `a\nb`,\n> = T\n')
42 expect(() => transpiler.transformSync(output)).not.toThrow()
43 expect(output).toContain('T = `a\nb`')
44 })
45})