Skip to content

Commit 35e1a3b

Browse files
committed
fix: allow declaration merging
fixes sveltejs/svelte#11416 Also cleans up test suite error checks
1 parent 0c11e2b commit 35e1a3b

File tree

13 files changed

+281
-103
lines changed

13 files changed

+281
-103
lines changed

.changeset/proud-parks-swim.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/acorn-typescript': patch
3+
---
4+
5+
fix: allow declaration merging

__test__/__snapshot__/identifier/normal.ts

+205-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const NormalIdentifierSnapshot = {
2-
Issue50: {
2+
TypeNameSame1: {
33
type: 'Program',
44
start: 0,
55
end: 25,
@@ -146,6 +146,210 @@ const NormalIdentifierSnapshot = {
146146
],
147147
sourceType: 'module'
148148
},
149+
TypeNameSame2: {
150+
type: 'Program',
151+
start: 0,
152+
end: 25,
153+
loc: { start: { line: 1, column: 0, index: 0 }, end: { line: 2, column: 8, index: 25 } },
154+
body: [
155+
{
156+
type: 'TSTypeAliasDeclaration',
157+
start: 0,
158+
end: 16,
159+
loc: { start: { line: 1, column: 0, index: 0 }, end: { line: 1, column: 16, index: 16 } },
160+
id: {
161+
type: 'Identifier',
162+
start: 5,
163+
end: 8,
164+
loc: { start: { line: 1, column: 5, index: 5 }, end: { line: 1, column: 8, index: 8 } },
165+
name: 'abc'
166+
},
167+
typeAnnotation: {
168+
type: 'TSLiteralType',
169+
start: 11,
170+
end: 15,
171+
loc: {
172+
start: { line: 1, column: 11, index: 11 },
173+
end: { line: 1, column: 15, index: 15 }
174+
},
175+
literal: {
176+
type: 'Literal',
177+
start: 11,
178+
end: 15,
179+
loc: {
180+
start: { line: 1, column: 11, index: 11 },
181+
end: { line: 1, column: 15, index: 15 }
182+
},
183+
value: 1234,
184+
raw: '1234'
185+
}
186+
}
187+
},
188+
{
189+
type: 'VariableDeclaration',
190+
start: 17,
191+
end: 25,
192+
loc: { start: { line: 2, column: 0, index: 17 }, end: { line: 2, column: 8, index: 25 } },
193+
declarations: [
194+
{
195+
type: 'VariableDeclarator',
196+
start: 21,
197+
end: 24,
198+
loc: {
199+
start: { line: 2, column: 4, index: 21 },
200+
end: { line: 2, column: 7, index: 24 }
201+
},
202+
id: {
203+
type: 'Identifier',
204+
start: 21,
205+
end: 24,
206+
loc: {
207+
start: { line: 2, column: 4, index: 21 },
208+
end: { line: 2, column: 7, index: 24 }
209+
},
210+
name: 'abc'
211+
},
212+
init: null
213+
}
214+
],
215+
kind: 'let'
216+
}
217+
],
218+
sourceType: 'module'
219+
},
220+
TypeNameSame3: {
221+
type: 'Program',
222+
start: 0,
223+
end: 34,
224+
loc: { start: { line: 1, column: 0, index: 0 }, end: { line: 2, column: 17, index: 34 } },
225+
body: [
226+
{
227+
type: 'TSTypeAliasDeclaration',
228+
start: 0,
229+
end: 16,
230+
loc: { start: { line: 1, column: 0, index: 0 }, end: { line: 1, column: 16, index: 16 } },
231+
id: {
232+
type: 'Identifier',
233+
start: 5,
234+
end: 8,
235+
loc: { start: { line: 1, column: 5, index: 5 }, end: { line: 1, column: 8, index: 8 } },
236+
name: 'abc'
237+
},
238+
typeAnnotation: {
239+
type: 'TSLiteralType',
240+
start: 11,
241+
end: 15,
242+
loc: {
243+
start: { line: 1, column: 11, index: 11 },
244+
end: { line: 1, column: 15, index: 15 }
245+
},
246+
literal: {
247+
type: 'Literal',
248+
start: 11,
249+
end: 15,
250+
loc: {
251+
start: { line: 1, column: 11, index: 11 },
252+
end: { line: 1, column: 15, index: 15 }
253+
},
254+
value: 1234,
255+
raw: '1234'
256+
}
257+
}
258+
},
259+
{
260+
type: 'FunctionDeclaration',
261+
start: 17,
262+
end: 34,
263+
loc: { start: { line: 2, column: 0, index: 17 }, end: { line: 2, column: 17, index: 34 } },
264+
id: {
265+
type: 'Identifier',
266+
start: 26,
267+
end: 29,
268+
loc: {
269+
start: { line: 2, column: 9, index: 26 },
270+
end: { line: 2, column: 12, index: 29 }
271+
},
272+
name: 'abc'
273+
},
274+
expression: false,
275+
generator: false,
276+
async: false,
277+
params: [],
278+
body: {
279+
type: 'BlockStatement',
280+
start: 32,
281+
end: 34,
282+
loc: {
283+
start: { line: 2, column: 15, index: 32 },
284+
end: { line: 2, column: 17, index: 34 }
285+
},
286+
body: []
287+
}
288+
}
289+
],
290+
sourceType: 'module'
291+
},
292+
InterfaceMerging: {
293+
type: 'Program',
294+
start: 0,
295+
end: 33,
296+
loc: { start: { line: 1, column: 0, index: 0 }, end: { line: 2, column: 16, index: 33 } },
297+
body: [
298+
{
299+
type: 'TSInterfaceDeclaration',
300+
start: 0,
301+
end: 16,
302+
loc: { start: { line: 1, column: 0, index: 0 }, end: { line: 1, column: 16, index: 16 } },
303+
id: {
304+
type: 'Identifier',
305+
start: 10,
306+
end: 13,
307+
loc: {
308+
start: { line: 1, column: 10, index: 10 },
309+
end: { line: 1, column: 13, index: 13 }
310+
},
311+
name: 'abc'
312+
},
313+
body: {
314+
type: 'TSInterfaceBody',
315+
start: 14,
316+
end: 16,
317+
loc: {
318+
start: { line: 1, column: 14, index: 14 },
319+
end: { line: 1, column: 16, index: 16 }
320+
},
321+
body: []
322+
}
323+
},
324+
{
325+
type: 'TSInterfaceDeclaration',
326+
start: 17,
327+
end: 33,
328+
loc: { start: { line: 2, column: 0, index: 17 }, end: { line: 2, column: 16, index: 33 } },
329+
id: {
330+
type: 'Identifier',
331+
start: 27,
332+
end: 30,
333+
loc: {
334+
start: { line: 2, column: 10, index: 27 },
335+
end: { line: 2, column: 13, index: 30 }
336+
},
337+
name: 'abc'
338+
},
339+
body: {
340+
type: 'TSInterfaceBody',
341+
start: 31,
342+
end: 33,
343+
loc: {
344+
start: { line: 2, column: 14, index: 31 },
345+
end: { line: 2, column: 16, index: 33 }
346+
},
347+
body: []
348+
}
349+
}
350+
],
351+
sourceType: 'module'
352+
},
149353
ExportIdentifierAs: {
150354
type: 'Program',
151355
start: 0,

__test__/assert/index.test.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, it, expect } from 'vitest';
1+
import { describe, it } from 'vitest';
22
import { equalNode, parseSource, parseSourceShouldThrowError } from '../utils';
33
import AssertionSnapshot from '../__snapshot__/assert';
44

@@ -16,13 +16,10 @@ describe('assert', () => {
1616
});
1717

1818
it('import with duplicate', () => {
19-
const res = parseSourceShouldThrowError(
19+
parseSourceShouldThrowError(
2020
`import json from './foo.json' with { type: 'json', type: 'json' };`,
21-
'Duplicated key in attributes',
22-
'(1:63)'
21+
'Duplicated key in attributes (1:63)'
2322
);
24-
25-
expect(res).toBe(true);
2623
});
2724

2825
it('dynamic import assert', () => {

__test__/class/type.test.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -402,15 +402,12 @@ describe('class', () => {
402402
});
403403

404404
it('class abstract method with body', function () {
405-
const res = parseSourceShouldThrowError(
405+
parseSourceShouldThrowError(
406406
generateSource([`abstract class Person {`, ` abstract find(string): Person {}`, `}`]),
407407
TypeScriptError.AbstractMethodHasImplementation({
408408
methodName: 'find'
409-
}),
410-
'(2:2)'
409+
}) + ' (2:2)'
411410
);
412-
413-
expect(res).toBe(true);
414411
});
415412

416413
it('definite property', () => {

__test__/export/type.test.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, it, expect } from 'vitest';
1+
import { describe, it } from 'vitest';
22
import {
33
equalNode,
44
generateSource,
@@ -97,12 +97,9 @@ describe('export type', () => {
9797
});
9898

9999
it('export outer type type with name', () => {
100-
const res = parseSourceShouldThrowError(
100+
parseSourceShouldThrowError(
101101
generateSource([`const A = 'test'`, `export type {`, ` type A`, `}`]),
102-
TypeScriptError.TypeModifierIsUsedInTypeExports,
103-
'(3:2)'
102+
TypeScriptError.TypeModifierIsUsedInTypeExports + ' (3:2)'
104103
);
105-
106-
expect(res).toBe(true);
107104
});
108105
});

__test__/expression/variables.test.ts

+3-12
Original file line numberDiff line numberDiff line change
@@ -173,23 +173,14 @@ describe('variables declaration', () => {
173173
});
174174

175175
it('parse generics with comma', () => {
176-
const res = parseSourceShouldThrowError(
177-
generateSource([`const a: Foo<T, > = 1`]),
178-
TypeScriptError.GenericsEndWithComma,
179-
'(1:16)'
180-
);
181-
182-
expect(res).toBe(false);
176+
parseSource(generateSource([`const a: Foo<T, > = 1`]));
183177
});
184178

185179
it('parse condition express error', () => {
186-
const res = parseSourceShouldThrowError(
180+
parseSourceShouldThrowError(
187181
generateSource([`const a = true ? : 1`]),
188-
'Unexpected token',
189-
'(1:17)'
182+
'Unexpected token (1:17)'
190183
);
191-
192-
expect(res).toBe(true);
193184
});
194185

195186
it('issue 43', () => {

__test__/for/index.test.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, it, expect } from 'vitest';
1+
import { describe, it } from 'vitest';
22
import { equalNode, generateSource, parseSource, parseSourceShouldThrowError } from '../utils';
33
import ForSnapshot from '../__snapshot__/for';
44

@@ -16,12 +16,9 @@ describe('for', () => {
1616
equalNode(node, ForSnapshot.inWithoutDecl);
1717
});
1818
it('async in for of without decl', () => {
19-
const res = parseSourceShouldThrowError(
19+
parseSourceShouldThrowError(
2020
generateSource([`var async;`, `for (async of [1]) ;`]),
21-
'Unexpected token',
22-
'(2:14)'
21+
'Unexpected token (2:14)'
2322
);
24-
25-
expect(res).toBe(true);
2623
});
2724
});

__test__/identifier/normal.test.ts

+35-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, it } from 'vitest';
2-
import { equalNode, generateSource, parseSource } from '../utils';
2+
import { equalNode, generateSource, parseSource, parseSourceShouldThrowError } from '../utils';
33
import NormalIdentifierSnapshot from '../__snapshot__/identifier/normal';
44

55
describe('normal identifier test', () => {
@@ -15,9 +15,41 @@ describe('normal identifier test', () => {
1515
equalNode(node, NormalIdentifierSnapshot.ImportIdentifierAs);
1616
});
1717

18-
it('issue 50', () => {
18+
it('type/value same name #1', () => {
1919
const node = parseSource(generateSource([`type abc = 1234;`, `var abc;`]));
2020

21-
equalNode(node, NormalIdentifierSnapshot.Issue50);
21+
equalNode(node, NormalIdentifierSnapshot.TypeNameSame1);
22+
});
23+
24+
it('type/identifier same name #2', () => {
25+
const node = parseSource(generateSource([`type abc = 1234;`, `let abc;`]));
26+
27+
equalNode(node, NormalIdentifierSnapshot.TypeNameSame2);
28+
});
29+
30+
it('type/identifier same name #3', () => {
31+
const node = parseSource(generateSource([`type abc = 1234;`, `function abc() {}`]));
32+
33+
equalNode(node, NormalIdentifierSnapshot.TypeNameSame3);
34+
});
35+
36+
it('interface merging', () => {
37+
const node = parseSource(generateSource([`interface abc {}`, `interface abc {}`]));
38+
39+
equalNode(node, NormalIdentifierSnapshot.InterfaceMerging);
40+
});
41+
42+
it('identifier multiple times error #1', () => {
43+
parseSourceShouldThrowError(
44+
generateSource([`let abc = 1234;`, `function abc() {}`]),
45+
"Identifier 'abc' has already been declared (2:9)"
46+
);
47+
});
48+
49+
it('identifier multiple times error #2', () => {
50+
parseSourceShouldThrowError(
51+
generateSource([`type abc = 1234;`, `type abc = 'hi';`]),
52+
"type 'abc' has already been declared. (2:5)"
53+
);
2254
});
2355
});

0 commit comments

Comments
 (0)