diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md index 7b9b2c4a630..56427fe58a3 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -7,7 +7,7 @@ assignees: '' --- - number, not number | null verify.codeFix({ description: "Change 'function(number?): number' to '(arg0: number) => number'", errorCode: 8020, index: 0, - newRangeContent: "(arg0: number) => number", + newRangeContent: "(arg0: number | null) => number", }); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue1.ts b/tests/cases/fourslash/codeFixCorrectReturnValue1.ts new file mode 100644 index 00000000000..4dc5bdfc683 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue1.ts @@ -0,0 +1,9 @@ +/// + +//// function Foo (): number { +//// 1 +//// } + +verify.codeFixAvailable([ + { description: 'Add a return statement' }, +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue10.ts b/tests/cases/fourslash/codeFixCorrectReturnValue10.ts new file mode 100644 index 00000000000..61523d804b1 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue10.ts @@ -0,0 +1,8 @@ +/// + +//// const a: ((() => number) | (() => undefined)) = () => { 1 } + +verify.codeFixAvailable([ + { description: ts.Diagnostics.Add_a_return_statement.message }, + { description: ts.Diagnostics.Remove_braces_from_arrow_function_body.message } +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue11.ts b/tests/cases/fourslash/codeFixCorrectReturnValue11.ts new file mode 100644 index 00000000000..a57c0513495 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue11.ts @@ -0,0 +1,13 @@ +/// +//// interface A { +//// bar: string +//// } +//// +//// function Foo (): A { +//// { bar: '123' } +//// } + +verify.codeFixAvailable([ + { description: 'Add a return statement' }, + { description: 'Remove unused label' }, +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue12.ts b/tests/cases/fourslash/codeFixCorrectReturnValue12.ts new file mode 100644 index 00000000000..8a4c0dbf923 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue12.ts @@ -0,0 +1,15 @@ +/// +//// interface A { +//// bar: string +//// } +//// +//// function Foo (a: () => A) { a() } +//// Foo(() => { +//// { bar: '123' } +//// }) + +verify.codeFixAvailable([ + { description: ts.Diagnostics.Add_a_return_statement.message }, + { description: ts.Diagnostics.Remove_braces_from_arrow_function_body.message }, + { description: ts.Diagnostics.Remove_unused_label.message } +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue13.ts b/tests/cases/fourslash/codeFixCorrectReturnValue13.ts new file mode 100644 index 00000000000..3c159151e1e --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue13.ts @@ -0,0 +1,14 @@ +/// +//// interface A { +//// bar: string +//// } +//// +//// const a: () => A = () => { +//// { bar: '1' } +//// } + +verify.codeFixAvailable([ + { description: ts.Diagnostics.Add_a_return_statement.message }, + { description: ts.Diagnostics.Remove_braces_from_arrow_function_body.message }, + { description: ts.Diagnostics.Remove_unused_label.message } +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue14.ts b/tests/cases/fourslash/codeFixCorrectReturnValue14.ts new file mode 100644 index 00000000000..0f602eb1a13 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue14.ts @@ -0,0 +1,13 @@ +/// +//// interface A { +//// bar: string +//// } +//// +//// const a: () => A = () => { +//// bar: '1' +//// } + +verify.codeFixAvailable([ + { description: 'Wrap the following body with parentheses which should be an object literal' }, + { description: 'Remove unused label' }, +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue15.ts b/tests/cases/fourslash/codeFixCorrectReturnValue15.ts new file mode 100644 index 00000000000..6b6280cec4a --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue15.ts @@ -0,0 +1,12 @@ +/// +//// interface A { +//// bar: string +//// } +//// +//// function Foo (a: () => A) { a() } +//// Foo(() => { bar: '1' }) + +verify.codeFixAvailable([ + { description: 'Wrap the following body with parentheses which should be an object literal' }, + { description: 'Remove unused label' }, +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue16.ts b/tests/cases/fourslash/codeFixCorrectReturnValue16.ts new file mode 100644 index 00000000000..bacb9a373b2 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue16.ts @@ -0,0 +1,13 @@ +/// + +//// interface A { +//// bar: string +//// } +//// +//// function Foo (a: () => A) { a() } +//// Foo(() => { bar: '1' }) + +verify.codeFixAvailable([ + { description: 'Wrap the following body with parentheses which should be an object literal' }, + { description: 'Remove unused label' }, +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue17.ts b/tests/cases/fourslash/codeFixCorrectReturnValue17.ts new file mode 100644 index 00000000000..2572b478e17 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue17.ts @@ -0,0 +1,14 @@ +/// + +//// interface A { +//// bar: string +//// } +//// +//// function Foo (): A { +//// bar: '123' +//// } + +verify.codeFixAvailable([ + { description: 'Add a return statement' }, + { description: 'Remove unused label' }, +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue18.ts b/tests/cases/fourslash/codeFixCorrectReturnValue18.ts new file mode 100644 index 00000000000..633a0096003 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue18.ts @@ -0,0 +1,17 @@ +/// + +//@Filename: file.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// class Comp { props: { t: () => number } } +//// var x = { 1 }} />; + +verify.codeFixAvailable([ + { description: ts.Diagnostics.Add_a_return_statement.message }, + { description: ts.Diagnostics.Remove_braces_from_arrow_function_body.message }, + { description: `Infer type of 'props' from usage` } +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue19.ts b/tests/cases/fourslash/codeFixCorrectReturnValue19.ts new file mode 100644 index 00000000000..a8726a5ed6f --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue19.ts @@ -0,0 +1,20 @@ +/// + +//@Filename: file.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface A { +//// bar: string +//// } +//// class Comp { props: { t: () => number } } +//// var x = { bar: '1' }} />; + +verify.codeFixAvailable([ + { description: 'Wrap the following body with parentheses which should be an object literal' }, + { description: `Infer type of 'props' from usage` }, + { description: 'Remove unused label' }, +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue2.ts b/tests/cases/fourslash/codeFixCorrectReturnValue2.ts new file mode 100644 index 00000000000..9d361067c4c --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue2.ts @@ -0,0 +1,13 @@ +/// + +//// interface A { +//// foo: number +//// } + +//// function Foo (): A { +//// ({ foo: 1 }) +//// } + +verify.codeFixAvailable([ + { description: 'Add a return statement' }, +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue20.ts b/tests/cases/fourslash/codeFixCorrectReturnValue20.ts new file mode 100644 index 00000000000..a9b9a6cd1ce --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue20.ts @@ -0,0 +1,23 @@ +/// + +//@Filename: file.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface A { +//// bar: string +//// } +//// class Comp { props: { t: () => number } } +//// var x = { +//// { bar: '1' } +//// }} />; + +verify.codeFixAvailable([ + { description: ts.Diagnostics.Add_a_return_statement.message }, + { description: ts.Diagnostics.Remove_braces_from_arrow_function_body.message }, + { description: `Infer type of 'props' from usage` }, + { description: ts.Diagnostics.Remove_unused_label.message }, +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue21.ts b/tests/cases/fourslash/codeFixCorrectReturnValue21.ts new file mode 100644 index 00000000000..fc0fef8872b --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue21.ts @@ -0,0 +1,14 @@ +/// + +//// interface A { +//// a: () => number +//// } +//// +//// let b: A = { +//// a: () => { 1 } +//// } + +verify.codeFixAvailable([ + { description: ts.Diagnostics.Add_a_return_statement.message }, + { description: ts.Diagnostics.Remove_braces_from_arrow_function_body.message } +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue22.ts b/tests/cases/fourslash/codeFixCorrectReturnValue22.ts new file mode 100644 index 00000000000..59f1e9cc4b6 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue22.ts @@ -0,0 +1,16 @@ +/// + +//// interface A { +//// a: () => number +//// } +//// +//// function Foo (): A { +//// return { +//// a: () => { 1 } +//// } +//// } + +verify.codeFixAvailable([ + { description: ts.Diagnostics.Add_a_return_statement.message }, + { description: ts.Diagnostics.Remove_braces_from_arrow_function_body.message } +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue23.ts b/tests/cases/fourslash/codeFixCorrectReturnValue23.ts new file mode 100644 index 00000000000..859749e754b --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue23.ts @@ -0,0 +1,10 @@ +/// + +//// class Foo { +//// bar: () => number = () => { 1 } +//// } + +verify.codeFixAvailable([ + { description: ts.Diagnostics.Add_a_return_statement.message }, + { description: ts.Diagnostics.Remove_braces_from_arrow_function_body.message } +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue24.ts b/tests/cases/fourslash/codeFixCorrectReturnValue24.ts new file mode 100644 index 00000000000..6cc9e52e4d0 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue24.ts @@ -0,0 +1,12 @@ +/// + +//// function Foo (a: () => number) { a() } +//// Foo(() => { /* leading */ 1 /* trailing */ }) + +verify.codeFix({ + description: "Add a return statement", + index: 0, + newFileContent: +`function Foo (a: () => number) { a() } +Foo(() => { /* leading */ return 1 /* trailing */ })` +}) \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue25.ts b/tests/cases/fourslash/codeFixCorrectReturnValue25.ts new file mode 100644 index 00000000000..1cb93bf3ecf --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue25.ts @@ -0,0 +1,12 @@ +/// + +//// function Foo (a: () => number) { a() } +//// Foo(() => { /* leading */ 1 /* trailing */ }) + +verify.codeFix({ + description: ts.Diagnostics.Remove_braces_from_arrow_function_body.message, + index: 1, + newFileContent: +`function Foo (a: () => number) { a() } +Foo(() => /* leading */ 1 /* trailing */)` +}) \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue26.ts b/tests/cases/fourslash/codeFixCorrectReturnValue26.ts new file mode 100644 index 00000000000..36f9ff9fa3b --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue26.ts @@ -0,0 +1,23 @@ +/// +//// interface A { +//// bar: string; +//// } +//// +//// function Foo (a: () => A) { a(); } +//// Foo(() => { +//// { bar: '123'; } +//// }) + +verify.codeFix({ + description: "Add a return statement", + index: 0, + newFileContent: +`interface A { + bar: string; +} + +function Foo (a: () => A) { a(); } +Foo(() => { + return { bar: '123' }; +})` +}) diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue3.ts b/tests/cases/fourslash/codeFixCorrectReturnValue3.ts new file mode 100644 index 00000000000..364da21f42d --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue3.ts @@ -0,0 +1,13 @@ +/// + +//// interface A { +//// foo: number +//// } + +//// function Foo (): A | number { +//// 1 +//// } + +verify.codeFixAvailable([ + { description: 'Add a return statement' }, +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue4.ts b/tests/cases/fourslash/codeFixCorrectReturnValue4.ts new file mode 100644 index 00000000000..e1270bee3f3 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue4.ts @@ -0,0 +1,7 @@ +/// + +//// function Foo (): any { +//// 1 +//// } + +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue5.ts b/tests/cases/fourslash/codeFixCorrectReturnValue5.ts new file mode 100644 index 00000000000..de457636368 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue5.ts @@ -0,0 +1,7 @@ +/// + +//// function Foo (): void { +//// undefined +//// } + +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue6.ts b/tests/cases/fourslash/codeFixCorrectReturnValue6.ts new file mode 100644 index 00000000000..693145f8c61 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue6.ts @@ -0,0 +1,9 @@ +/// + +//// function Foo (): undefined { +//// undefined +//// } + +verify.codeFixAvailable([ + { description: 'Add a return statement' }, +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue7.ts b/tests/cases/fourslash/codeFixCorrectReturnValue7.ts new file mode 100644 index 00000000000..0125238c8a4 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue7.ts @@ -0,0 +1,9 @@ +/// + +//// function Foo (a: () => number) { a() } +//// Foo(() => { 1 }) + +verify.codeFixAvailable([ + { description: ts.Diagnostics.Add_a_return_statement.message }, + { description: ts.Diagnostics.Remove_braces_from_arrow_function_body.message } +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue8.ts b/tests/cases/fourslash/codeFixCorrectReturnValue8.ts new file mode 100644 index 00000000000..640f84af4d0 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue8.ts @@ -0,0 +1,9 @@ +/// + +//// function Foo (a: (() => number) | (() => undefined) ) { a() } +//// Foo(() => { 1 }) + +verify.codeFixAvailable([ + { description: ts.Diagnostics.Add_a_return_statement.message }, + { description: ts.Diagnostics.Remove_braces_from_arrow_function_body.message } +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue9.ts b/tests/cases/fourslash/codeFixCorrectReturnValue9.ts new file mode 100644 index 00000000000..97e684b0c0f --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue9.ts @@ -0,0 +1,8 @@ +/// + +//// const a: () => number = () => { 1 } + +verify.codeFixAvailable([ + { description: ts.Diagnostics.Add_a_return_statement.message }, + { description: ts.Diagnostics.Remove_braces_from_arrow_function_body.message } +]); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue_all1.ts b/tests/cases/fourslash/codeFixCorrectReturnValue_all1.ts new file mode 100644 index 00000000000..e14f31e5e8b --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue_all1.ts @@ -0,0 +1,121 @@ +/// + +//// interface A { +//// bar: string +//// } +//// +//// function foo1 (_a: () => number ) { } +//// foo1(() => { +//// 1 +//// }) +//// function foo2 (_a: () => A) { } +//// foo2(() => { +//// { bar: '1' } +//// }) +//// foo2(() => { +//// bar: '1' +//// }) +//// function foo3 (_a: () => A | number) { } +//// foo3(() => { +//// 1 +//// }) +//// foo3(() => { +//// bar: '1' +//// }) +//// +//// function bar1 (): number { +//// 1 +//// } +//// function bar2 (): A { +//// { bar: '1' } +//// } +//// function bar3 (): A { +//// bar: '1' +//// } +//// function bar4 (): A | number { +//// 1 +//// } +//// function bar5(): A | number { +//// bar: '1' +//// } +// +//// const baz1: () => number = () => { +//// 1 +//// } +//// const baz2: () => A = () => { +//// { bar: '1' } +//// } +//// const baz3: () => A = () => { +//// bar: '1' +//// } +//// const baz4: ((() => number) | (() => A)) = () => { +//// 1 +//// } +//// const baz5: ((() => number) | (() => A)) = () => { +//// bar: '1' +//// } +//// const baz6: () => number = () => { 1 } +//// +//// const test: { a: () => A } = { a: () => { bar: '1' } } + +verify.codeFixAll({ + fixId: "fixAddReturnStatement", + fixAllDescription: "Add all missing return statement", + newFileContent: +`interface A { + bar: string +} + +function foo1 (_a: () => number ) { } +foo1(() => { + return 1 +}) +function foo2 (_a: () => A) { } +foo2(() => { + return { bar: '1' } +}) +foo2(() => { + return { bar: '1' } +}) +function foo3 (_a: () => A | number) { } +foo3(() => { + return 1 +}) +foo3(() => { + return { bar: '1' } +}) + +function bar1 (): number { + return 1 +} +function bar2 (): A { + return { bar: '1' } +} +function bar3 (): A { + return { bar: '1' } +} +function bar4 (): A | number { + return 1 +} +function bar5(): A | number { + return { bar: '1' } +} +const baz1: () => number = () => { + return 1 +} +const baz2: () => A = () => { + return { bar: '1' } +} +const baz3: () => A = () => { + return { bar: '1' } +} +const baz4: ((() => number) | (() => A)) = () => { + return 1 +} +const baz5: ((() => number) | (() => A)) = () => { + return { bar: '1' } +} +const baz6: () => number = () => { return 1 } + +const test: { a: () => A } = { a: () => { return { bar: '1' } } }`, +}); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue_all2.ts b/tests/cases/fourslash/codeFixCorrectReturnValue_all2.ts new file mode 100644 index 00000000000..34b889849ac --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue_all2.ts @@ -0,0 +1,99 @@ +/// + +//// interface A { +//// bar: string +//// } +//// +//// function foo1 (_a: () => number ) { } +//// foo1(() => { +//// 1 +//// }) +//// function foo2 (_a: () => A) { } +//// foo2(() => { +//// { bar: '1' } +//// }) +//// foo2(() => { +//// bar: '1' +//// }) +//// function foo3 (_a: () => A | number) { } +//// foo3(() => { +//// 1 +//// }) +//// foo3(() => { +//// bar: '1' +//// }) +//// +//// function bar1 (): number { +//// 1 +//// } +//// function bar2 (): A { +//// { bar: '1' } +//// } +//// function bar3 (): A { +//// bar: '1' +//// } +//// function bar4 (): A | number { +//// 1 +//// } +//// function bar5(): A | number { +//// bar: '1' +//// } +// +//// const baz1: () => number = () => { +//// 1 +//// } +//// const baz2: () => A = () => { +//// { bar: '1' } +//// } +//// const baz3: () => A = () => { +//// bar: '1' +//// } +//// const baz4: ((() => number) | (() => A)) = () => { +//// 1 +//// } +//// const baz5: ((() => number) | (() => A)) = () => { +//// bar: '1' +//// } +//// +//// const test: { a: () => A } = { a: () => { bar: '1' } } + +verify.codeFixAll({ + fixId: "fixRemoveBracesFromArrowFunctionBody", + fixAllDescription: ts.Diagnostics.Remove_braces_from_all_arrow_function_bodies_with_relevant_issues.message, + newFileContent: +`interface A { + bar: string +} + +function foo1 (_a: () => number ) { } +foo1(() => 1) +function foo2 (_a: () => A) { } +foo2(() => ({ bar: '1' })) +foo2(() => ({ bar: '1' })) +function foo3 (_a: () => A | number) { } +foo3(() => 1) +foo3(() => ({ bar: '1' })) + +function bar1 (): number { + 1 +} +function bar2 (): A { + { bar: '1' } +} +function bar3 (): A { + bar: '1' +} +function bar4 (): A | number { + 1 +} +function bar5(): A | number { + bar: '1' +} +const baz1: () => number = () => 1 +const baz2: () => A = () => ({ bar: '1' }) +const baz3: () => A = () => ({ bar: '1' }) +const baz4: ((() => number) | (() => A)) = () => 1 +const baz5: ((() => number) | (() => A)) = () => ({ bar: '1' }) + +const test: { a: () => A } = { a: () => ({ bar: '1' }) }`, +}); diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue_all3.ts b/tests/cases/fourslash/codeFixCorrectReturnValue_all3.ts new file mode 100644 index 00000000000..0d4806b19c1 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue_all3.ts @@ -0,0 +1,99 @@ +/// + +//// interface A { +//// bar: string +//// } +//// +//// function foo1 (_a: () => number ) { } +//// foo1(() => { +//// 1 +//// }) +//// function foo2 (_a: () => A) { } +//// foo2(() => { +//// { bar: '1' } +//// }) +//// foo2(() => { +//// bar: '1' +//// }) +//// function foo3 (_a: () => A | number) { } +//// foo3(() => { +//// 1 +//// }) +//// foo3(() => { +//// bar: '1' +//// }) +//// +//// function bar1 (): number { +//// 1 +//// } +//// function bar2 (): A { +//// { bar: '1' } +//// } +//// function bar3 (): A { +//// bar: '1' +//// } +//// function bar4 (): A | number { +//// 1 +//// } +//// function bar5(): A | number { +//// bar: '1' +//// } +// +//// const baz1: () => number = () => { +//// 1 +//// } +//// const baz2: () => A = () => { +//// { bar: '1' } +//// } +//// const baz3: () => A = () => { +//// bar: '1' +//// } +//// const baz4: ((() => number) | (() => A)) = () => { +//// 1 +//// } +//// const baz5: ((() => number) | (() => A)) = () => { +//// bar: '1' +//// } +//// +//// const test: { a: () => A } = { a: () => { bar: '1' } } + +verify.codeFixAll({ + fixId: "fixWrapTheBlockWithParen", + fixAllDescription: "Wrap all object literal with parentheses", + newFileContent: +`interface A { + bar: string +} + +function foo1 (_a: () => number ) { } +foo1(() => (1)) +function foo2 (_a: () => A) { } +foo2(() => ({ bar: '1' })) +foo2(() => ({ bar: '1' })) +function foo3 (_a: () => A | number) { } +foo3(() => (1)) +foo3(() => ({ bar: '1' })) + +function bar1 (): number { + 1 +} +function bar2 (): A { + { bar: '1' } +} +function bar3 (): A { + bar: '1' +} +function bar4 (): A | number { + 1 +} +function bar5(): A | number { + bar: '1' +} +const baz1: () => number = () => (1) +const baz2: () => A = () => ({ bar: '1' }) +const baz3: () => A = () => ({ bar: '1' }) +const baz4: ((() => number) | (() => A)) = () => (1) +const baz5: ((() => number) | (() => A)) = () => ({ bar: '1' }) + +const test: { a: () => A } = { a: () => ({ bar: '1' }) }`, +}); diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile10.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile10.ts new file mode 100644 index 00000000000..ff1ba5c75b5 --- /dev/null +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile10.ts @@ -0,0 +1,23 @@ +/// + +// @allowjs: true +// @checkJs: true +// @noEmit: true + +// @filename: a.js +////let x = ""; +////[|x|] = 1; + +// verify.codeFixAvailable([ +// { description: ts.Diagnostics.Ignore_this_error_message.message }, +// { description: ts.Diagnostics.Disable_checking_for_this_file.message } +// ]); + +verify.codeFix({ + description: ts.Diagnostics.Disable_checking_for_this_file.message, + index: 1, + newFileContent: +`// @ts-nocheck +let x = ""; +x = 1;`, +}); diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile9.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile9.ts new file mode 100644 index 00000000000..e7401e683b7 --- /dev/null +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile9.ts @@ -0,0 +1,24 @@ +/// + +// @allowjs: true +// @checkJs: true +// @noEmit: true + +// @filename: a.js +////// @ts-check +////let x = ""; +////[|x|] = 1; + +// verify.codeFixAvailable([ +// { description: ts.Diagnostics.Ignore_this_error_message.message }, +// { description: ts.Diagnostics.Disable_checking_for_this_file.message } +// ]); + +verify.codeFix({ + description: ts.Diagnostics.Disable_checking_for_this_file.message, + index: 1, + newFileContent: +`// @ts-nocheck +let x = ""; +x = 1;`, +}); diff --git a/tests/cases/fourslash/codeFixIncorrectNamedTupleSyntax1.ts b/tests/cases/fourslash/codeFixIncorrectNamedTupleSyntax1.ts new file mode 100644 index 00000000000..08c8234e634 --- /dev/null +++ b/tests/cases/fourslash/codeFixIncorrectNamedTupleSyntax1.ts @@ -0,0 +1,10 @@ +/// + +////type Tup = [first: string, elem: ...any[]]; + +verify.codeFix({ + description: "Move labeled tuple element modifiers to labels", + index: 0, + newFileContent: + `type Tup = [first: string, ...elem: any[]];` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixIncorrectNamedTupleSyntax2.ts b/tests/cases/fourslash/codeFixIncorrectNamedTupleSyntax2.ts new file mode 100644 index 00000000000..9a7f7590d96 --- /dev/null +++ b/tests/cases/fourslash/codeFixIncorrectNamedTupleSyntax2.ts @@ -0,0 +1,10 @@ +/// + +////type Tup = [first: string, elem: any[]?]; + +verify.codeFix({ + description: "Move labeled tuple element modifiers to labels", + index: 0, + newFileContent: + `type Tup = [first: string, elem?: any[]];` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsageParameterLiteral.ts b/tests/cases/fourslash/codeFixInferFromUsageParameterLiteral.ts new file mode 100644 index 00000000000..16610635982 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageParameterLiteral.ts @@ -0,0 +1,10 @@ +/// + +// @noImplicitAny: true +//// function foo([|text |]) { +//// text.length; +//// text.indexOf("z"); +//// text.charAt(0); +//// } + +verify.rangeAfterCodeFix("text: string", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); diff --git a/tests/cases/fourslash/codeFixInferFromUsagePropertyAccess.ts b/tests/cases/fourslash/codeFixInferFromUsagePropertyAccess.ts index 44d2e2d7b1c..41112b2409e 100644 --- a/tests/cases/fourslash/codeFixInferFromUsagePropertyAccess.ts +++ b/tests/cases/fourslash/codeFixInferFromUsagePropertyAccess.ts @@ -12,4 +12,4 @@ //// return x.y.z ////} -verify.rangeAfterCodeFix("a: { b: { c: void; }; }, m: { n: () => number; }, x: { y: { z: number[]; }; }", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); +verify.rangeAfterCodeFix("a: { b: { c: any; }; }, m: { n: () => number; }, x: { y: { z: number[]; }; }", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); diff --git a/tests/cases/fourslash/codeFixInferFromUsagePropertyAccessJS.ts b/tests/cases/fourslash/codeFixInferFromUsagePropertyAccessJS.ts index 357b1a991ba..ed9d4b33b37 100644 --- a/tests/cases/fourslash/codeFixInferFromUsagePropertyAccessJS.ts +++ b/tests/cases/fourslash/codeFixInferFromUsagePropertyAccessJS.ts @@ -21,7 +21,7 @@ verify.codeFix({ index: 0, newFileContent: `/** - * @param {{ b: { c: void; }; }} a + * @param {{ b: { c: any; }; }} a * @param {{ n: () => number; }} m * @param {{ y: { z: number[]; }; }} x */ diff --git a/tests/cases/fourslash/codeFixInferFromUsageVariableLiteral.ts b/tests/cases/fourslash/codeFixInferFromUsageVariableLiteral.ts new file mode 100644 index 00000000000..2641b009636 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageVariableLiteral.ts @@ -0,0 +1,9 @@ +/// + +// @noImplicitAny: true +//// let [|text! |]; +//// text.length; +//// text.indexOf("z"); +//// text.charAt(0); + +verify.rangeAfterCodeFix("text!: string", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); diff --git a/tests/cases/fourslash/codeFixPropertyOverrideAccess.ts b/tests/cases/fourslash/codeFixPropertyOverrideAccess.ts new file mode 100644 index 00000000000..d930f76e468 --- /dev/null +++ b/tests/cases/fourslash/codeFixPropertyOverrideAccess.ts @@ -0,0 +1,27 @@ +/// + +// @strict: true + +//// class A { +//// get x() { return 1 } +//// } +//// class B extends A { +//// x = 2 +//// } + +verify.codeFix({ + description: `Generate 'get' and 'set' accessors`, + newFileContent: `class A { + get x() { return 1 } +} +class B extends A { + private _x = 2 + public get x() { + return this._x + } + public set x(value) { + this._x = value + } +}`, + index: 0 +}) diff --git a/tests/cases/fourslash/codeFixPropertyOverrideAccess2.ts b/tests/cases/fourslash/codeFixPropertyOverrideAccess2.ts new file mode 100644 index 00000000000..3146d1364fe --- /dev/null +++ b/tests/cases/fourslash/codeFixPropertyOverrideAccess2.ts @@ -0,0 +1,27 @@ +/// + +// @strict: true + +//// class A { +//// x = 1 +//// } +//// class B extends A { +//// get x() { return 2 } +//// } + +verify.codeFix({ + description: `Generate 'get' and 'set' accessors`, + newFileContent: `class A { + private _x = 1 + public get x() { + return this._x + } + public set x(value) { + this._x = value + } +} +class B extends A { + get x() { return 2 } +}`, + index: 0 +}) diff --git a/tests/cases/fourslash/codeFixPropertyOverrideAccess3.ts b/tests/cases/fourslash/codeFixPropertyOverrideAccess3.ts new file mode 100644 index 00000000000..cc83c8e067f --- /dev/null +++ b/tests/cases/fourslash/codeFixPropertyOverrideAccess3.ts @@ -0,0 +1,28 @@ +/// + +// @strict: true + +// @Filename: foo.ts +//// import { A } from './source' +//// class B extends A { +//// get x() { return 2 } +//// } +// @Filename: source.ts +//// export class A { +//// x = 1 +//// } + +verify.codeFix({ + description: `Generate 'get' and 'set' accessors`, + newFileContent: { + '/tests/cases/fourslash/source.ts': `export class A { + private _x = 1; + public get x() { + return this._x; + } + public set x(value) { + this._x = value; + } +}`}, + index: 0 +}) diff --git a/tests/cases/fourslash/codeFixPropertyOverrideAccess_all.ts b/tests/cases/fourslash/codeFixPropertyOverrideAccess_all.ts new file mode 100644 index 00000000000..5cc9a7a8eaa --- /dev/null +++ b/tests/cases/fourslash/codeFixPropertyOverrideAccess_all.ts @@ -0,0 +1,45 @@ +/// + +// @strict: true + +//// class A { +//// get x() { return 1 } +//// } +//// class B extends A { +//// x = 2 +//// } +//// class C { +//// get x() { return 3 } +//// } +//// class D extends C { +//// x = 4 +//// } + +verify.codeFixAll({ + fixId: "fixPropertyOverrideAccessor", + fixAllDescription: "Generate 'get' and 'set' accessors for all overriding properties", + newFileContent: `class A { + get x() { return 1 } +} +class B extends A { + private _x = 2 + public get x() { + return this._x + } + public set x(value) { + this._x = value + } +} +class C { + get x() { return 3 } +} +class D extends C { + private _x = 4 + public get x() { + return this._x + } + public set x(value) { + this._x = value + } +}`, +}) diff --git a/tests/cases/fourslash/codeFixRequireInTs.ts b/tests/cases/fourslash/codeFixRequireInTs1.ts similarity index 64% rename from tests/cases/fourslash/codeFixRequireInTs.ts rename to tests/cases/fourslash/codeFixRequireInTs1.ts index 345b15f69f2..773afe0eb12 100644 --- a/tests/cases/fourslash/codeFixRequireInTs.ts +++ b/tests/cases/fourslash/codeFixRequireInTs1.ts @@ -9,7 +9,6 @@ verify.getSuggestionDiagnostics([{ }]); verify.codeFix({ - description: "Convert 'require' to 'import'", - newFileContent: -`import a = require("a");`, + description: ts.Diagnostics.Convert_require_to_import.message, + newFileContent: 'import a = require("a");', }); diff --git a/tests/cases/fourslash/codeFixRequireInTs2.ts b/tests/cases/fourslash/codeFixRequireInTs2.ts new file mode 100644 index 00000000000..6d6325cdfef --- /dev/null +++ b/tests/cases/fourslash/codeFixRequireInTs2.ts @@ -0,0 +1,9 @@ +/// + +// @Filename: /a.ts +////const { a, b, c } = [|require("a")|]; + +verify.codeFix({ + description: ts.Diagnostics.Convert_require_to_import.message, + newFileContent: 'import { a, b, c } from "a";', +}); diff --git a/tests/cases/fourslash/codeFixRequireInTs3.ts b/tests/cases/fourslash/codeFixRequireInTs3.ts new file mode 100644 index 00000000000..3943f38fc1e --- /dev/null +++ b/tests/cases/fourslash/codeFixRequireInTs3.ts @@ -0,0 +1,6 @@ +/// + +// @Filename: /a.ts +////const { a, b: { c } } = [|require("a")|]; + +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixRequireInTs_all.ts b/tests/cases/fourslash/codeFixRequireInTs_all.ts index 9f9fe4824a8..d37d2455e93 100644 --- a/tests/cases/fourslash/codeFixRequireInTs_all.ts +++ b/tests/cases/fourslash/codeFixRequireInTs_all.ts @@ -3,11 +3,15 @@ // @Filename: /a.ts ////const a = [|require("a")|]; ////const b = [|require("b")|]; +////const { c } = [|require("c")|]; +////const { d } = [|require("d")|]; verify.codeFixAll({ fixId: "requireInTs", - fixAllDescription: "Convert all 'require' to 'import'", + fixAllDescription: ts.Diagnostics.Convert_all_require_to_import.message, newFileContent: `import a = require("a"); -import b = require("b");`, +import b = require("b"); +import { c } from "c"; +import { d } from "d";`, }); diff --git a/tests/cases/fourslash/codeFixRequireInTs_allowSyntheticDefaultImports.ts b/tests/cases/fourslash/codeFixRequireInTs_allowSyntheticDefaultImports.ts index 949387af2e5..5fcad968e23 100644 --- a/tests/cases/fourslash/codeFixRequireInTs_allowSyntheticDefaultImports.ts +++ b/tests/cases/fourslash/codeFixRequireInTs_allowSyntheticDefaultImports.ts @@ -1,11 +1,10 @@ /// // @allowSyntheticDefaultImports: true - // @Filename: /a.ts ////const a = [|require("a")|]; verify.codeFix({ - description: "Convert 'require' to 'import'", - newFileContent: `import a from "a";`, + description: ts.Diagnostics.Convert_require_to_import.message, + newFileContent: 'import a from "a";', }); diff --git a/tests/cases/fourslash/codeFixRequireInTs_allowSyntheticDefaultImports_all.ts b/tests/cases/fourslash/codeFixRequireInTs_allowSyntheticDefaultImports_all.ts new file mode 100644 index 00000000000..8e0017eb2a5 --- /dev/null +++ b/tests/cases/fourslash/codeFixRequireInTs_allowSyntheticDefaultImports_all.ts @@ -0,0 +1,18 @@ +/// + +// @allowSyntheticDefaultImports: true +// @Filename: /a.ts +////const a = [|require("a")|]; +////const b = [|require("b")|]; +////const { c } = [|require("c")|]; +////const { d } = [|require("d")|]; + +verify.codeFixAll({ + fixId: "requireInTs", + fixAllDescription: ts.Diagnostics.Convert_all_require_to_import.message, + newFileContent: +`import a from "a"; +import b from "b"; +import { c } from "c"; +import { d } from "d";`, +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction1.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction1.ts new file mode 100644 index 00000000000..9a52e240690 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction1.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): number {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "number", "number"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction10.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction10.ts new file mode 100644 index 00000000000..0e7c3994904 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction10.ts @@ -0,0 +1,13 @@ +/// + +// @target: es2015 +////type Foo = "a" | "b"; +////async function fn(): Foo {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "Foo", "Foo"], + newFileContent: +`type Foo = "a" | "b"; +async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction11.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction11.ts new file mode 100644 index 00000000000..338087032a2 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction11.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): PromiseLike {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "PromiseLike", "string"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction12.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction12.ts new file mode 100644 index 00000000000..0e3cb2b90c6 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction12.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): PromiseLike {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "PromiseLike", "void"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction13.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction13.ts new file mode 100644 index 00000000000..0cbc1859571 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction13.ts @@ -0,0 +1,13 @@ +/// + +// @target: es2015 +////declare class Thenable { then(): void; } +////async function fn(): Thenable {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "Thenable", "void"], + newFileContent: +`declare class Thenable { then(): void; } +async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction14.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction14.ts new file mode 100644 index 00000000000..315c3ff5aea --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction14.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): string | symbol {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "string | symbol", "string | symbol"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction15.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction15.ts new file mode 100644 index 00000000000..ff0f6105748 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction15.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////const foo = async function (): number {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "number", "number"], + newFileContent: `const foo = async function (): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction16.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction16.ts new file mode 100644 index 00000000000..e0430490b50 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction16.ts @@ -0,0 +1,15 @@ +/// + +// @target: es2015 +////class A { +//// async foo(): number {} +////} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "number", "number"], + newFileContent: +`class A { + async foo(): Promise {} +}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction17.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction17.ts new file mode 100644 index 00000000000..082d4ab2fe5 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction17.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////const foo = async (): number => {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "number", "number"], + newFileContent: `const foo = async (): Promise => {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction18.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction18.ts new file mode 100644 index 00000000000..75b6727fd0a --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction18.ts @@ -0,0 +1,20 @@ +/// + +// @target: es2015 +//// +////interface A {} +////export { A as PublicA }; +////async function foo(): A { +//// return {} +////} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "A", "A"], + newFileContent: ` +interface A {} +export { A as PublicA }; +async function foo(): Promise { + return {} +}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction2.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction2.ts new file mode 100644 index 00000000000..10d07519e7d --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction2.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): boolean {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "boolean", "boolean"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction3.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction3.ts new file mode 100644 index 00000000000..06eca5ee4fb --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction3.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): string {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "string", "string"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction4.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction4.ts new file mode 100644 index 00000000000..3aff287ed2c --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction4.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): void {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "void", "void"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction5.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction5.ts new file mode 100644 index 00000000000..dc3a781cacc --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction5.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): null {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "null", "null"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction6.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction6.ts new file mode 100644 index 00000000000..0d027d6a278 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction6.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): undefined {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "undefined", "undefined"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction7.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction7.ts new file mode 100644 index 00000000000..4d9beac706b --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction7.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): any {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "any", "any"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction8.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction8.ts new file mode 100644 index 00000000000..0533791f6f4 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction8.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): symbol {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "symbol", "symbol"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction9.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction9.ts new file mode 100644 index 00000000000..6614735af7d --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction9.ts @@ -0,0 +1,13 @@ +/// + +// @target: es2015 +////interface Foo {} +////async function fn(): Foo {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "Foo", "Foo"], + newFileContent: +`interface Foo {} +async function fn(): Promise> {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction_fixAll.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction_fixAll.ts new file mode 100644 index 00000000000..4ad9a351364 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction_fixAll.ts @@ -0,0 +1,50 @@ +/// + +// @target: es2015 +////declare class Thenable { then(): void; } +////interface Foo {} +////type Bar = "a" | "b"; +//// +////async function f1(): number {} +////async function f2(): boolean {} +////async function f3(): string {} +////async function f4(): void {} +////async function f5(): null {} +////async function f6(): undefined {} +////async function f7(): any {} +////async function f8(): symbol {} +//// +////async function f9(): Foo {} +////async function f10(): Bar {} +////async function f11(): PromiseLike {} +////async function f12(): PromiseLike {} +////async function f13(): Thenable {} +//// +////async function f14(): string | symbol {} + + +verify.codeFixAll({ + fixId: "fixReturnTypeInAsyncFunction", + fixAllDescription: ts.Diagnostics.Fix_all_incorrect_return_type_of_an_async_functions.message, + newFileContent: +`declare class Thenable { then(): void; } +interface Foo {} +type Bar = "a" | "b"; + +async function f1(): Promise {} +async function f2(): Promise {} +async function f3(): Promise {} +async function f4(): Promise {} +async function f5(): Promise {} +async function f6(): Promise {} +async function f7(): Promise {} +async function f8(): Promise {} + +async function f9(): Promise> {} +async function f10(): Promise {} +async function f11(): Promise {} +async function f12(): Promise {} +async function f13(): Promise {} + +async function f14(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixUndeclaredAcrossFiles3.ts b/tests/cases/fourslash/codeFixUndeclaredAcrossFiles3.ts index 9ea5ac1a165..dce1ca38a9d 100644 --- a/tests/cases/fourslash/codeFixUndeclaredAcrossFiles3.ts +++ b/tests/cases/fourslash/codeFixUndeclaredAcrossFiles3.ts @@ -20,7 +20,7 @@ verify.getAndApplyCodeFix(/*errorCode*/ undefined, 0); verify.rangeIs(` - m0(arg0: import("./f2").D) { + m0(arg0: D) { throw new Error("Method not implemented."); } `); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixUndeclaredMethod.ts b/tests/cases/fourslash/codeFixUndeclaredMethod.ts index 32713e5dd19..ac7a8b32b2f 100644 --- a/tests/cases/fourslash/codeFixUndeclaredMethod.ts +++ b/tests/cases/fourslash/codeFixUndeclaredMethod.ts @@ -15,9 +15,6 @@ verify.codeFix({ index: 0, newFileContent: `class A { - foo1(arg0: number, arg1: number, arg2: number) { - throw new Error("Method not implemented."); - } constructor() { this.foo1(1,2,3); // 7 type args @@ -25,6 +22,9 @@ verify.codeFix({ // 8 type args this.foo3<1,2,3,4,5,6,7,8>(); } + foo1(arg0: number, arg1: number, arg2: number) { + throw new Error("Method not implemented."); + } }`, applyChanges: true, }); @@ -34,12 +34,6 @@ verify.codeFix({ index: 0, newFileContent: `class A { - foo2() { - throw new Error("Method not implemented."); - } - foo1(arg0: number, arg1: number, arg2: number) { - throw new Error("Method not implemented."); - } constructor() { this.foo1(1,2,3); // 7 type args @@ -47,6 +41,12 @@ verify.codeFix({ // 8 type args this.foo3<1,2,3,4,5,6,7,8>(); } + foo2() { + throw new Error("Method not implemented."); + } + foo1(arg0: number, arg1: number, arg2: number) { + throw new Error("Method not implemented."); + } }`, applyChanges: true, }); @@ -56,6 +56,13 @@ verify.codeFix({ index: 0, newFileContent: `class A { + constructor() { + this.foo1(1,2,3); + // 7 type args + this.foo2<1,2,3,4,5,6,7>(); + // 8 type args + this.foo3<1,2,3,4,5,6,7,8>(); + } foo3() { throw new Error("Method not implemented."); } @@ -65,12 +72,5 @@ verify.codeFix({ foo1(arg0: number, arg1: number, arg2: number) { throw new Error("Method not implemented."); } - constructor() { - this.foo1(1,2,3); - // 7 type args - this.foo2<1,2,3,4,5,6,7>(); - // 8 type args - this.foo3<1,2,3,4,5,6,7,8>(); - } }` }); diff --git a/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs.ts b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs.ts index c4056625b70..faa5a165ace 100644 --- a/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs.ts +++ b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs.ts @@ -1,10 +1,11 @@ /// -//// class A {[| -//// |]constructor() { +//// class A { +//// constructor() { //// this.foo1(() => 1, () => "2", () => false); //// this.foo2((a: number) => a, (b: string) => b, (c: boolean) => c); -//// } +//// }[| +//// |] //// } verify.codeFix({ diff --git a/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType.ts b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType.ts new file mode 100644 index 00000000000..b9410c03583 --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType.ts @@ -0,0 +1,31 @@ +/// + +// @Filename: a.ts +////export interface A { +//// x: number; +////} +////export function create(fn: (args: A) => void) {} + +// @Filename: b.ts +////import { create } from "./a"; +////class B { +//// bar() { +//// create(args => this.foo(args)); +//// } +////} + +goTo.file("b.ts"); +verify.codeFix({ + description: [ts.Diagnostics.Declare_method_0.message, "foo"], + index: 0, + newFileContent: +`import { create, A } from "./a"; +class B { + bar() { + create(args => this.foo(args)); + } + foo(args: A): void { + throw new Error("Method not implemented."); + } +}` +}); diff --git a/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType1.ts b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType1.ts new file mode 100644 index 00000000000..4a7afe32b53 --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType1.ts @@ -0,0 +1,38 @@ +/// + +// @Filename: a.ts +////export interface A { +//// x: number; +////} + +// @Filename: b.ts +////import { A } from "./a"; +////export interface B { +//// payload: T; +////} +////export function create(fn: (args: B) => void) {} + +// @Filename: c.ts +////import { create } from "./b"; +////class C { +//// bar() { +//// create(args => this.foo(args)); +//// } +////} + +goTo.file("c.ts"); +verify.codeFix({ + description: [ts.Diagnostics.Declare_method_0.message, "foo"], + index: 0, + newFileContent: +`import { create, B } from "./b"; +import { A } from "./a"; +class C { + bar() { + create(args => this.foo(args)); + } + foo(args: B): void { + throw new Error("Method not implemented."); + } +}` +}); diff --git a/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType2.ts b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType2.ts new file mode 100644 index 00000000000..05755845534 --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType2.ts @@ -0,0 +1,45 @@ +/// + +// @Filename: a.ts +////export interface A { +//// x: number; +////} + +// @Filename: b.ts +////export interface B { +//// payload: T; +////} + +// @Filename: c.ts +////import { A } from "./a"; +////import { B } from "./b"; +////export interface C { +//// payload: T; +////} +////export function create(fn: (args: C>) => void) {} + +// @Filename: d.ts +////import { create } from "./c"; +////class D { +//// bar() { +//// create(args => this.foo(args)); +//// } +////} + +goTo.file("d.ts"); +verify.codeFix({ + description: [ts.Diagnostics.Declare_method_0.message, "foo"], + index: 0, + newFileContent: +`import { create, C } from "./c"; +import { B } from "./b"; +import { A } from "./a"; +class D { + bar() { + create(args => this.foo(args)); + } + foo(args: C>): void { + throw new Error("Method not implemented."); + } +}` +}); diff --git a/tests/cases/fourslash/codeFixUndeclaredMethodObjectLiteralArgs.ts b/tests/cases/fourslash/codeFixUndeclaredMethodObjectLiteralArgs.ts index 5c0698ad653..9d339c50fae 100644 --- a/tests/cases/fourslash/codeFixUndeclaredMethodObjectLiteralArgs.ts +++ b/tests/cases/fourslash/codeFixUndeclaredMethodObjectLiteralArgs.ts @@ -1,11 +1,12 @@ /// -//// class A {[| -//// |]constructor() { +//// class A { +//// constructor() { //// this.foo1(null, {}, { a: 1, b: "2"}); //// const bar = this.foo2(null, {}, { a: 1, b: "2"}); //// const baz: number = this.foo3(null, {}, { a: 1, b: "2"}); -//// } +//// }[| +//// |] //// } verify.codeFix({ diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_all_prefix.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_all_prefix.ts index f77fef6510f..4eb7137d365 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_all_prefix.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_all_prefix.ts @@ -3,6 +3,10 @@ // @noUnusedLocals: true // @noUnusedParameters: true +/////** +//// * @param a First parameter. +//// * @param b Second parameter. +//// */ ////function f(a, b) { //// const x = 0; // Can't be prefixed, ignored ////} @@ -12,7 +16,11 @@ verify.codeFixAll({ fixId: "unusedIdentifier_prefix", fixAllDescription: "Prefix all unused declarations with '_' where possible", newFileContent: -`function f(_a, _b) { +`/** + * @param _a First parameter. + * @param _b Second parameter. + */ +function f(_a, _b) { const x = 0; // Can't be prefixed, ignored } type Length = T extends ArrayLike ? number : never;`, diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_prefix.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_prefix.ts new file mode 100644 index 00000000000..80b2b9bb75c --- /dev/null +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_prefix.ts @@ -0,0 +1,25 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true + +/////** +//// * @param a +//// * @param b +//// */ +////function f(a, b) { +//// const x = a; +////} + +verify.codeFix({ + description: "Prefix 'b' with an underscore", + index: 1, + newFileContent: +`/** + * @param a + * @param _b + */ +function f(a, _b) { + const x = a; +}`, +}); diff --git a/tests/cases/fourslash/codeFixWrapJsxInFragment.ts b/tests/cases/fourslash/codeFixWrapJsxInFragment.ts new file mode 100644 index 00000000000..10acf5916b7 --- /dev/null +++ b/tests/cases/fourslash/codeFixWrapJsxInFragment.ts @@ -0,0 +1,7 @@ +/// + +// @jsx: react +// @Filename: /a.tsx +////[||] + +verify.rangeAfterCodeFix(`<>`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 0); diff --git a/tests/cases/fourslash/codeFixWrapJsxInFragment2.ts b/tests/cases/fourslash/codeFixWrapJsxInFragment2.ts new file mode 100644 index 00000000000..229f554c801 --- /dev/null +++ b/tests/cases/fourslash/codeFixWrapJsxInFragment2.ts @@ -0,0 +1,7 @@ +/// + +// @jsx: react +// @Filename: /a.tsx +////[||] + +verify.rangeAfterCodeFix(`<>`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 0); diff --git a/tests/cases/fourslash/commentsClassMembers.ts b/tests/cases/fourslash/commentsClassMembers.ts index 4457dc617cd..718b9e7816e 100644 --- a/tests/cases/fourslash/commentsClassMembers.ts +++ b/tests/cases/fourslash/commentsClassMembers.ts @@ -248,22 +248,22 @@ verify.quickInfos({ 1: ["class c1", "This is comment for c1"], 2: ["(property) c1.p1: number", "p1 is property of c1"], 3: ["(method) c1.p2(b: number): number", "sum with property"], - 6: ["(property) c1.p3: number", "getter property 1\nsetter property 1"], + 6: ["(property) c1.p3: number", "getter property 1"], "8q": ["(method) c1.p2(b: number): number", "sum with property"], - 10: ["(property) c1.p3: number", "getter property 1\nsetter property 1"], + 10: ["(property) c1.p3: number", "setter property 1"], "13q": ["(method) c1.p2(b: number): number", "sum with property"], 14: ["(property) c1.pp1: number", "pp1 is property of c1"], 15: ["(method) c1.pp2(b: number): number", "sum with property"], - 18: ["(property) c1.pp3: number", "getter property 2\nsetter property 2"], + 18: ["(property) c1.pp3: number", "getter property 2"], "20q": ["(method) c1.pp2(b: number): number", "sum with property"], - 22: ["(property) c1.pp3: number", "getter property 2\nsetter property 2"], + 22: ["(property) c1.pp3: number", "setter property 2"], "25q": ["(method) c1.pp2(b: number): number", "sum with property"], 26: ["constructor c1(): c1", "Constructor method"], 27: ["(property) c1.s1: number", "s1 is static property of c1"], 28: ["(method) c1.s2(b: number): number", "static sum with property"], - 32: ["(property) c1.s3: number", "static getter property\nsetter property 3"], + 32: ["(property) c1.s3: number", "static getter property"], "35q": ["(method) c1.s2(b: number): number", "static sum with property"], - 37: ["(property) c1.s3: number", "static getter property\nsetter property 3"], + 37: ["(property) c1.s3: number", "setter property 3"], "42q": ["(method) c1.s2(b: number): number", "static sum with property"], 43: "(property) c1.nc_p1: number", 44: "(method) c1.nc_p2(b: number): number", diff --git a/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment1.ts b/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment1.ts index a913a4d5e65..5d79b9ad973 100644 --- a/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment1.ts +++ b/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment1.ts @@ -8,10 +8,14 @@ //// let files: Configfiles; //// files = { //// /*0*/: '', -//// '/*1*/': '' +//// '[|/*1*/|]': '' //// } +const replacementSpan = test.ranges()[0] verify.completions( { marker: "0", exact: ["jspm", '"jspm:browser"'] }, - { marker: "1", exact: ["jspm", "jspm:browser"] }, + { marker: "1", exact: [ + { name: "jspm", replacementSpan }, + { name: "jspm:browser", replacementSpan } + ] }, ); diff --git a/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment2.ts b/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment2.ts index 1f779908ca1..3d05e3f3a5e 100644 --- a/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment2.ts +++ b/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment2.ts @@ -13,11 +13,15 @@ //// config = { //// files: { //// /*0*/: '', -//// '/*1*/': '' +//// '[|/*1*/|]': '' //// } //// } +const replacementSpan = test.ranges()[0] verify.completions( { marker: "0", exact: ["jspm", '"jspm:browser"'] }, - { marker: "1", exact: ["jspm", "jspm:browser"] }, + { marker: "1", exact: [ + { name: "jspm", replacementSpan }, + { name: "jspm:browser", replacementSpan } + ] }, ); diff --git a/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment3.ts b/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment3.ts index fe8818e7831..0aa2491d2a9 100644 --- a/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment3.ts +++ b/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment3.ts @@ -12,10 +12,14 @@ //// 'jspm:browser': string; //// } = { //// jspm: "", -//// '/*1*/': "" +//// '[|/*1*/|]': "" //// } +const replacementSpan = test.ranges()[0] verify.completions( { marker: "0", exact: ["jspm", '"jspm:browser"'] }, - { marker: "1", exact: ["jspm", "jspm:browser"] }, + { marker: "1", exact: [ + { name: "jspm", replacementSpan }, + { name: "jspm:browser", replacementSpan } + ] } ); diff --git a/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment4.ts b/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment4.ts index ff654b57f16..eafc35e3ae4 100644 --- a/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment4.ts +++ b/tests/cases/fourslash/completionForQuotedPropertyInPropertyAssignment4.ts @@ -8,11 +8,14 @@ //// function foo(c: ConfigFiles) {} //// foo({ //// j/*0*/: "", -//// "/*1*/": "", +//// "[|/*1*/|]": "", //// }) - +const replacementSpan = test.ranges()[0] verify.completions( { marker: "0", exact: ["jspm", '"jspm:browser"'] }, - { marker: "1", exact: ["jspm", "jspm:browser"] }, + { marker: "1", exact: [ + { name: "jspm", replacementSpan }, + { name: "jspm:browser", replacementSpan } + ] } ); diff --git a/tests/cases/fourslash/completionForStringLiteral.ts b/tests/cases/fourslash/completionForStringLiteral.ts index 66fd26f26dd..8581635f3ab 100644 --- a/tests/cases/fourslash/completionForStringLiteral.ts +++ b/tests/cases/fourslash/completionForStringLiteral.ts @@ -1,9 +1,20 @@ /// ////type Options = "Option 1" | "Option 2" | "Option 3"; -////var x: Options = "/*1*/Option 3"; +////var x: Options = "[|/*1*/Option 3|]"; //// ////function f(a: Options) { }; ////f("/*2*/ -verify.completions({ marker: ["1", "2"], exact: ["Option 1", "Option 2", "Option 3"] }); +verify.completions( + { marker: "1", exact: [ + { name: "Option 1", replacementSpan: test.ranges()[0] }, + { name: "Option 2", replacementSpan: test.ranges()[0] }, + { name: "Option 3", replacementSpan: test.ranges()[0] } + ] }, + { marker: "2", exact: [ + { name: "Option 1", replacementSpan: test.ranges()[1] }, + { name: "Option 2", replacementSpan: test.ranges()[1] }, + { name: "Option 3", replacementSpan: test.ranges()[1] } + ] } +); diff --git a/tests/cases/fourslash/completionForStringLiteral10.ts b/tests/cases/fourslash/completionForStringLiteral10.ts index 0da078af6d8..3e6ddd3f1da 100644 --- a/tests/cases/fourslash/completionForStringLiteral10.ts +++ b/tests/cases/fourslash/completionForStringLiteral10.ts @@ -2,6 +2,9 @@ ////type As = 'arf' | 'abacus' | 'abaddon'; ////let a: As; -////if ('/**/' != a +////if ('[|/**/|]' != a -verify.completions({ marker: "", exact: ["arf", "abacus", "abaddon"] }); +verify.completions({ marker: "", exact: ["arf", "abacus", "abaddon"].map(name => ({ + name, + replacementSpan: test.ranges()[0] +})) }); diff --git a/tests/cases/fourslash/completionForStringLiteral11.ts b/tests/cases/fourslash/completionForStringLiteral11.ts index c0edc8e2a61..289a2617f2f 100644 --- a/tests/cases/fourslash/completionForStringLiteral11.ts +++ b/tests/cases/fourslash/completionForStringLiteral11.ts @@ -3,7 +3,7 @@ ////type As = 'arf' | 'abacus' | 'abaddon'; ////let a: As; ////switch (a) { -//// case '/**/ +//// case '[|/**/|] ////} verify.completions({ marker: "", exact: ["arf", "abacus", "abaddon" ] }); diff --git a/tests/cases/fourslash/completionForStringLiteral12.ts b/tests/cases/fourslash/completionForStringLiteral12.ts index a8ccfb08402..0d241306dab 100644 --- a/tests/cases/fourslash/completionForStringLiteral12.ts +++ b/tests/cases/fourslash/completionForStringLiteral12.ts @@ -3,6 +3,9 @@ ////function foo(x: "bla"): void; ////function foo(x: "bla"): void; ////function foo(x: string) {} -////foo("/**/") +////foo("[|/**/|]") -verify.completions({ marker: "", exact: "bla" }); +verify.completions({ marker: "", exact: { + name: "bla", + replacementSpan: test.ranges()[0] +} }); diff --git a/tests/cases/fourslash/completionForStringLiteral14.ts b/tests/cases/fourslash/completionForStringLiteral14.ts new file mode 100644 index 00000000000..b1a28df23ef --- /dev/null +++ b/tests/cases/fourslash/completionForStringLiteral14.ts @@ -0,0 +1,18 @@ +/// + +////interface Foo { +//// a: string; +//// b: boolean; +//// c: number; +////} +////type Bar = Record["[|/**/|]"]; + +const replacementSpan = test.ranges()[0] +verify.completions({ + marker: "", + exact: [ + { name: "a", replacementSpan }, + { name: "b", replacementSpan }, + { name: "c", replacementSpan } + ] +}); diff --git a/tests/cases/fourslash/completionForStringLiteral15.ts b/tests/cases/fourslash/completionForStringLiteral15.ts new file mode 100644 index 00000000000..3736e5e5b78 --- /dev/null +++ b/tests/cases/fourslash/completionForStringLiteral15.ts @@ -0,0 +1,12 @@ +/// + +////let x: { [_ in "foo"]: string } = { +//// "[|/**/|]" +////} + +verify.completions({ + marker: "", + exact: [ + { name: "foo", replacementSpan: test.ranges()[0] } + ] +}); diff --git a/tests/cases/fourslash/completionForStringLiteral2.ts b/tests/cases/fourslash/completionForStringLiteral2.ts index d6b71594d88..e5753e72960 100644 --- a/tests/cases/fourslash/completionForStringLiteral2.ts +++ b/tests/cases/fourslash/completionForStringLiteral2.ts @@ -7,11 +7,22 @@ ////}; ////declare const p: { [s: string]: any, a: number }; //// -////o["/*1*/bar"]; +////o["[|/*1*/bar|]"]; ////o["/*2*/ ; -////p["/*3*/"]; +////p["[|/*3*/|]"]; + +const replacementSpan0 = test.ranges()[0] verify.completions( - { marker: ["1", "2"], exact: ["foo", "bar", "some other name"] }, - { marker: "3", exact: "a", isNewIdentifierLocation: true }, + { marker: "1", exact: [ + { name: "foo", replacementSpan: replacementSpan0 }, + { name: "bar", replacementSpan: replacementSpan0 }, + { name: "some other name", replacementSpan: replacementSpan0 } + ] }, + { marker: "2", exact: [ "foo", "bar", "some other name" ] }, + { marker: "3", exact: { + name: "a", + replacementSpan: test.ranges()[1] + }, + isNewIdentifierLocation: true }, ); diff --git a/tests/cases/fourslash/completionForStringLiteral3.ts b/tests/cases/fourslash/completionForStringLiteral3.ts index 9ebcec52593..40ea9277b05 100644 --- a/tests/cases/fourslash/completionForStringLiteral3.ts +++ b/tests/cases/fourslash/completionForStringLiteral3.ts @@ -5,8 +5,14 @@ ////declare function f(a: "C", b: number): void; ////declare function f(a: string, b: number): void; //// -////f("/*1*/C", 2); +////f("[|/*1*/C|]", 2); //// ////f("/*2*/ -verify.completions({ marker: ["1", "2"], exact: ["A", "B", "C"], isNewIdentifierLocation: true }); +verify.completions({ marker: "1", exact: [ + { name: "A", replacementSpan: test.ranges()[0] }, + { name: "B", replacementSpan: test.ranges()[0] }, + { name: "C", replacementSpan: test.ranges()[0] } +], isNewIdentifierLocation: true }); + +verify.completions({ marker: "2", exact: [ "A", "B", "C"], isNewIdentifierLocation: true }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionForStringLiteral4.ts b/tests/cases/fourslash/completionForStringLiteral4.ts index d05e353fd23..605b3b3891d 100644 --- a/tests/cases/fourslash/completionForStringLiteral4.ts +++ b/tests/cases/fourslash/completionForStringLiteral4.ts @@ -11,10 +11,14 @@ ////function f(p1, p2, p3, p4, p5) { //// return p1 + p2 + p3 + p4 + p5 + '.'; ////} -////f/*1*/('literal', 'literal', "o/*2*/ther1", 12); +////f/*1*/('literal', 'literal', "[|o/*2*/ther1|]", 12); goTo.marker('1'); verify.quickInfoExists(); -verify.quickInfoIs('function f(p1: "literal", p2: "literal", p3: "other1" | "other2", p4: number | "literal", p5: true | 12): string', 'I am documentation'); +verify.quickInfoIs('function f(p1: \'literal\', p2: "literal", p3: \'other1\' | \'other2\', p4: \'literal\' | number, p5: 12 | true): string', 'I am documentation'); -verify.completions({ marker: "2", exact: ["other1", "other2"] }); +const replacementSpan = test.ranges()[0] +verify.completions({ marker: "2", exact: [ + { name: "other1", replacementSpan }, + { name: "other2", replacementSpan } +] }); diff --git a/tests/cases/fourslash/completionForStringLiteral6.ts b/tests/cases/fourslash/completionForStringLiteral6.ts index df08f56aa9a..86b949cef32 100644 --- a/tests/cases/fourslash/completionForStringLiteral6.ts +++ b/tests/cases/fourslash/completionForStringLiteral6.ts @@ -4,6 +4,9 @@ //// x: "abc" | "def"; ////} ////function bar(f: Foo) { }; -////bar({x: "/**/"}); +////bar({x: "[|/**/|]"}); -verify.completions({ marker: "", exact: ["abc", "def"] }); +verify.completions({ marker: "", exact: ["abc", "def"].map(name => ({ + name, + replacementSpan: test.ranges()[0] +})) }); diff --git a/tests/cases/fourslash/completionForStringLiteral7.ts b/tests/cases/fourslash/completionForStringLiteral7.ts index 13cf2814c86..3b8bde1a876 100644 --- a/tests/cases/fourslash/completionForStringLiteral7.ts +++ b/tests/cases/fourslash/completionForStringLiteral7.ts @@ -3,9 +3,16 @@ ////type T = "foo" | "bar"; ////type U = "oof" | "rab"; ////function f(x: T, ...args: U[]) { }; -////f("/*1*/", "/*2*/", "/*3*/"); +////f("[|/*1*/|]", "[|/*2*/|]", "[|/*3*/|]"); verify.completions( - { marker: "1", exact: ["foo", "bar"] }, - { marker: ["2", "3"], exact: ["oof", "rab"] }, + { marker: "1", exact: ["foo", "bar"].map(name => ({ + name, replacementSpan: test.ranges()[0] + })) }, + { marker: "2", exact: ["oof", "rab"].map(name => ({ + name, replacementSpan: test.ranges()[1] + })) }, + { marker: "3", exact: ["oof", "rab"].map(name => ({ + name, replacementSpan: test.ranges()[2] + })) }, ); diff --git a/tests/cases/fourslash/completionForStringLiteralFromSignature.ts b/tests/cases/fourslash/completionForStringLiteralFromSignature.ts index b9e96c7603b..81cd25beb0c 100644 --- a/tests/cases/fourslash/completionForStringLiteralFromSignature.ts +++ b/tests/cases/fourslash/completionForStringLiteralFromSignature.ts @@ -2,6 +2,9 @@ ////declare function f(a: "x"): void; ////declare function f(a: string): void; -////f("/**/"); +////f("[|/**/|]"); -verify.completions({ marker: "", exact: "x", isNewIdentifierLocation: true }); +verify.completions({ marker: "", exact: { + name: "x", + replacementSpan: test.ranges()[0] +}, isNewIdentifierLocation: true }); diff --git a/tests/cases/fourslash/completionForStringLiteralInIndexedAccess01.ts b/tests/cases/fourslash/completionForStringLiteralInIndexedAccess01.ts index 14f11ba227e..90f6e03cc0c 100644 --- a/tests/cases/fourslash/completionForStringLiteralInIndexedAccess01.ts +++ b/tests/cases/fourslash/completionForStringLiteralInIndexedAccess01.ts @@ -5,6 +5,10 @@ //// bar: string; ////} //// -////let x: Foo["/*1*/"] +////let x: Foo["[|/*1*/|]"] -verify.completions({ marker: "1", exact: ["foo", "bar"] }); +const replacementSpan = test.ranges()[0] +verify.completions({ marker: "1", exact: [ + { name: "foo", replacementSpan }, + { name: "bar", replacementSpan } +] }); diff --git a/tests/cases/fourslash/completionForStringLiteral_details.ts b/tests/cases/fourslash/completionForStringLiteral_details.ts index 8c6e4d36481..e4521cbeadd 100644 --- a/tests/cases/fourslash/completionForStringLiteral_details.ts +++ b/tests/cases/fourslash/completionForStringLiteral_details.ts @@ -6,7 +6,7 @@ // @Filename: /a.ts ////import {} from ".//*path*/"; //// -////const x: "a" = "/*type*/"; +////const x: "a" = "[|/*type*/|]"; //// ////interface I { //// /** Prop doc */ @@ -15,16 +15,16 @@ //// m(): void; ////} ////declare const o: I; -////o["/*prop*/"]; +////o["[|/*prop*/|]"]; verify.completions( { marker: "path", includes: { name: "other", text: "other", kind: "script", kindModifiers: ".ts" }, isNewIdentifierLocation: true }, - { marker: "type", exact: { name: "a", text: "a", kind: "string" } }, + { marker: "type", exact: { name: "a", text: "a", kind: "string", replacementSpan: test.ranges()[0] } }, { marker: "prop", exact: [ - { name: "x", text: "(property) I.x: number", documentation: "Prop doc", kind: "property" }, - { name: "m", text: "(method) I.m(): void", documentation: "Method doc", kind: "method" }, + { name: "x", text: "(property) I.x: number", documentation: "Prop doc", kind: "property", replacementSpan: test.ranges()[1] }, + { name: "m", text: "(method) I.m(): void", documentation: "Method doc", kind: "method", replacementSpan: test.ranges()[1] }, ], }, ); diff --git a/tests/cases/fourslash/completionForStringLiteral_mappedTypeMembers.ts b/tests/cases/fourslash/completionForStringLiteral_mappedTypeMembers.ts new file mode 100644 index 00000000000..0822cf9eafa --- /dev/null +++ b/tests/cases/fourslash/completionForStringLiteral_mappedTypeMembers.ts @@ -0,0 +1,18 @@ +/// + +////type Foo = { +//// a: string; +//// b: string; +////}; +//// +////type A = Readonly; +////type B = A["[|/**/|]"] + +const replacementSpan = test.ranges()[0]; +verify.completions({ + marker: "", + exact: [ + { name: "a", replacementSpan }, + { name: "b", replacementSpan } + ] +}); diff --git a/tests/cases/fourslash/completionInfoWithExplicitTypeArguments.ts b/tests/cases/fourslash/completionInfoWithExplicitTypeArguments.ts index 3fc5052fcff..46e9b6a692d 100644 --- a/tests/cases/fourslash/completionInfoWithExplicitTypeArguments.ts +++ b/tests/cases/fourslash/completionInfoWithExplicitTypeArguments.ts @@ -9,6 +9,14 @@ ////f({ /*f*/ }); //// ////declare function g(x: keyof T, y: number): void; -////g("/*g*/"); +////g("[|/*g*/|]"); -verify.completions({ marker: test.markers(), exact: ["x", "y"] }); +verify.completions({ marker: "f", exact: [ + { name: "x" }, + { name: "y" }, +] }); + +verify.completions({ marker: "g", exact: [ + { name: "x", replacementSpan: test.ranges()[0] }, + { name: "y", replacementSpan: test.ranges()[0] }, +] }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListAfterStringLiteralTypeWithNoSubstitutionTemplateLiteral.ts b/tests/cases/fourslash/completionListAfterStringLiteralTypeWithNoSubstitutionTemplateLiteral.ts index d44b1d04bbe..46782406969 100644 --- a/tests/cases/fourslash/completionListAfterStringLiteralTypeWithNoSubstitutionTemplateLiteral.ts +++ b/tests/cases/fourslash/completionListAfterStringLiteralTypeWithNoSubstitutionTemplateLiteral.ts @@ -1,6 +1,10 @@ /// ////let count: 'one' | 'two'; -////count = `/**/` +////count = `[|/**/|]` -verify.completions({ marker: "", exact: ["one", "two"] }); +const replacementSpan = test.ranges()[0] +verify.completions({ marker: "", exact: [ + { name: "one", replacementSpan }, + { name: "two", replacementSpan } +] }); diff --git a/tests/cases/fourslash/completionListClassPrivateFields.ts b/tests/cases/fourslash/completionListClassPrivateFields.ts new file mode 100644 index 00000000000..f7638047a67 --- /dev/null +++ b/tests/cases/fourslash/completionListClassPrivateFields.ts @@ -0,0 +1,15 @@ +/// + +////class A { +//// #private = 1; +////} +//// +////class B extends A { +//// /**/ +////} + +verify.completions({ + marker: "", + exact: completion.classElementKeywords, + isNewIdentifierLocation: true +}); diff --git a/tests/cases/fourslash/completionListClassPrivateFields_JS.ts b/tests/cases/fourslash/completionListClassPrivateFields_JS.ts new file mode 100644 index 00000000000..49c8d05af6a --- /dev/null +++ b/tests/cases/fourslash/completionListClassPrivateFields_JS.ts @@ -0,0 +1,21 @@ +/// + +// @allowJs: true +// @Filename: a.js +////class A { +//// #private = 1; +////} +//// +////class B extends A { +//// /**/ +////} + +verify.completions({ + marker: "", + exact: [ + { name: "A", sortText: completion.SortText.JavascriptIdentifiers }, + { name: "B", sortText: completion.SortText.JavascriptIdentifiers }, + ...completion.classElementInJsKeywords + ], + isNewIdentifierLocation: true +}); diff --git a/tests/cases/fourslash/completionListForStringUnion.ts b/tests/cases/fourslash/completionListForStringUnion.ts index 98755ea1e41..5a93ea63329 100644 --- a/tests/cases/fourslash/completionListForStringUnion.ts +++ b/tests/cases/fourslash/completionListForStringUnion.ts @@ -2,10 +2,24 @@ //// type A = 'foo' | 'bar' | 'baz'; //// type B = {}; -//// type C = B<'foo' | '/**/'> +//// type C = B<'foo' | '[|/**/|]'> -verify.completions({ marker: "", exact: ["bar", "baz"] }); +const replacementSpan = test.ranges()[0] +verify.completions({ marker: "", exact: [ + { name: "bar", replacementSpan }, + { name: "baz", replacementSpan } +] }); edit.insert("b"); -verify.completions({ exact: ["bar", "baz"] }); +replacementSpan.end++ + +verify.completions({ exact: [ + { name: "bar", replacementSpan }, + { name: "baz", replacementSpan } +] }); edit.insert("ar"); -verify.completions({ exact: ["bar", "baz"] }); +replacementSpan.end += 2 + +verify.completions({ exact: [ + { name: "bar", replacementSpan }, + { name: "baz", replacementSpan } +] }); diff --git a/tests/cases/fourslash/completionListInvalidMemberNames.ts b/tests/cases/fourslash/completionListInvalidMemberNames.ts index 6cfddbdfa28..07dc47be830 100644 --- a/tests/cases/fourslash/completionListInvalidMemberNames.ts +++ b/tests/cases/fourslash/completionListInvalidMemberNames.ts @@ -12,11 +12,21 @@ ////}; //// ////x[|./*a*/|]; -////x["/*b*/"]; +////x["[|/*b*/|]"]; const replacementSpan = test.ranges()[0]; +const replacementSpan1 = test.ranges()[1]; verify.completions( - { marker: "b", exact: ["foo ", "bar", "break", "any", "#", "$", "b", "1b"] }, + { marker: "b", exact: [ + { name: "foo ", replacementSpan: replacementSpan1 }, + { name: "bar", replacementSpan: replacementSpan1 }, + { name: "break", replacementSpan: replacementSpan1 }, + { name: "any", replacementSpan: replacementSpan1 }, + { name: "#", replacementSpan: replacementSpan1 }, + { name: "$", replacementSpan: replacementSpan1 }, + { name: "b", replacementSpan: replacementSpan1 }, + { name: "1b", replacementSpan: replacementSpan1 }, + ] }, { marker: "a", exact: [ diff --git a/tests/cases/fourslash/completionsClassPropertiesAssignment.ts b/tests/cases/fourslash/completionsClassPropertiesAssignment.ts index a3be4038c36..cb9aa111df0 100644 --- a/tests/cases/fourslash/completionsClassPropertiesAssignment.ts +++ b/tests/cases/fourslash/completionsClassPropertiesAssignment.ts @@ -1,29 +1,32 @@ /// ////class Class1 { -//// protected a = /*1*/ -//// private b = /*2*/ -//// public c = /*3*/ -//// public d = this./*4*/ +//// public a = this./*0*/ +//// protected b = /*1*/ +//// private c = /*2*/ +//// public d = /*3*/ ////} //// ////class Class2 { -//// a = /*5*/ +//// a = /*4*/ ////} ////class Class3 { -//// a = /*6*/ +//// a = /*5*/ ////} //// ////const prop = 'prop'; ////class Class4 { -//// [prop] = /*7*/ +//// [prop] = /*6*/ ////} const exact = completion.globalsPlus(["Class1", "Class2", "Class3", "prop", "Class4"]); -verify.completions({ marker: ["1"], exact }); -verify.completions({ marker: ["2"], exact }); -verify.completions({ marker: ["3"], exact }); -verify.completions({ marker: ["4"], exact: ['a', 'b', 'c', 'd'], isGlobalCompletion: false }); -verify.completions({ marker: ["5"], exact }); -verify.completions({ marker: ["6"], exact }); -verify.completions({ marker: ["7"], exact }); +const markers = ["1", "2", "3", "4", "5", "6"]; + +verify.completions({ marker: "0", exact: ['a', 'b', 'c', 'd'], isGlobalCompletion: false }); +verify.completions({ marker: markers, exact }); + +for (let marker of markers) { + goTo.marker(marker); + edit.insert("c"); + verify.completions({ exact }); +} diff --git a/tests/cases/fourslash/completionsElementAccessNumeric.ts b/tests/cases/fourslash/completionsElementAccessNumeric.ts new file mode 100644 index 00000000000..dbb330a7ae9 --- /dev/null +++ b/tests/cases/fourslash/completionsElementAccessNumeric.ts @@ -0,0 +1,30 @@ +/// + +// @target: esnext + +////type Tup = [ +//// /** +//// * The first label +//// */ +//// lbl1: number, +//// /** +//// * The second label +//// */ +//// lbl2: number +////]; +////declare var x: Tup; +////x[|./**/|] + +const replacementSpan = test.ranges()[0]; +verify.completions( + { + marker: "", + includes: [ + {name: "0", insertText: "[0]", replacementSpan, documentation: "The first label", text: "(property) 0: number (lbl1)" }, + {name: "1", insertText: "[1]", replacementSpan, documentation: "The second label", text: "(property) 1: number (lbl2)" }, + ], + preferences: { + includeInsertTextCompletions: true, + }, + }, +); diff --git a/tests/cases/fourslash/completionsImportModuleAugmentationWithJS.ts b/tests/cases/fourslash/completionsImportModuleAugmentationWithJS.ts new file mode 100644 index 00000000000..8ea84247d84 --- /dev/null +++ b/tests/cases/fourslash/completionsImportModuleAugmentationWithJS.ts @@ -0,0 +1,41 @@ +// #37833 + +/// + +// @allowJs: true +// @checkJs: true +// @noEmit: true + +// @Filename: /test.js +////class Abcde { +//// x +////} +//// +////module.exports = { +//// Abcde +////}; + +// @Filename: /index.ts +////export {}; +////declare module "./test" { +//// interface Abcde { b: string } +////} +//// +////Abcde/**/ + +verify.applyCodeActionFromCompletion("", { + name: "Abcde", + source: "/test", + description: `Import 'Abcde' from module "./test"`, + newFileContent: `import { Abcde } from "./test"; + +export {}; +declare module "./test" { + interface Abcde { b: string } +} + +Abcde`, + preferences: { + includeCompletionsForModuleExports: true + } +}); diff --git a/tests/cases/fourslash/completionsJsPropertyAssignment.ts b/tests/cases/fourslash/completionsJsPropertyAssignment.ts index 77fade15b76..afa1284d28f 100644 --- a/tests/cases/fourslash/completionsJsPropertyAssignment.ts +++ b/tests/cases/fourslash/completionsJsPropertyAssignment.ts @@ -5,6 +5,9 @@ // @Filename: /a.js /////** @type {{ p: "x" | "y" }} */ ////const x = { p: "x" }; -////x.p = "/**/"; +////x.p = "[|/**/|]"; -verify.completions({ marker: "", exact: ["x", "y"] }); +verify.completions({ marker: "", exact: [ + { name: "x", replacementSpan: test.ranges()[0] }, + { name: "y", replacementSpan: test.ranges()[0] } +] }); diff --git a/tests/cases/fourslash/completionsKeyof.ts b/tests/cases/fourslash/completionsKeyof.ts index 3f743ed604d..7b836f204fd 100644 --- a/tests/cases/fourslash/completionsKeyof.ts +++ b/tests/cases/fourslash/completionsKeyof.ts @@ -3,11 +3,23 @@ ////interface A { a: number; }; ////interface B { a: number; b: number; }; ////function f(key: T) {} -////f("/*f*/"); +////f("[|/*f*/|]"); ////function g(key: T) {} -////g("/*g*/"); +////g("[|/*g*/|]"); verify.completions( - { marker: "f", exact: "a" }, - { marker: "g", exact: ["a", "b"] }, + { + marker: "f", + exact: [ + { name: "a", replacementSpan: test.ranges()[0] } + ] + }, + { + marker: "g", + exact: [ + { name: "a", replacementSpan: test.ranges()[1] }, + { name: "b", replacementSpan: test.ranges()[1] }, + + ] + }, ); diff --git a/tests/cases/fourslash/completionsPrivateProperties_Js.ts b/tests/cases/fourslash/completionsPrivateProperties_Js.ts new file mode 100644 index 00000000000..cd11b37af95 --- /dev/null +++ b/tests/cases/fourslash/completionsPrivateProperties_Js.ts @@ -0,0 +1,20 @@ +/// + +// @allowJs: true +// @Filename: a.d.ts +////declare namespace A { +//// class Foo { +//// constructor(); +//// +//// private m1(): void; +//// protected m2(): void; +//// +//// m3(): void; +//// } +////} + +// @filename: b.js +////let foo = new A.Foo(); +////foo./**/ + +verify.completions({ marker: [""], includes: ["m3"], excludes: ["m1", "m2"] }); diff --git a/tests/cases/fourslash/completionsStringLiteral_fromTypeConstraint.ts b/tests/cases/fourslash/completionsStringLiteral_fromTypeConstraint.ts index e29b2b7268f..44e134915a2 100644 --- a/tests/cases/fourslash/completionsStringLiteral_fromTypeConstraint.ts +++ b/tests/cases/fourslash/completionsStringLiteral_fromTypeConstraint.ts @@ -1,6 +1,9 @@ /// ////interface Foo { foo: string; bar: string; } -////type T = Pick; +////type T = Pick; -verify.completions({ marker: "", exact: ["foo", "bar"] }); +verify.completions({ marker: "", exact: [ + { name: "foo", replacementSpan: test.ranges()[0] }, + { name: "bar", replacementSpan: test.ranges()[0] } +] }); diff --git a/tests/cases/fourslash/completionsStringsWithTriggerCharacter.ts b/tests/cases/fourslash/completionsStringsWithTriggerCharacter.ts index 277218305f4..89d13efafad 100644 --- a/tests/cases/fourslash/completionsStringsWithTriggerCharacter.ts +++ b/tests/cases/fourslash/completionsStringsWithTriggerCharacter.ts @@ -1,30 +1,51 @@ /// //// type A = "a/b" | "b/a"; -//// const a: A = "a/*1*/"; +//// const a: A = "[|a/*1*/|]"; //// //// type B = "a@b" | "b@a"; -//// const a: B = "a@/*2*/"; +//// const a: B = "[|a@/*2*/|]"; //// //// type C = "a.b" | "b.a"; -//// const c: C = "a./*3*/"; +//// const c: C = "[|a./*3*/|]"; //// //// type D = "a'b" | "b'a"; -//// const d: D = "a'/*4*/"; +//// const d: D = "[|a'/*4*/|]"; //// //// type E = "a`b" | "b`a"; -//// const e: E = "a`/*5*/"; +//// const e: E = "[|a`/*5*/|]"; //// //// type F = 'a"b' | 'b"a'; -//// const f: F = 'a"/*6*/'; +//// const f: F = '[|a"/*6*/|]'; //// //// type G = "a(obj: T, key: K): T[K]; -//// get({ hello: 123, world: 456 }, "/**/"); +//// get({ hello: 123, world: 456 }, "[|/**/|]"); verify.completions({ marker: "", - includes: ['hello', 'world'] + includes: [ + { name: 'hello', replacementSpan: test.ranges()[0] }, + { name: 'world', replacementSpan: test.ranges()[0] } + ] }); - diff --git a/tests/cases/fourslash/completionsWithStringReplacementMode.ts b/tests/cases/fourslash/completionsWithStringReplacementMode.ts new file mode 100644 index 00000000000..2ff01d4abea --- /dev/null +++ b/tests/cases/fourslash/completionsWithStringReplacementMode.ts @@ -0,0 +1,16 @@ +/// + +////interface Foo { foo: string; bar: string; } +////type T = Pick; +////type TT = Pick; +////type TTT = Pick; + +for (let i = 0 ; i < 3; ++i) { + verify.completions({ + marker: `${i + 1}`, + exact: [ + { name: "foo", replacementSpan: test.ranges()[i] }, + { name: "bar", replacementSpan: test.ranges()[i] }, + ] + }); +} \ No newline at end of file diff --git a/tests/cases/fourslash/completionsWithStringReplacementMode1.ts b/tests/cases/fourslash/completionsWithStringReplacementMode1.ts new file mode 100644 index 00000000000..1b4dd96e380 --- /dev/null +++ b/tests/cases/fourslash/completionsWithStringReplacementMode1.ts @@ -0,0 +1,44 @@ +/// + +//// interface TFunction { +//// (_: 'login.title', __?: {}): string; +//// (_: 'login.description', __?: {}): string; +//// (_: 'login.sendEmailAgree', __?: {}): string; +//// (_: 'login.termsOfUse', __?: {}): string; +//// (_: 'login.privacyPolicy', __?: {}): string; +//// (_: 'login.sendEmailButton', __?: {}): string; +//// (_: 'login.emailInputPlaceholder', __?: {}): string; +//// (_: 'login.errorWrongEmailTitle', __?: {}): string; +//// (_: 'login.errorWrongEmailDescription', __?: {}): string; +//// (_: 'login.errorGeneralEmailTitle', __?: {}): string; +//// (_: 'login.errorGeneralEmailDescription', __?: {}): string; +//// (_: 'login.loginErrorTitle', __?: {}): string; +//// (_: 'login.loginErrorDescription', __?: {}): string; +//// (_: 'login.openEmailAppErrorTitle', __?: {}): string; +//// (_: 'login.openEmailAppErrorDescription', __?: {}): string; +//// (_: 'login.openEmailAppErrorConfirm', __?: {}): string; +//// } +//// const f: TFunction = (() => {}) as any; +//// f('[|login./**/|]') + +verify.completions({ + marker: "", + exact: [ + { name: "login.title", replacementSpan: test.ranges()[0] }, + { name: "login.description", replacementSpan: test.ranges()[0] }, + { name: "login.sendEmailAgree", replacementSpan: test.ranges()[0] }, + { name: "login.termsOfUse", replacementSpan: test.ranges()[0] }, + { name: "login.privacyPolicy", replacementSpan: test.ranges()[0] }, + { name: "login.sendEmailButton", replacementSpan: test.ranges()[0] }, + { name: "login.emailInputPlaceholder", replacementSpan: test.ranges()[0] }, + { name: "login.errorWrongEmailTitle", replacementSpan: test.ranges()[0] }, + { name: "login.errorWrongEmailDescription", replacementSpan: test.ranges()[0] }, + { name: "login.errorGeneralEmailTitle", replacementSpan: test.ranges()[0] }, + { name: "login.errorGeneralEmailDescription", replacementSpan: test.ranges()[0] }, + { name: "login.loginErrorTitle", replacementSpan: test.ranges()[0] }, + { name: "login.loginErrorDescription", replacementSpan: test.ranges()[0] }, + { name: "login.openEmailAppErrorTitle", replacementSpan: test.ranges()[0] }, + { name: "login.openEmailAppErrorDescription", replacementSpan: test.ranges()[0] }, + { name: "login.openEmailAppErrorConfirm", replacementSpan: test.ranges()[0] }, + ] +}); \ No newline at end of file diff --git a/tests/cases/fourslash/contextuallyTypedParameters.ts b/tests/cases/fourslash/contextuallyTypedParameters.ts index f600180c087..b19ec282eb6 100644 --- a/tests/cases/fourslash/contextuallyTypedParameters.ts +++ b/tests/cases/fourslash/contextuallyTypedParameters.ts @@ -40,19 +40,19 @@ verify.quickInfos({ 10: "(parameter) a: number", - 11: "(parameter) args: [string, boolean]", + 11: "(parameter) args: [y: string, z: boolean]", 20: "(parameter) a: number", 21: "(parameter) b: string", - 22: "(parameter) args: [boolean]", + 22: "(parameter) args: [z: boolean]", 30: "(parameter) a: number", 31: "(parameter) b: string", 32: "(parameter) c: boolean", 33: "(parameter) args: []", 40: "(parameter) a: number", - 41: "(parameter) args: [string, boolean]", + 41: "(parameter) args: [y: string, z: boolean]", 50: "(parameter) a: number", 51: "(parameter) b: string", - 52: "(parameter) args: [boolean]", + 52: "(parameter) args: [z: boolean]", 60: "(parameter) a: number", 61: "(parameter) b: string", 62: "(parameter) c: boolean", diff --git a/tests/cases/fourslash/convertFunctionToEs6Class-propertyMember.ts b/tests/cases/fourslash/convertFunctionToEs6Class-propertyMember.ts new file mode 100644 index 00000000000..9ee5a8ce2f0 --- /dev/null +++ b/tests/cases/fourslash/convertFunctionToEs6Class-propertyMember.ts @@ -0,0 +1,31 @@ +// @allowNonTsExtensions: true +// @Filename: test123.js + +/// + +//// // Comment +//// function /*1*/fn() { +//// this.baz = 10; +//// } +//// fn.prototype = { +//// /** JSDoc */ +//// bar: function () { +//// console.log('hello world'); +//// } +//// } + +verify.codeFix({ + description: "Convert function to an ES2015 class", + newFileContent: + `// Comment +class fn { + constructor() { + this.baz = 10; + } + /** JSDoc */ + bar() { + console.log('hello world'); + } +} +`, +}); diff --git a/tests/cases/fourslash/convertFunctionToEs6Class-prototypeAccessor.ts b/tests/cases/fourslash/convertFunctionToEs6Class-prototypeAccessor.ts new file mode 100644 index 00000000000..366147c7cc4 --- /dev/null +++ b/tests/cases/fourslash/convertFunctionToEs6Class-prototypeAccessor.ts @@ -0,0 +1,31 @@ +// @allowNonTsExtensions: true +// @Filename: test123.js + +/// + +//// // Comment +//// function /*1*/fn() { +//// this.baz = 10; +//// } +//// fn.prototype = { +//// /** JSDoc */ +//// get bar() { +//// return this.baz; +//// } +//// } + +verify.codeFix({ + description: "Convert function to an ES2015 class", + newFileContent: + `// Comment +class fn { + constructor() { + this.baz = 10; + } + /** JSDoc */ + get bar() { + return this.baz; + } +} +`, +}); diff --git a/tests/cases/fourslash/convertFunctionToEs6Class-prototypeMethod.ts b/tests/cases/fourslash/convertFunctionToEs6Class-prototypeMethod.ts new file mode 100644 index 00000000000..19f9f6dda47 --- /dev/null +++ b/tests/cases/fourslash/convertFunctionToEs6Class-prototypeMethod.ts @@ -0,0 +1,29 @@ +// @allowNonTsExtensions: true +// @Filename: test123.js + +/// + +//// // Comment +//// function /*1*/fn() { +//// this.baz = 10; +//// } +//// fn.prototype = { +//// bar() { +//// console.log('hello world'); +//// } +//// } + +verify.codeFix({ + description: "Convert function to an ES2015 class", + newFileContent: + `// Comment +class fn { + constructor() { + this.baz = 10; + } + bar() { + console.log('hello world'); + } +} +`, +}); diff --git a/tests/cases/fourslash/convertFunctionToEs6Class-removeConstructor.ts b/tests/cases/fourslash/convertFunctionToEs6Class-removeConstructor.ts new file mode 100644 index 00000000000..d1bab8377a9 --- /dev/null +++ b/tests/cases/fourslash/convertFunctionToEs6Class-removeConstructor.ts @@ -0,0 +1,24 @@ +// @allowNonTsExtensions: true +// @Filename: test123.js + +/// + +//// // Comment +//// function /*1*/fn() { +//// this.baz = 10; +//// } +//// fn.prototype = { +//// constructor: fn +//// } + +verify.codeFix({ + description: "Convert function to an ES2015 class", + newFileContent: + `// Comment +class fn { + constructor() { + this.baz = 10; + } +} +`, +}); diff --git a/tests/cases/fourslash/convertFunctionToEs6Class-removeConstructor2.ts b/tests/cases/fourslash/convertFunctionToEs6Class-removeConstructor2.ts new file mode 100644 index 00000000000..7efd37c1aa9 --- /dev/null +++ b/tests/cases/fourslash/convertFunctionToEs6Class-removeConstructor2.ts @@ -0,0 +1,22 @@ +// @allowNonTsExtensions: true +// @Filename: test123.js + +/// + +//// // Comment +//// function /*1*/fn() { +//// this.baz = 10; +//// } +//// fn.prototype.constructor = fn + +verify.codeFix({ + description: "Convert function to an ES2015 class", + newFileContent: + `// Comment +class fn { + constructor() { + this.baz = 10; + } +} +`, +}); diff --git a/tests/cases/fourslash/docCommentTemplateExportAssignmentJS.ts b/tests/cases/fourslash/docCommentTemplateExportAssignmentJS.ts new file mode 100644 index 00000000000..849227ba74b --- /dev/null +++ b/tests/cases/fourslash/docCommentTemplateExportAssignmentJS.ts @@ -0,0 +1,15 @@ +/// + +// @allowJs: true +// @checkJs: true + +// @Filename: index.js +//// /** /**/ */ +//// exports.foo = (a) => {}; + + +verify.docCommentTemplateAt("", 8, +`/** + * + * @param {any} a + */`); diff --git a/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts b/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts index b60fff2d590..8ff2f3452e5 100644 --- a/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts +++ b/tests/cases/fourslash/docCommentTemplateInSingleLineComment.ts @@ -3,7 +3,7 @@ // @Filename: justAComment.ts //// // We want to check off-by-one errors in assessing the end of the comment, so we check twice, //// // first with a trailing space and then without. -//// // /*0*/ +//// // /*0*/ //// // /*1*/ //// // We also want to check EOF handling at the end of a comment //// // /*2*/ diff --git a/tests/cases/fourslash/extract-const4.ts b/tests/cases/fourslash/extract-const4.ts new file mode 100644 index 00000000000..4130a168fdb --- /dev/null +++ b/tests/cases/fourslash/extract-const4.ts @@ -0,0 +1,21 @@ +/// + +// GH#35372 + +// @jsx: preserve +// @filename: main.tsx +////function foo() { +//// return ; +////} + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "constant_scope_0", + actionDescription: "Extract to constant in enclosing scope", + newContent: + `function foo() { + const /*RENAME*/newLocal = content; + return
{newLocal}
; +}` +}); diff --git a/tests/cases/fourslash/extract-method32.ts b/tests/cases/fourslash/extract-method32.ts new file mode 100644 index 00000000000..229561e9795 --- /dev/null +++ b/tests/cases/fourslash/extract-method32.ts @@ -0,0 +1,35 @@ +/// + +// @Filename: /a.ts +////export interface A { +//// x: number; +////} +////export const a: A = { x: 1 }; + +// @Filename: /b.ts +////import { a } from "./a"; +//// +////function foo() { +//// const arg = a; +//// /*a*/console.log(arg);/*b*/ +////} + +goTo.file("/b.ts"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to function in module scope", + newContent: +`import { a, A } from "./a"; + +function foo() { + const arg = a; + /*RENAME*/newFunction(arg); +} + +function newFunction(arg: A) { + console.log(arg); +} +` +}); diff --git a/tests/cases/fourslash/extract-method33.ts b/tests/cases/fourslash/extract-method33.ts new file mode 100644 index 00000000000..96d4216c844 --- /dev/null +++ b/tests/cases/fourslash/extract-method33.ts @@ -0,0 +1,44 @@ +/// + +// @Filename: /a.ts +////export interface A { +//// x: number; +////} + +// @Filename: /b.ts +////import { A } from "./a"; +////export interface B { +//// payload: T; +////} +////export const b: B = { +//// payload: { x: 1 } +////} + +// @Filename: /c.ts +////import { b } from "./b"; +//// +////function foo() { +//// const prop = b; +//// /*a*/console.log(prop);/*b*/ +////} + +goTo.file("/c.ts"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to function in module scope", + newContent: +`import { b, B } from "./b"; +import { A } from "./a"; + +function foo() { + const prop = b; + /*RENAME*/newFunction(prop); +} + +function newFunction(prop: B) { + console.log(prop); +} +` +}); diff --git a/tests/cases/fourslash/extract-method34.ts b/tests/cases/fourslash/extract-method34.ts new file mode 100644 index 00000000000..7ffb72e7af5 --- /dev/null +++ b/tests/cases/fourslash/extract-method34.ts @@ -0,0 +1,54 @@ +/// + +// @Filename: /a.ts +////export interface A { +//// x: number; +////} + +// @Filename: /b.ts +////export interface B { +//// payload: T; +////} + +// @Filename: /c.ts +////import { A } from "./a"; +////import { B } from "./b"; +////export interface C { +//// payload: T; +////} +//// +////export const c: C> = { +//// payload: { +//// payload: { x: 1 } +//// } +////} + +// @Filename: /d.ts +////import { c } from "./c"; +//// +////function foo() { +//// const prop = c; +//// /*a*/console.log(prop);/*b*/ +////} + +goTo.file("/c.ts"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to function in module scope", + newContent: +`import { c, C } from "./c"; +import { B } from "./b"; +import { A } from "./a"; + +function foo() { + const prop = c; + /*RENAME*/newFunction(prop); +} + +function newFunction(prop: C>) { + console.log(prop); +} +` +}); diff --git a/tests/cases/fourslash/extract-method35.ts b/tests/cases/fourslash/extract-method35.ts new file mode 100644 index 00000000000..67a3edd0b4a --- /dev/null +++ b/tests/cases/fourslash/extract-method35.ts @@ -0,0 +1,38 @@ +/// + +// @Filename: /a.ts +////export interface A { +//// x: number; +////} +////export const a: A = { x: 1 }; + +// @Filename: /b.ts +////import { a } from "./a"; +//// +////class Foo { +//// foo() { +//// const arg = a; +//// /*a*/console.log(arg);/*b*/ +//// } +////} + +goTo.file("/b.ts"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to method in class 'Foo'", + newContent: +`import { a, A } from "./a"; + +class Foo { + foo() { + const arg = a; + this./*RENAME*/newMethod(arg); + } + + private newMethod(arg: A) { + console.log(arg); + } +}` +}); diff --git a/tests/cases/fourslash/extract-method36.ts b/tests/cases/fourslash/extract-method36.ts new file mode 100644 index 00000000000..0b3e93e2b95 --- /dev/null +++ b/tests/cases/fourslash/extract-method36.ts @@ -0,0 +1,47 @@ +/// + +// @Filename: /a.ts +////export interface A { +//// x: number; +////} + +// @Filename: /b.ts +////import { A } from "./a"; +////export interface B { +//// payload: T; +////} +////export const b: B = { +//// payload: { x: 1 } +////} + +// @Filename: /c.ts +////import { b } from "./b"; +//// +////class Foo { +//// foo() { +//// const arg = b; +//// /*a*/console.log(arg);/*b*/ +//// } +////} + +goTo.file("/c.ts"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to method in class 'Foo'", + newContent: +`import { b, B } from "./b"; +import { A } from "./a"; + +class Foo { + foo() { + const arg = b; + this./*RENAME*/newMethod(arg); + } + + private newMethod(arg: B) { + console.log(arg); + } +}` +}); diff --git a/tests/cases/fourslash/extract-method37.ts b/tests/cases/fourslash/extract-method37.ts new file mode 100644 index 00000000000..1f71cd09818 --- /dev/null +++ b/tests/cases/fourslash/extract-method37.ts @@ -0,0 +1,57 @@ +/// + +// @Filename: /a.ts +////export interface A { +//// x: number; +////} + +// @Filename: /b.ts +////export interface B { +//// payload: T; +////} + +// @Filename: /c.ts +////import { A } from "./a"; +////import { B } from "./b"; +////export interface C { +//// payload: T; +////} +//// +////export const c: C> = { +//// payload: { +//// payload: { x: 1 } +//// } +////} + +// @Filename: /d.ts +////import { c } from "./c"; +//// +////class Foo { +//// foo() { +//// const arg = c; +//// /*a*/console.log(arg);/*b*/ +//// } +////} + +goTo.file("/d.ts"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to method in class 'Foo'", + newContent: +`import { c, C } from "./c"; +import { B } from "./b"; +import { A } from "./a"; + +class Foo { + foo() { + const arg = c; + this./*RENAME*/newMethod(arg); + } + + private newMethod(arg: C>) { + console.log(arg); + } +}` +}); diff --git a/tests/cases/fourslash/extract-method38.ts b/tests/cases/fourslash/extract-method38.ts new file mode 100644 index 00000000000..075f08ec7f9 --- /dev/null +++ b/tests/cases/fourslash/extract-method38.ts @@ -0,0 +1,14 @@ +/// + +////function bar(fn: () => void) {} +//// +////class Foo { +//// x: number; +//// foo() { +//// /*start*/bar(() => { this.x });/*end*/ +//// } +////} + +goTo.select("start", "end"); +verify.refactorAvailable("Extract Symbol", "function_scope_1"); +verify.not.refactorAvailable("Extract Symbol", "function_scope_2"); diff --git a/tests/cases/fourslash/extract-method39.ts b/tests/cases/fourslash/extract-method39.ts new file mode 100644 index 00000000000..85b51dcd9c0 --- /dev/null +++ b/tests/cases/fourslash/extract-method39.ts @@ -0,0 +1,14 @@ +/// + +////function bar(fn: () => void) {} +//// +////class Foo { +//// x: number; +//// foo() { +//// /*start*/bar(() => {});/*end*/ +//// } +////} + +goTo.select("start", "end"); +verify.refactorAvailable("Extract Symbol", "function_scope_1"); +verify.refactorAvailable("Extract Symbol", "function_scope_2"); diff --git a/tests/cases/fourslash/extract-method40.ts b/tests/cases/fourslash/extract-method40.ts new file mode 100644 index 00000000000..e59c56fe352 --- /dev/null +++ b/tests/cases/fourslash/extract-method40.ts @@ -0,0 +1,23 @@ +/// + +////const foo = /*start*/{ +//// a: 1, +//// b: () => { return 1; } +////}/*end*/ + +goTo.select("start", "end"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_0", + actionDescription: "Extract to function in global scope", + newContent: +`const foo = /*RENAME*/newFunction() + +function newFunction() { + return { + a: 1, + b: () => { return 1; } + }; +} +` +}); diff --git a/tests/cases/fourslash/extract-method41.ts b/tests/cases/fourslash/extract-method41.ts new file mode 100644 index 00000000000..d90ee90eeac --- /dev/null +++ b/tests/cases/fourslash/extract-method41.ts @@ -0,0 +1,20 @@ +/// + +////function bar(fn: () => void) {} +//// +////class Foo { +//// x: number; +//// foo() { +//// /*start*/bar(() => { +//// () => { +//// () => { +//// this.x; +//// } +//// } +//// });/*end*/ +//// } +////} + +goTo.select("start", "end"); +verify.refactorAvailable("Extract Symbol", "function_scope_1"); +verify.not.refactorAvailable("Extract Symbol", "function_scope_2"); diff --git a/tests/cases/fourslash/extractSymbolForTriggerReason.ts b/tests/cases/fourslash/extractSymbolForTriggerReason.ts new file mode 100644 index 00000000000..be946f5fc15 --- /dev/null +++ b/tests/cases/fourslash/extractSymbolForTriggerReason.ts @@ -0,0 +1,10 @@ +/// + +////function foo() { +//// return 1/*a*//*b*/00; +////} + +// Only offer refactor for empty span if explicity requested +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Extract Symbol"); +verify.refactorAvailableForTriggerReason("invoked", "Extract Symbol", "constant_scope_0"); diff --git a/tests/cases/fourslash/formatAsyncClassMethod1.ts b/tests/cases/fourslash/formatAsyncClassMethod1.ts new file mode 100644 index 00000000000..b120a8c771e --- /dev/null +++ b/tests/cases/fourslash/formatAsyncClassMethod1.ts @@ -0,0 +1,12 @@ +/// + +////class Foo { +//// async foo() {} +////} + +format.document(); +verify.currentFileContentIs( +`class Foo { + async foo() { } +}` +); diff --git a/tests/cases/fourslash/formatAsyncClassMethod2.ts b/tests/cases/fourslash/formatAsyncClassMethod2.ts new file mode 100644 index 00000000000..6901778b0a6 --- /dev/null +++ b/tests/cases/fourslash/formatAsyncClassMethod2.ts @@ -0,0 +1,12 @@ +/// + +////class Foo { +//// private async foo() {} +////} + +format.document(); +verify.currentFileContentIs( +`class Foo { + private async foo() { } +}` +); diff --git a/tests/cases/fourslash/formatNoSpaceAfterTemplateHeadAndMiddle.ts b/tests/cases/fourslash/formatNoSpaceAfterTemplateHeadAndMiddle.ts new file mode 100644 index 00000000000..4c4758917ad --- /dev/null +++ b/tests/cases/fourslash/formatNoSpaceAfterTemplateHeadAndMiddle.ts @@ -0,0 +1,52 @@ +/// + +////const a1 = `${ 1 }${ 1 }`; +////const a2 = ` +//// ${ 1 }${ 1 } +////`; +////const a3 = ` +//// +//// +//// ${ 1 }${ 1 } +////`; +////const a4 = ` +//// +//// ${ 1 }${ 1 } +//// +////`; +////const a5 = `text ${ 1 } text ${ 1 } text`; +////const a6 = ` +//// text ${ 1 } +//// text ${ 1 } +//// text +////`; + +format.setOption("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces", false); +format.document(); +verify.currentFileContentIs( + "const a1 = `${1}${1}`;\n" + + + "const a2 = `\n" + + " ${1}${1}\n" + + "`;\n" + + + "const a3 = `\n" + + "\n" + + "\n" + + " ${1}${1}\n" + + "`;\n" + + + "const a4 = `\n" + + "\n" + + " ${1}${1}\n" + + "\n" + + "`;\n" + + + "const a5 = `text ${1} text ${1} text`;\n" + + + "const a6 = `\n" + + " text ${1}\n" + + " text ${1}\n" + + " text\n" + + "`;" +); diff --git a/tests/cases/fourslash/formatSpaceAfterTemplateHeadAndMiddle.ts b/tests/cases/fourslash/formatSpaceAfterTemplateHeadAndMiddle.ts new file mode 100644 index 00000000000..b75c4f59623 --- /dev/null +++ b/tests/cases/fourslash/formatSpaceAfterTemplateHeadAndMiddle.ts @@ -0,0 +1,52 @@ +/// + +////const a1 = `${1}${1}`; +////const a2 = ` +//// ${1}${1} +////`; +////const a3 = ` +//// +//// +//// ${1}${1} +////`; +////const a4 = ` +//// +//// ${1}${1} +//// +////`; +////const a5 = `text ${1} text ${1} text`; +////const a6 = ` +//// text ${1} +//// text ${1} +//// text +////`; + +format.setOption("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces", true); +format.document(); +verify.currentFileContentIs( + "const a1 = `${ 1 }${ 1 }`;\n" + + + "const a2 = `\n" + + " ${ 1 }${ 1 }\n" + + "`;\n" + + + "const a3 = `\n" + + "\n" + + "\n" + + " ${ 1 }${ 1 }\n" + + "`;\n" + + + "const a4 = `\n" + + "\n" + + " ${ 1 }${ 1 }\n" + + "\n" + + "`;\n" + + + "const a5 = `text ${ 1 } text ${ 1 } text`;\n" + + + "const a6 = `\n" + + " text ${ 1 }\n" + + " text ${ 1 }\n" + + " text\n" + + "`;" +); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index d9b47adc1fb..ce3eefcb4ac 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -243,6 +243,7 @@ declare namespace FourSlashInterface { applicableRefactorAvailableForRange(): void; refactorAvailable(name: string, actionName?: string): void; + refactorAvailableForTriggerReason(triggerReason: RefactorTriggerReason, name: string, action?: string): void; } class verify extends verifyNegatable { assertHasRanges(ranges: Range[]): void; @@ -394,6 +395,8 @@ declare namespace FourSlashInterface { noMoveToNewFile(): void; generateTypes(...options: GenerateTypesOptions[]): void; + + organizeImports(newContent: string): void; } class edit { backspace(count?: number): void; @@ -681,6 +684,8 @@ declare namespace FourSlashInterface { triggerCharacter?: string, } + export type RefactorTriggerReason = "implicit" | "invoked"; + export interface VerifyCodeFixAvailableOptions { readonly description: string; readonly actions?: ReadonlyArray<{ readonly type: string, readonly data: {} }>; diff --git a/tests/cases/fourslash/getJavaScriptCompletions21.ts b/tests/cases/fourslash/getJavaScriptCompletions21.ts index e7dad574428..7e878c26f17 100644 --- a/tests/cases/fourslash/getJavaScriptCompletions21.ts +++ b/tests/cases/fourslash/getJavaScriptCompletions21.ts @@ -7,9 +7,12 @@ //// #privatething = 1; //// notSoPrivate = 1; ////} -////new Prv()['/**/']; +////new Prv()['[|/**/|]']; verify.completions({ marker: "", - exact: ["notSoPrivate"] + exact: [{ + name: "notSoPrivate", + replacementSpan: test.ranges()[0] + }] }); diff --git a/tests/cases/fourslash/getOutliningForArrayDestructuring.ts b/tests/cases/fourslash/getOutliningForArrayDestructuring.ts new file mode 100644 index 00000000000..72a2a0807ec --- /dev/null +++ b/tests/cases/fourslash/getOutliningForArrayDestructuring.ts @@ -0,0 +1,45 @@ +/// + +////const[| [ +//// a, +//// b, +//// c +////]|] =[| [ +//// 1, +//// 2, +//// 3 +////]|]; + +////const[| [ +//// [|[ +//// [|[ +//// [|[ +//// a, +//// b, +//// c +//// ]|] +//// ]|] +//// ]|], +//// [|[ +//// a1, +//// b1, +//// c1 +//// ]|] +////]|] =[| [ +//// [|[ +//// [|[ +//// [|[ +//// 1, +//// 2, +//// 3 +//// ]|] +//// ]|] +//// ]|], +//// [|[ +//// 1, +//// 2, +//// 3 +//// ]|] +////]|] + +verify.outliningSpansInCurrentFile(test.ranges(), "code"); diff --git a/tests/cases/fourslash/getOutliningForBlockComments.ts b/tests/cases/fourslash/getOutliningForBlockComments.ts index cc0bbc3c310..567806877ba 100644 --- a/tests/cases/fourslash/getOutliningForBlockComments.ts +++ b/tests/cases/fourslash/getOutliningForBlockComments.ts @@ -110,6 +110,26 @@ //// const sum2 = (y, z) =>[| { //// return y + z; //// }|]; +//// +////function Foo()[| { +//// [|/** +//// * Description +//// * +//// * @param {string} param +//// * @returns +//// */|] +//// this.method = function (param)[| { +//// }|] +//// +//// [|/** +//// * Description +//// * +//// * @param {string} param +//// * @returns +//// */|] +//// function method(param)[| { +//// }|] +////}|] verify.outliningSpansInCurrentFile(test.ranges()); diff --git a/tests/cases/fourslash/getOutliningForObjectDestructuring.ts b/tests/cases/fourslash/getOutliningForObjectDestructuring.ts new file mode 100644 index 00000000000..bc9ce6ba2cd --- /dev/null +++ b/tests/cases/fourslash/getOutliningForObjectDestructuring.ts @@ -0,0 +1,39 @@ +/// + +////const[| { +//// a, +//// b, +//// c +////}|] =[| { +//// a: 1, +//// b: 2, +//// c: 3 +////}|] + +////const[| { +//// a:[| { +//// a_1, +//// a_2, +//// a_3:[| { +//// a_3_1, +//// a_3_2, +//// a_3_3, +//// }|], +//// }|], +//// b, +//// c +////}|] =[| { +//// a:[| { +//// a_1: 1, +//// a_2: 2, +//// a_3:[| { +//// a_3_1: 1, +//// a_3_2: 1, +//// a_3_3: 1 +//// }|], +//// }|], +//// b: 2, +//// c: 3 +////}|] + +verify.outliningSpansInCurrentFile(test.ranges(), "code"); diff --git a/tests/cases/fourslash/getOutliningForSingleLineComments.ts b/tests/cases/fourslash/getOutliningForSingleLineComments.ts index 903b1c55494..9ada3fca446 100644 --- a/tests/cases/fourslash/getOutliningForSingleLineComments.ts +++ b/tests/cases/fourslash/getOutliningForSingleLineComments.ts @@ -72,6 +72,18 @@ ////// One single line comment should not be collapsed ////class WithOneSingleLineComment[| { ////}|] +//// +////function Foo()[| { +//// [|// comment 1 +//// // comment 2|] +//// this.method = function (param)[| { +//// }|] +//// +//// [|// comment 1 +//// // comment 2|] +//// function method(param)[| { +//// }|] +////}|] verify.outliningSpansInCurrentFile(test.ranges()); diff --git a/tests/cases/fourslash/getOutliningForTupleType.ts b/tests/cases/fourslash/getOutliningForTupleType.ts new file mode 100644 index 00000000000..f63fb623ac4 --- /dev/null +++ b/tests/cases/fourslash/getOutliningForTupleType.ts @@ -0,0 +1,19 @@ +/// + +////type A =[| [ +//// number, +//// number, +//// number +////]|] +//// +////type B =[| [ +//// [|[ +//// [|[ +//// number, +//// number, +//// number +//// ]|] +//// ]|] +////]|] + +verify.outliningSpansInCurrentFile(test.ranges(), "code"); diff --git a/tests/cases/fourslash/getOutliningForTypeLiteral.ts b/tests/cases/fourslash/getOutliningForTypeLiteral.ts new file mode 100644 index 00000000000..d0d6693ec39 --- /dev/null +++ b/tests/cases/fourslash/getOutliningForTypeLiteral.ts @@ -0,0 +1,24 @@ +/// + +////type A =[| { +//// a: number; +////}|] +//// +////type B =[| { +//// a:[| { +//// a1:[| { +//// a2:[| { +//// x: number; +//// y: number; +//// }|] +//// }|] +//// }|], +//// b:[| { +//// x: number; +//// }|], +//// c:[| { +//// x: number; +//// }|] +////}|] + +verify.outliningSpansInCurrentFile(test.ranges(), "code"); diff --git a/tests/cases/fourslash/goToDefinitionJsModuleExports.ts b/tests/cases/fourslash/goToDefinitionJsModuleExports.ts new file mode 100644 index 00000000000..43d81085a47 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionJsModuleExports.ts @@ -0,0 +1,10 @@ +/// + +// #33520 + +// @allowJs: true +// @Filename: foo.js +////x.test = /*def*/() => { } +////x.[|/*ref*/test|](); + +verify.goToDefinition("ref", "def"); diff --git a/tests/cases/fourslash/goToDefinitionVariableAssignment.ts b/tests/cases/fourslash/goToDefinitionVariableAssignment.ts index 09d5f1126f1..3b0c14655e7 100644 --- a/tests/cases/fourslash/goToDefinitionVariableAssignment.ts +++ b/tests/cases/fourslash/goToDefinitionVariableAssignment.ts @@ -4,9 +4,9 @@ // @checkJs: true // @filename: foo.js ////const Bar; -////const /*def1*/Foo = /*def2*/Bar = function () {} +////const Foo = /*def*/Bar = function () {} ////Foo.prototype.bar = function() {} ////new [|Foo/*ref*/|](); goTo.file("foo.js"); -verify.goToDefinition("ref", ["def1", "def2"]); +verify.goToDefinition("ref", "def"); diff --git a/tests/cases/fourslash/goToDefinitionVariableAssignment1.ts b/tests/cases/fourslash/goToDefinitionVariableAssignment1.ts index 45e666cafa6..cce4afa072a 100644 --- a/tests/cases/fourslash/goToDefinitionVariableAssignment1.ts +++ b/tests/cases/fourslash/goToDefinitionVariableAssignment1.ts @@ -3,9 +3,9 @@ // @allowJs: true // @checkJs: true // @filename: foo.js -////const /*def1*/Foo = module./*def2*/exports = function () {} +////const Foo = module./*def*/exports = function () {} ////Foo.prototype.bar = function() {} ////new [|Foo/*ref*/|](); goTo.file("foo.js"); -verify.goToDefinition("ref", ["def1", "def2"]); +verify.goToDefinition("ref", "def"); diff --git a/tests/cases/fourslash/goToDefinitionVariableAssignment2.ts b/tests/cases/fourslash/goToDefinitionVariableAssignment2.ts index d5474cda93c..a23c121a340 100644 --- a/tests/cases/fourslash/goToDefinitionVariableAssignment2.ts +++ b/tests/cases/fourslash/goToDefinitionVariableAssignment2.ts @@ -2,9 +2,9 @@ // @filename: foo.ts ////const Bar; -////const /*def1*/Foo = /*def2*/Bar = function () {} +////const Foo = /*def*/Bar = function () {} ////Foo.prototype.bar = function() {} ////new [|Foo/*ref*/|](); goTo.file("foo.ts"); -verify.goToDefinition("ref", ["def1", "def2"]); +verify.goToDefinition("ref", "def"); diff --git a/tests/cases/fourslash/goToDefinitionVariableAssignment3.ts b/tests/cases/fourslash/goToDefinitionVariableAssignment3.ts index 85d6c43e729..e1ac6b9c8ee 100644 --- a/tests/cases/fourslash/goToDefinitionVariableAssignment3.ts +++ b/tests/cases/fourslash/goToDefinitionVariableAssignment3.ts @@ -1,9 +1,9 @@ /// // @filename: foo.ts -////const /*def1*/Foo = module./*def2*/exports = function () {} +////const Foo = module./*def*/exports = function () {} ////Foo.prototype.bar = function() {} ////new [|Foo/*ref*/|](); goTo.file("foo.ts"); -verify.goToDefinition("ref", ["def1", "def2"]); +verify.goToDefinition("ref", "def"); diff --git a/tests/cases/fourslash/goToImplementationInterface_01.ts b/tests/cases/fourslash/goToImplementationInterface_01.ts index 9f76e9db5cd..a797fca37bc 100644 --- a/tests/cases/fourslash/goToImplementationInterface_01.ts +++ b/tests/cases/fourslash/goToImplementationInterface_01.ts @@ -10,10 +10,10 @@ //// abstract hello (): void; //// } //// -//// class Bar extends SuperBar { +//// class [|Bar|] extends SuperBar { //// } //// -//// class NotAbstractBar extends AbstractBar { +//// class [|NotAbstractBar|] extends AbstractBar { //// hello () {} //// } //// diff --git a/tests/cases/fourslash/importNameCodeFix_all2.ts b/tests/cases/fourslash/importNameCodeFix_all2.ts new file mode 100644 index 00000000000..6f7a9b3403c --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_all2.ts @@ -0,0 +1,23 @@ +/// + +// @Filename: /path.ts +////export declare function join(): void; + +// @Filename: /os.ts +////export declare function homedir(): void; + +// @Filename: /index.ts +//// +////join(); +////homedir(); + +goTo.file("/index.ts"); +verify.codeFixAll({ + fixId: "fixMissingImport", + fixAllDescription: "Add all missing imports", + newFileContent: `import { join } from "./path"; +import { homedir } from "./os"; + +join(); +homedir();` +}); diff --git a/tests/cases/fourslash/importNameCodeFix_exportEquals.ts b/tests/cases/fourslash/importNameCodeFix_exportEquals.ts index 4ab87df7e76..e413c4d4e1d 100644 --- a/tests/cases/fourslash/importNameCodeFix_exportEquals.ts +++ b/tests/cases/fourslash/importNameCodeFix_exportEquals.ts @@ -17,7 +17,6 @@ verify.codeFixAll({ fixAllDescription: "Add all missing imports", newFileContent: `import { b } from "./a"; - import a = require("./a"); a; diff --git a/tests/cases/fourslash/moveToNewFile_decorators.ts b/tests/cases/fourslash/moveToNewFile_decorators.ts new file mode 100644 index 00000000000..a44ff9cb5cd --- /dev/null +++ b/tests/cases/fourslash/moveToNewFile_decorators.ts @@ -0,0 +1,34 @@ +/// + +// @experimentalDecorators: true + +// @Filename: /a.ts +////const decorator1: any = () => {}; +////const decorator2: any = () => {}; +////[|class Foo { +//// constructor(@decorator1 private readonly x: number, +//// @decorator1 @decorator2 private readonly y: number) { } +//// +//// method1(@decorator1 x: number) { } +//// method2(@decorator1 @decorator2 x: number) { } +////}|] + +verify.noErrors(); + +verify.moveToNewFile({ + newFileContents: { + "/a.ts": +`const decorator1: any = () => {}; +const decorator2: any = () => {}; +`, + "/Foo.ts": +`class Foo { + constructor(@decorator1 private readonly x: number, + @decorator1 @decorator2 private readonly y: number) { } + + method1(@decorator1 x: number) { } + method2(@decorator1 @decorator2 x: number) { } +} +` + } +}); diff --git a/tests/cases/fourslash/moveToNewFile_decorators1.ts b/tests/cases/fourslash/moveToNewFile_decorators1.ts new file mode 100644 index 00000000000..3f2ca9a30f4 --- /dev/null +++ b/tests/cases/fourslash/moveToNewFile_decorators1.ts @@ -0,0 +1,28 @@ +/// + +// @experimentalDecorators: true + +// @Filename: /a.ts +////const decorator1: any = () => {}; +////const decorator2: any = () => {}; +////[|class Foo { +//// @decorator1 method1() { } +//// @decorator1 @decorator2 method2() { } +////}|] + +verify.noErrors(); + +verify.moveToNewFile({ + newFileContents: { + "/a.ts": +`const decorator1: any = () => {}; +const decorator2: any = () => {}; +`, + "/Foo.ts": +`class Foo { + @decorator1 method1() { } + @decorator1 @decorator2 method2() { } +} +` + } +}); diff --git a/tests/cases/fourslash/moveToNewFile_decorators2.ts b/tests/cases/fourslash/moveToNewFile_decorators2.ts new file mode 100644 index 00000000000..41daa532eea --- /dev/null +++ b/tests/cases/fourslash/moveToNewFile_decorators2.ts @@ -0,0 +1,22 @@ +/// + +// @experimentalDecorators: true + +// @Filename: /a.ts +////const decorator1: any = () => {}; +////[|@decorator1 class Foo { +////}|] + +verify.noErrors(); + +verify.moveToNewFile({ + newFileContents: { + "/a.ts": +`const decorator1: any = () => {}; +`, + "/Foo.ts": +`@decorator1 class Foo { +} +` + } +}); diff --git a/tests/cases/fourslash/moveToNewFile_decorators3.ts b/tests/cases/fourslash/moveToNewFile_decorators3.ts new file mode 100644 index 00000000000..dc75ce48969 --- /dev/null +++ b/tests/cases/fourslash/moveToNewFile_decorators3.ts @@ -0,0 +1,24 @@ +/// + +// @experimentalDecorators: true + +// @Filename: /a.ts +////const decorator1: any = () => {}; +////const decorator2: any = () => {}; +////[|@decorator1 @decorator2 class Foo { +////}|] + +verify.noErrors(); + +verify.moveToNewFile({ + newFileContents: { + "/a.ts": +`const decorator1: any = () => {}; +const decorator2: any = () => {}; +`, + "/Foo.ts": +`@decorator1 @decorator2 class Foo { +} +` + } +}); diff --git a/tests/cases/fourslash/moveToNewFile_moveNamedImport.ts b/tests/cases/fourslash/moveToNewFile_moveNamedImport.ts new file mode 100644 index 00000000000..63100d05f93 --- /dev/null +++ b/tests/cases/fourslash/moveToNewFile_moveNamedImport.ts @@ -0,0 +1,18 @@ +/// + +// @Filename: /a.ts +////import { foo as oFoo } from './other'; +////[|export const x = oFoo();|] +////export const a = 0; + +verify.moveToNewFile({ + newFileContents: { +"/a.ts": +`export const a = 0;`, + +"/x.ts": +`import { foo as oFoo } from './other'; +export const x = oFoo(); +` + }, +}); diff --git a/tests/cases/fourslash/moveToNewFile_moveNamespaceImport.ts b/tests/cases/fourslash/moveToNewFile_moveNamespaceImport.ts new file mode 100644 index 00000000000..4d5ee7ffbf0 --- /dev/null +++ b/tests/cases/fourslash/moveToNewFile_moveNamespaceImport.ts @@ -0,0 +1,18 @@ +/// + +// @Filename: /a.ts +////import * as o from './other'; +////[|export const x = o.foo();|] +////export const a = 0; + +verify.moveToNewFile({ + newFileContents: { +"/a.ts": +`export const a = 0;`, + +"/x.ts": +`import * as o from './other'; +export const x = o.foo(); +` + }, +}); diff --git a/tests/cases/fourslash/namedTupleMembers.ts b/tests/cases/fourslash/namedTupleMembers.ts new file mode 100644 index 00000000000..034570e715f --- /dev/null +++ b/tests/cases/fourslash/namedTupleMembers.ts @@ -0,0 +1,5 @@ +/// + +////export type /*1*/Segment = [length: number, count: number]; + +verify.quickInfoAt("1", "type Segment = [length: number, count: number]"); \ No newline at end of file diff --git a/tests/cases/fourslash/navigationBarWithLocalVariables.ts b/tests/cases/fourslash/navigationBarWithLocalVariables.ts new file mode 100644 index 00000000000..de673d6d9d6 --- /dev/null +++ b/tests/cases/fourslash/navigationBarWithLocalVariables.ts @@ -0,0 +1,23 @@ +/// + +//// function x(){ +//// const x = Object() +//// x.foo = "" +//// } + +verify.navigationTree({ + "text": "", + "kind": "script", + "childItems": [ + { + "text": "x", + "kind": "function", + "childItems": [ + { + "text": "x", + "kind": "const" + } + ] + } + ] +}); diff --git a/tests/cases/fourslash/navigationItemsExportDefaultExpression.ts b/tests/cases/fourslash/navigationItemsExportDefaultExpression.ts index 6425fd4bf7a..c3059d50c03 100644 --- a/tests/cases/fourslash/navigationItemsExportDefaultExpression.ts +++ b/tests/cases/fourslash/navigationItemsExportDefaultExpression.ts @@ -5,6 +5,13 @@ //// export default () => "" //// export default abc; //// export default class AB {} +//// export default { +//// a: 1, +//// b: 1, +//// c: { +//// d: 1 +//// } +//// } verify.navigationTree({ "text": '"navigationItemsExportDefaultExpression"', @@ -20,6 +27,31 @@ verify.navigationTree({ "kind": "function", "kindModifiers": "export" }, + { + "text": "default", + "kind": "const", + "kindModifiers": "export", + "childItems": [ + { + "text": "a", + "kind": "property" + }, + { + "text": "b", + "kind": "property" + }, + { + "text": "c", + "kind": "property", + "childItems": [ + { + "text": "d", + "kind": "property" + } + ] + } + ] + }, { "text": "AB", "kind": "class", diff --git a/tests/cases/fourslash/navigationItemsExportEqualsExpression.ts b/tests/cases/fourslash/navigationItemsExportEqualsExpression.ts index 053a1fa0023..f63db161b09 100644 --- a/tests/cases/fourslash/navigationItemsExportEqualsExpression.ts +++ b/tests/cases/fourslash/navigationItemsExportEqualsExpression.ts @@ -6,6 +6,13 @@ //// export = function () {} //// export = () => "" //// export = class AB {} +//// export = { +//// a: 1, +//// b: 1, +//// c: { +//// d: 1 +//// } +//// } verify.navigationTree({ "text": '"navigationItemsExportEqualsExpression"', @@ -26,6 +33,31 @@ verify.navigationTree({ "kind": "class", "kindModifiers": "export" }, + { + "text": "export=", + "kind": "const", + "kindModifiers": "export", + "childItems": [ + { + "text": "a", + "kind": "property" + }, + { + "text": "b", + "kind": "property" + }, + { + "text": "c", + "kind": "property", + "childItems": [ + { + "text": "d", + "kind": "property" + } + ] + } + ] + }, { "text": "abc", "kind": "const" diff --git a/tests/cases/fourslash/organizeImportsNoFormatOptions.ts b/tests/cases/fourslash/organizeImportsNoFormatOptions.ts new file mode 100644 index 00000000000..24626441222 --- /dev/null +++ b/tests/cases/fourslash/organizeImportsNoFormatOptions.ts @@ -0,0 +1,22 @@ +/// + +// #38548 + +////import { +//// stat, +//// statSync, +////} from "fs"; +////export function fakeFn() { +//// stat; +//// statSync; +////} + +format.setFormatOptions({}); + +// Default newline is carriage return. +// See `getNewLineOrDefaultFromHost()` in services/utilities.ts. +verify.organizeImports( +`import {\r\nstat,\r\nstatSync\r\n} from "fs";\r\nexport function fakeFn() { + stat; + statSync; +}`); diff --git a/tests/cases/fourslash/outliningSpansForFunction.ts b/tests/cases/fourslash/outliningSpansForFunction.ts index acc00eedbee..f46886b7306 100644 --- a/tests/cases/fourslash/outliningSpansForFunction.ts +++ b/tests/cases/fourslash/outliningSpansForFunction.ts @@ -1,14 +1,84 @@ /// -////function f(x: number, y: number)[| { -//// return x + y; +////[|( +//// a: number, +//// b: number +////) => { +//// return a + b; +////}|] +///// +////(a: number, b: number) => [|{ +//// return a + b; ////}|] //// -////function g[|( -//// x: number, -//// y: number, -////): number { -//// return x + y; +////const f1 = function[| ( +//// a: number +//// b: number +////) { +//// return a + b; ////}|] +//// +////const f2 = function (a: number, b: number)[| { +//// return a + b; +////}|] +//// +////function f3[| ( +//// a: number +//// b: number +////) { +//// return a + b; +////}|] +//// +////function f4(a: number, b: number)[| { +//// return a + b; +////}|] +//// +////class Foo[| { +//// constructor[|( +//// a: number, +//// b: number +//// ) { +//// this.a = a; +//// this.b = b; +//// }|] +//// +//// m1[|( +//// a: number, +//// b: number +//// ) { +//// return a + b; +//// }|] +//// +//// m1(a: number, b: number)[| { +//// return a + b; +//// }|] +////}|] +//// +////declare function foo(props: any): void; +////foo( +//// a =>[| { +//// +//// }|] +////) +//// +////foo( +//// (a) =>[| { +//// +//// }|] +////) +//// +////foo( +//// (a, b, c) =>[| { +//// +//// }|] +////) +//// +////foo([| +//// (a, +//// b, +//// c) => { +//// +//// }|] +////) verify.outliningSpansInCurrentFile(test.ranges()); diff --git a/tests/cases/fourslash/quickInfoForGenericTaggedTemplateExpression.ts b/tests/cases/fourslash/quickInfoForGenericTaggedTemplateExpression.ts new file mode 100644 index 00000000000..922c9984355 --- /dev/null +++ b/tests/cases/fourslash/quickInfoForGenericTaggedTemplateExpression.ts @@ -0,0 +1,28 @@ +/// + +////interface T1 {} +////class T2 {} +////type T3 = "a" | "b"; +//// +////declare function foo(strings: TemplateStringsArray, ...values: T[]): void; +//// +/////*1*/foo``; +/////*2*/foo``; +/////*3*/foo<{ a: number }>``; +/////*4*/foo``; +/////*5*/foo``; +/////*6*/foo``; +/////*7*/foo``; + +verify.quickInfoAt("1", "function foo(strings: TemplateStringsArray, ...values: number[]): void"); +verify.quickInfoAt("2", "function foo(strings: TemplateStringsArray, ...values: (string | number)[]): void"); +verify.quickInfoAt("3", +`function foo<{ + a: number; +}>(strings: TemplateStringsArray, ...values: { + a: number; +}[]): void`); +verify.quickInfoAt("4", "function foo(strings: TemplateStringsArray, ...values: T1[]): void"); +verify.quickInfoAt("5", "function foo(strings: TemplateStringsArray, ...values: T2[]): void"); +verify.quickInfoAt("6", "function foo(strings: TemplateStringsArray, ...values: T3[]): void"); +verify.quickInfoAt("7", "function foo(strings: TemplateStringsArray, ...values: unknown[]): void"); diff --git a/tests/cases/fourslash/quickInfoForGetterAndSetter.ts b/tests/cases/fourslash/quickInfoForGetterAndSetter.ts new file mode 100644 index 00000000000..723836488c2 --- /dev/null +++ b/tests/cases/fourslash/quickInfoForGetterAndSetter.ts @@ -0,0 +1,23 @@ +/// + +//// class Test { +//// constructor() { +//// this.value; +//// } +//// +//// /** Getter text */ +//// get val/*1*/ue() { +//// return this.value; +//// } +//// +//// /** Setter text */ +//// set val/*2*/ue(value) { +//// this.value = value; +//// } +//// } + +goTo.marker("1"); +verify.quickInfoIs("(property) Test.value: any", "Getter text"); + +goTo.marker("2"); +verify.quickInfoIs("(property) Test.value: any", "Setter text"); diff --git a/tests/cases/fourslash/quickInfoForOverloadOnConst1.ts b/tests/cases/fourslash/quickInfoForOverloadOnConst1.ts index de06e2480c5..15c51a86433 100644 --- a/tests/cases/fourslash/quickInfoForOverloadOnConst1.ts +++ b/tests/cases/fourslash/quickInfoForOverloadOnConst1.ts @@ -20,13 +20,13 @@ ////c.x1(1, (x/*10*/x) => { return 1; } ); verify.quickInfos({ - 1: "(method) I.x1(a: number, callback: (x: \"hi\") => number): any", - 2: "(method) C.x1(a: number, callback: (x: \"hi\") => number): any", - 3: "(parameter) callback: (x: \"hi\") => number", + 1: "(method) I.x1(a: number, callback: (x: 'hi') => number): any", + 2: "(method) C.x1(a: number, callback: (x: 'hi') => number): any", + 3: "(parameter) callback: (x: 'hi') => number", 4: "(method) C.x1(a: number, callback: (x: \"hi\") => number): any", 5: "(parameter) callback: (x: string) => number", 6: "(parameter) callback: (x: string) => number", - 7: "(method) C.x1(a: number, callback: (x: \"hi\") => number): any", + 7: "(method) C.x1(a: number, callback: (x: 'hi') => number): any", 8: "(parameter) xx: \"hi\"", 9: "(parameter) xx: \"bye\"", 10: "(parameter) xx: \"hi\"" diff --git a/tests/cases/fourslash/quickInfoJSExport.ts b/tests/cases/fourslash/quickInfoJSExport.ts new file mode 100644 index 00000000000..24a9bd00fa3 --- /dev/null +++ b/tests/cases/fourslash/quickInfoJSExport.ts @@ -0,0 +1,24 @@ +/// + +// GH #35347 + +// @Filename: a.js +// @allowJs: true +//// /** +//// * @enum {string} +//// */ +//// const testString = { +//// one: "1", +//// two: "2" +//// }; +//// +//// export { test/**/String }; + +verify.quickInfoAt("", +`type testString = string +(alias) type testString = any +(alias) const testString: { + one: string; + two: string; +} +export testString`); diff --git a/tests/cases/fourslash/quickInfoOnUnionPropertiesWithIdenticalJSDocComments01.ts b/tests/cases/fourslash/quickInfoOnUnionPropertiesWithIdenticalJSDocComments01.ts new file mode 100644 index 00000000000..132130da22f --- /dev/null +++ b/tests/cases/fourslash/quickInfoOnUnionPropertiesWithIdenticalJSDocComments01.ts @@ -0,0 +1,29 @@ +/// + +////export type DocumentFilter = { +//// /** A language id, like `typescript`. */ +//// language: string; +//// /** A Uri [scheme](#Uri.scheme), like `file` or `untitled`. */ +//// scheme?: string; +//// /** A glob pattern, like `*.{ts,js}`. */ +//// pattern?: string; +////} | { +//// /** A language id, like `typescript`. */ +//// language?: string; +//// /** A Uri [scheme](#Uri.scheme), like `file` or `untitled`. */ +//// scheme: string; +//// /** A glob pattern, like `*.{ts,js}`. */ +//// pattern?: string; +////} | { +//// /** A language id, like `typescript`. */ +//// language?: string; +//// /** A Uri [scheme](#Uri.scheme), like `file` or `untitled`. */ +//// scheme?: string; +//// /** A glob pattern, like `*.{ts,js}`. */ +//// pattern: string; +////}; +//// +////declare let x: DocumentFilter; +////x./**/language + +verify.baselineQuickInfo(); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction24.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction24.ts new file mode 100644 index 00000000000..3bee61a201c --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction24.ts @@ -0,0 +1,11 @@ +/// + +//// const a = (a: number) /*a*/=>/*b*/ {/* comment */ return a;}; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const a = (a: number) => /* comment */ a;`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction25.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction25.ts new file mode 100644 index 00000000000..5f7226c2e93 --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction25.ts @@ -0,0 +1,11 @@ +/// + +//// const a = (a: number) /*a*/=>/*b*/ { return a; /* trailing */}; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const a = (a: number) => a /* trailing */;`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction26.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction26.ts new file mode 100644 index 00000000000..24234c7107d --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction26.ts @@ -0,0 +1,11 @@ +/// + +//// const a = (a: number) /*a*/=>/*b*/ {/* leading */ return a; /* trailing */}; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const a = (a: number) => /* leading */ a /* trailing */;`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction27.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction27.ts new file mode 100644 index 00000000000..7f36317a233 --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction27.ts @@ -0,0 +1,13 @@ +/// + +//// const b = (a: number) /*a*/=>/*b*/ { /* leading */ +//// return a; /* trailing */ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const b = (a: number) => /* leading */ a /* trailing */`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction28.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction28.ts new file mode 100644 index 00000000000..a79b89c9f2f --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction28.ts @@ -0,0 +1,11 @@ +/// + +//// const a = (a: number) /*a*/=>/*b*/ { return a; /* c */ /* d */ }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const a = (a: number) => a /* c */ /* d */;`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunctionForTriggerReason1.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunctionForTriggerReason1.ts new file mode 100644 index 00000000000..4f5e41a8e3a --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunctionForTriggerReason1.ts @@ -0,0 +1,8 @@ +/// + +//// const a = (a: number) => { return/*a*//*b*/ a; }; + +// Only offer refactor for empty span in body if explicity requested +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Add or remove braces in an arrow function"); +verify.refactorAvailableForTriggerReason("invoked", "Add or remove braces in an arrow function", "Remove braces from arrow function"); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunctionForTriggerReason2.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunctionForTriggerReason2.ts new file mode 100644 index 00000000000..5677e2c7144 --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunctionForTriggerReason2.ts @@ -0,0 +1,8 @@ +/// + +//// const a = (a: number) => { re/*a*/tur/*b*/n a; }; + +// Only offer refactor in body if explicity requested +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Add or remove braces in an arrow function"); +verify.refactorAvailableForTriggerReason("invoked", "Add or remove braces in an arrow function", "Remove braces from arrow function"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon.ts new file mode 100644 index 00000000000..0fa3222617c --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon.ts @@ -0,0 +1,28 @@ +/// + +//// /*z*/c/*y*/onst /*x*/f/*w*/oo = /*v*/f/*u*/unction() /*t*/{/*s*/ /*r*/r/*q*/eturn 42;}; + +goTo.select("z", "y"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("x", "w"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("v", "u"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("t", "s"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("r", "q"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_FnArgument.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_FnArgument.ts new file mode 100644 index 00000000000..6c017aeeb73 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_FnArgument.ts @@ -0,0 +1,34 @@ +/// + +//// function foo(a){} +//// /*z*/f/*y*/oo/*x*/(/*w*//*v*/f/*u*/unction/*t*/(/*s*//*r*/b/*q*/,c){/*p*/r/*o*/eturn 42;}) + +goTo.select("z", "y"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("x", "w"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("v", "u"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("t", "s"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("r", "q"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("p", "o"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_nested_this.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_nested_this.ts new file mode 100644 index 00000000000..cbf57122526 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_nested_this.ts @@ -0,0 +1,19 @@ +/// + +//// const zoo = /*x*/f/*w*/unction () { +//// class Animal { +//// weight = 42 +//// askWeight() { return this.weight } +//// } +//// const Insect = class { +//// weight = 42 +//// askWeight() { return this.weight } +//// } +//// function callTaxi() { this.no = "054 xxx xx xx" } +//// const callPizzaDelivery = function() { this.phone = "064 yyy yy yy"} +//// }; + +goTo.select("x", "w"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_this.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_this.ts new file mode 100644 index 00000000000..a895fea432d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_this.ts @@ -0,0 +1,11 @@ +/// + +//// const foo = /*x*/f/*w*/unction() { +//// this.bar = "F-Express"; +//// return this.bar; +//// }; + +goTo.select("x", "w"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_unusedName.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_unusedName.ts new file mode 100644 index 00000000000..480dd466ec2 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_unusedName.ts @@ -0,0 +1,28 @@ +/// + +//// /*z*/c/*y*/onst /*x*/f/*w*/oo = /*v*/f/*u*/unction bar() /*t*/{/*s*/ /*r*/r/*q*/eturn 42;}; + +goTo.select("z", "y"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("x", "w"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("v", "u"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("t", "s"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("r", "q"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_usedName.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_usedName.ts new file mode 100644 index 00000000000..ff87ca84714 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_usedName.ts @@ -0,0 +1,28 @@ +/// + +//// /*z*/c/*y*/onst /*x*/f/*w*/oo = /*v*/f/*u*/unction isEven(n) /*t*/{/*s*/ /*r*/r/*q*/eturn n === 0 ? true : n === 1 ? false : isEven(n - 2);}; + +goTo.select("z", "y"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("x", "w"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("v", "u"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("t", "s"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("r", "q"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow.ts new file mode 100644 index 00000000000..619b2af822c --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow.ts @@ -0,0 +1,33 @@ +/// + +//// /*z*/c/*y*/onst /*x*/f/*w*/oo = /*v*/(/*u*//*t*/a/*s*/, b) /*r*/=/*q*/> /*p*/4/*o*/2; + +goTo.select("z", "y"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("x", "w"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("v", "u"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("t", "s"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("r", "q"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("p", "o"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_FnArgument.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_FnArgument.ts new file mode 100644 index 00000000000..6d309494da9 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_FnArgument.ts @@ -0,0 +1,30 @@ +/// + +//// function foo(a){} +//// /*z*/f/*y*/oo/*x*/(/*w*//*v*/(/*u*//*t*/a/*s*/, b) => /*r*/a/*q*/ + b) + + +goTo.select("z", "y"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("x", "w"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("v", "u"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("t", "s"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("r", "q"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_MultiDecl.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_MultiDecl.ts new file mode 100644 index 00000000000..1e87f8bc0c3 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_MultiDecl.ts @@ -0,0 +1,23 @@ +/// + +//// /*z*/l/*y*/et /*x*/f/*w*/oo, /*v*/b/*u*/ar = /*t*/(/*s*/) => 42; + +goTo.select("z", "y"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("x", "w"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("v", "u"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); + +goTo.select("t", "s"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_nested_this.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_nested_this.ts new file mode 100644 index 00000000000..4b5985b9a85 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_nested_this.ts @@ -0,0 +1,19 @@ +/// + +//// const zoo = /*x*/(/*w*/) => { +//// class Animal { +//// weight = 42 +//// askWeight() { return this.weight } +//// } +//// const Insect = class { +//// weight = 42 +//// askWeight() { return this.weight } +//// } +//// function callTaxi() { this.no = "054 xxx xx xx" } +//// const callPizzaDelivery = function() { this.phone = "064 yyy yy yy"} +//// }; + +goTo.select("x", "w"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_this.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_this.ts new file mode 100644 index 00000000000..d1905c48f35 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_this.ts @@ -0,0 +1,9 @@ +/// + +//// const bar = 42; +//// const foo = /*x*/(/*w*/) => this.bar; + +goTo.select("x", "w"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function"); +verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_Comment.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_Comment.ts new file mode 100644 index 00000000000..c3a65cbf055 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_Comment.ts @@ -0,0 +1,23 @@ +/// + +//// const foo = /*x*/a/*y*/ => { +//// // secret word +//// return a + 1; +//// /* +//// hidden msg +//// */ +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to anonymous function", + actionDescription: "Convert to anonymous function", + newContent: `const foo = function(a) { + // secret word + return a + 1; + /* + hidden msg + */ +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_FnArgument.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_FnArgument.ts new file mode 100644 index 00000000000..c07a741f1ab --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_FnArgument.ts @@ -0,0 +1,15 @@ +/// + +//// function doSomething(a){} +//// doSomething(/*x*/(/*y*/) => 1 + 1); + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to anonymous function", + actionDescription: "Convert to anonymous function", + newContent: `function doSomething(a){} +doSomething(function() { + return 1 + 1; + });`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MapArgument.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MapArgument.ts new file mode 100644 index 00000000000..8d53517d7ea --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MapArgument.ts @@ -0,0 +1,13 @@ +/// + +//// [9,8,7].map(/*x*/n/*y*/ => n + 418); + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to anonymous function", + actionDescription: "Convert to anonymous function", + newContent: `[9,8,7].map(function(n) { + return n + 418; + });`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MultiLine.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MultiLine.ts new file mode 100644 index 00000000000..cbaadbf6a85 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MultiLine.ts @@ -0,0 +1,17 @@ +/// + +//// const foo = /*x*/a/*y*/ => { +//// let b = 1; +//// return a + b; +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to anonymous function", + actionDescription: "Convert to anonymous function", + newContent: `const foo = function(a) { + let b = 1; + return a + b; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MultiParam.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MultiParam.ts new file mode 100644 index 00000000000..38953dbf248 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MultiParam.ts @@ -0,0 +1,13 @@ +/// + +//// const foo = /*x*/(/*y*/a,b,c) => a + 1; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to anonymous function", + actionDescription: "Convert to anonymous function", + newContent: `const foo = function(a, b, c) { + return a + 1; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_SingleLine.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_SingleLine.ts new file mode 100644 index 00000000000..9870104eb16 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_SingleLine.ts @@ -0,0 +1,13 @@ +/// + +//// const foo = /*x*/(/*y*/) => 1 + 1; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to anonymous function", + actionDescription: "Convert to anonymous function", + newContent: `const foo = function() { + return 1 + 1; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_Typed.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_Typed.ts new file mode 100644 index 00000000000..0fbea66be0e --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_Typed.ts @@ -0,0 +1,13 @@ +/// + +//// const increment = /*x*/(/*y*/a: number): number => a + 1; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to anonymous function", + actionDescription: "Convert to anonymous function", + newContent: `const increment = function(a: number): number { + return a + 1; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_EmptyReturn.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_EmptyReturn.ts new file mode 100644 index 00000000000..e77adca0eb8 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_EmptyReturn.ts @@ -0,0 +1,15 @@ +/// + +//// const foo = /*x*/f/*y*/unction() { +//// return; +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to arrow function", + actionDescription: "Convert to arrow function", + newContent: `const foo = () => { + return; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_FnArgument.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_FnArgument.ts new file mode 100644 index 00000000000..3dc442e4e5d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_FnArgument.ts @@ -0,0 +1,15 @@ +/// + +//// function foo(lambda){} +//// foo(function /*x*/is/*y*/Even(n) { +//// return n % 2 === 0; +//// }); + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to arrow function", + actionDescription: "Convert to arrow function", + newContent: `function foo(lambda){} +foo((n) => n % 2 === 0);`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MapArgument.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MapArgument.ts new file mode 100644 index 00000000000..4e1c0b2f9f5 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MapArgument.ts @@ -0,0 +1,13 @@ +/// + +//// [4,5,6,7].map(function /*x*/is/*y*/Even(n) { +//// return n % 2 === 0; +//// }); + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to arrow function", + actionDescription: "Convert to arrow function", + newContent: `[4,5,6,7].map((n) => n % 2 === 0);`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MultiLine.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MultiLine.ts new file mode 100644 index 00000000000..71855947b36 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MultiLine.ts @@ -0,0 +1,17 @@ +/// + +//// const foo = /*x*/f/*y*/unction() { +//// let a = 41; +//// return a + 1; +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to arrow function", + actionDescription: "Convert to arrow function", + newContent: `const foo = () => { + let a = 41; + return a + 1; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MultiLine_Comment.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MultiLine_Comment.ts new file mode 100644 index 00000000000..470cae1c446 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MultiLine_Comment.ts @@ -0,0 +1,25 @@ +/// + +//// const foo = /*x*/f/*y*/unction() { +//// // secret +//// let a = 41; +//// /* +//// msg +//// */ +//// return a + 1; +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to arrow function", + actionDescription: "Convert to arrow function", + newContent: `const foo = () => { + // secret + let a = 41; + /* + msg + */ + return a + 1; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Param.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Param.ts new file mode 100644 index 00000000000..a7659080998 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Param.ts @@ -0,0 +1,13 @@ +/// + +//// const foo = /*x*/f/*y*/unction(a, b, c) { +//// return a + b + c; +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to arrow function", + actionDescription: "Convert to arrow function", + newContent: `const foo = (a, b, c) => a + b + c;`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Assign.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Assign.ts new file mode 100644 index 00000000000..f5e15ab8ac9 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Assign.ts @@ -0,0 +1,17 @@ +/// + +//// let bar; +//// const foo = /*x*/f/*y*/unction() { +//// bar = 42; +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to arrow function", + actionDescription: "Convert to arrow function", + newContent: `let bar; +const foo = () => { + bar = 42; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Decl.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Decl.ts new file mode 100644 index 00000000000..e1f15b78f3d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Decl.ts @@ -0,0 +1,15 @@ +/// + +//// const foo = /*x*/f/*y*/unction() { +//// let bar; +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to arrow function", + actionDescription: "Convert to arrow function", + newContent: `const foo = () => { + let bar; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_FnCall.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_FnCall.ts new file mode 100644 index 00000000000..af8068699df --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_FnCall.ts @@ -0,0 +1,17 @@ +/// + +//// function s(){} +//// const foo = /*x*/f/*y*/unction() { +//// s(); +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to arrow function", + actionDescription: "Convert to arrow function", + newContent: `function s(){} +const foo = () => { + s(); +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_For.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_For.ts new file mode 100644 index 00000000000..a0da4868b0e --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_For.ts @@ -0,0 +1,15 @@ +/// + +//// const foo = /*x*/f/*y*/unction() { +//// for (let i = 0; i < 5; i++) { } +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to arrow function", + actionDescription: "Convert to arrow function", + newContent: `const foo = () => { + for (let i = 0; i < 5; i++) { } +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_If.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_If.ts new file mode 100644 index 00000000000..65084f0f3a9 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_If.ts @@ -0,0 +1,15 @@ +/// + +//// const foo = /*x*/f/*y*/unction() { +//// if (true) { } +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to arrow function", + actionDescription: "Convert to arrow function", + newContent: `const foo = () => { + if (true) { } +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Return.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Return.ts new file mode 100644 index 00000000000..c901046de3e --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Return.ts @@ -0,0 +1,13 @@ +/// + +//// const foo = /*x*/f/*y*/unction() { +//// return 42; +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to arrow function", + actionDescription: "Convert to arrow function", + newContent: `const foo = () => 42;`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_While.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_While.ts new file mode 100644 index 00000000000..830a9b4933b --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_While.ts @@ -0,0 +1,15 @@ +/// + +//// const foo = /*x*/f/*y*/unction() { +//// while (true) { } +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to arrow function", + actionDescription: "Convert to arrow function", + newContent: `const foo = () => { + while (true) { } +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Typed.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Typed.ts new file mode 100644 index 00000000000..01d30d1f080 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Typed.ts @@ -0,0 +1,13 @@ +/// + +//// const concat = /*x*/f/*y*/unction(a: string, b: string): string { +//// return a + b; +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to arrow function", + actionDescription: "Convert to arrow function", + newContent: `const concat = (a: string, b: string): string => a + b;`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Comment.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Comment.ts new file mode 100644 index 00000000000..8f615da85ef --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Comment.ts @@ -0,0 +1,23 @@ +/// + +//// const foo = /*x*/a/*y*/ => { +//// // secret word +//// return a + 1; +//// /* +//// hidden msg +//// */ +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to named function", + actionDescription: "Convert to named function", + newContent: `function foo(a) { + // secret word + return a + 1; + /* + hidden msg + */ +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Modifier.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Modifier.ts new file mode 100644 index 00000000000..9d60d172397 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Modifier.ts @@ -0,0 +1,17 @@ +/// + +//// export let foo = /*x*/a/*y*/ => { +//// let b = 1; +//// return a + b; +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to named function", + actionDescription: "Convert to named function", + newContent: `export function foo(a) { + let b = 1; + return a + b; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Modifier_Comment.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Modifier_Comment.ts new file mode 100644 index 00000000000..20bb3885590 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Modifier_Comment.ts @@ -0,0 +1,19 @@ +/// + +//// // Do not add me second time +//// export let foo = /*x*/a/*y*/ => { +//// let b = 1; +//// return a + b; +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to named function", + actionDescription: "Convert to named function", + newContent: `// Do not add me second time +export function foo(a) { + let b = 1; + return a + b; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl.ts new file mode 100644 index 00000000000..789eb98141d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl.ts @@ -0,0 +1,15 @@ +/// + +//// let foo, bar = /*x*/(/*y*/) => 1 + 1, magicNo; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to named function", + actionDescription: "Convert to named function", + newContent: `let foo, magicNo; +function bar() { + return 1 + 1; +} +`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_Modifier.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_Modifier.ts new file mode 100644 index 00000000000..4044d76ad2a --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_Modifier.ts @@ -0,0 +1,15 @@ +/// + +//// export let foo, bar = /*x*/(/*y*/) => 1 + 1; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to named function", + actionDescription: "Convert to named function", + newContent: `export let foo; +export function bar() { + return 1 + 1; +} +`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_Modifier_Comment.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_Modifier_Comment.ts new file mode 100644 index 00000000000..46fc080ebda --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_Modifier_Comment.ts @@ -0,0 +1,17 @@ +/// + +//// // Do not add me second time +//// export let foo, bar = /*x*/(/*y*/) => 1 + 1; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to named function", + actionDescription: "Convert to named function", + newContent: `// Do not add me second time +export let foo; +export function bar() { + return 1 + 1; +} +`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_VarSelection.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_VarSelection.ts new file mode 100644 index 00000000000..6757cb15609 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_VarSelection.ts @@ -0,0 +1,15 @@ +/// + +//// let foo, /*x*/b/*y*/ar = a => 1 + a; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to named function", + actionDescription: "Convert to named function", + newContent: `let foo; +function bar(a) { + return 1 + a; +} +`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiLine.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiLine.ts new file mode 100644 index 00000000000..ef2866f783e --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiLine.ts @@ -0,0 +1,17 @@ +/// + +//// let foo = /*x*/a/*y*/ => { +//// let b = 1; +//// return a + b; +//// }; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to named function", + actionDescription: "Convert to named function", + newContent: `function foo(a) { + let b = 1; + return a + b; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiParam.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiParam.ts new file mode 100644 index 00000000000..0036f11136d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiParam.ts @@ -0,0 +1,13 @@ +/// + +//// let foo = /*x*/(/*y*/a,b,c) => a + 1; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to named function", + actionDescription: "Convert to named function", + newContent: `function foo(a, b, c) { + return a + 1; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_SingleLine.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_SingleLine.ts new file mode 100644 index 00000000000..4952856d87f --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_SingleLine.ts @@ -0,0 +1,13 @@ +/// + +//// let foo = /*x*/(/*y*/) => 1 + 1; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to named function", + actionDescription: "Convert to named function", + newContent: `function foo() { + return 1 + 1; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Typed.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Typed.ts new file mode 100644 index 00000000000..6a67c390bd4 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Typed.ts @@ -0,0 +1,13 @@ +/// + +//// let isFoo = /*x*/(/*y*/n: number): boolean => n === 42; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to named function", + actionDescription: "Convert to named function", + newContent: `function isFoo(n: number): boolean { + return n === 42; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_keywordSelection.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_keywordSelection.ts new file mode 100644 index 00000000000..2e2f1b2b14d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_keywordSelection.ts @@ -0,0 +1,13 @@ +/// + +//// /*x*/let/*y*/ foo = a => 1 + a; + +goTo.select("x", "y"); +edit.applyRefactor({ + refactorName: "Convert arrow function or function expression", + actionName: "Convert to named function", + actionDescription: "Convert to named function", + newContent: `function foo(a) { + return 1 + a; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertExportForTriggerReason.ts b/tests/cases/fourslash/refactorConvertExportForTriggerReason.ts new file mode 100644 index 00000000000..9735acb5132 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertExportForTriggerReason.ts @@ -0,0 +1,8 @@ +/// + +////export /*a*//*b*/function f() {} + +// Only offer refactor for empty span if explicity requested +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert export"); +verify.refactorAvailableForTriggerReason("invoked", "Convert export"); diff --git a/tests/cases/fourslash/refactorConvertImportForTriggerReason1.ts b/tests/cases/fourslash/refactorConvertImportForTriggerReason1.ts new file mode 100644 index 00000000000..72e8a6f8e1b --- /dev/null +++ b/tests/cases/fourslash/refactorConvertImportForTriggerReason1.ts @@ -0,0 +1,8 @@ +/// + +////import /*a*//*b*/d, * as n from "m"; + +// Only offer refactor for empty span if explicity requested +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert import"); +verify.refactorAvailableForTriggerReason("invoked", "Convert import"); diff --git a/tests/cases/fourslash/refactorConvertImportForTriggerReason2.ts b/tests/cases/fourslash/refactorConvertImportForTriggerReason2.ts new file mode 100644 index 00000000000..1404ade7348 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertImportForTriggerReason2.ts @@ -0,0 +1,8 @@ +/// + +////import d, * as /*a*/n/*b*/ from "m"; + +// Only offer refactor for sub span if explicity requested +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert import"); +verify.refactorAvailableForTriggerReason("invoked", "Convert import"); diff --git a/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_escapedBackslashes.ts b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_escapedBackslashes.ts new file mode 100644 index 00000000000..6025107ff03 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_escapedBackslashes.ts @@ -0,0 +1,15 @@ +/// + +//// console.log(/*0*/"\\[[" + text + "](" + link + ")\\]"/*1*/) + +goTo.select("0", "1"); +edit.applyRefactor({ + refactorName: "Convert to template string", + actionName: "Convert to template string", + actionDescription: ts.Diagnostics.Convert_to_template_string.message, + // Four backslashes here + // = two backslashes in the expected file content + // = one backslash in the string data sent to console.log + // (which is the same as what the user started with) + newContent: 'console.log(`\\\\[[${text}](${link})\\\\]`)', +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess14.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess14.ts index 095cc4fdd79..c3c6c824fbe 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess14.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess14.ts @@ -4,14 +4,13 @@ //// /*a*/public readonly a: string = "foo";/*b*/ //// } -goTo.select("a", "b"); goTo.select("a", "b"); edit.applyRefactor({ refactorName: "Generate 'get' and 'set' accessors", actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private /*RENAME*/_a: string = "foo"; + private readonly /*RENAME*/_a: string = "foo"; public get a(): string { return this._a; } diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess33.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess33.ts index aa224b8b31b..f490c27f714 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess33.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess33.ts @@ -22,7 +22,7 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private /*RENAME*/_a: number; + private readonly /*RENAME*/_a: number; public get a(): number { return this._a; } diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess36.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess36.ts new file mode 100644 index 00000000000..c5f82c3c440 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess36.ts @@ -0,0 +1,28 @@ +/// + +////class Foo { +//// /** +//// * Property description +//// */ +//// /*a*/_prop!: string; // comment/*b*/ +////} + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: +`class Foo { + /** + * Property description + */ + private _prop!: string; // comment + public get /*RENAME*/prop(): string { + return this._prop; + } + public set prop(value: string) { + this._prop = value; + } +}` +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAndSetAccessForTriggerReason.ts b/tests/cases/fourslash/refactorConvertToGetAndSetAccessForTriggerReason.ts new file mode 100644 index 00000000000..a6edb03c95f --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAndSetAccessForTriggerReason.ts @@ -0,0 +1,10 @@ +/// + +//// class A { +//// public /*a*//*b*/a: string; +//// } + +// Only offer refactor for empty span if explicity requested +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Generate 'get' and 'set' accessors"); +verify.refactorAvailableForTriggerReason("invoked", "Generate 'get' and 'set' accessors"); diff --git a/tests/cases/fourslash/refactorExtractTypeForTriggerReason1.ts b/tests/cases/fourslash/refactorExtractTypeForTriggerReason1.ts new file mode 100644 index 00000000000..4bc28336657 --- /dev/null +++ b/tests/cases/fourslash/refactorExtractTypeForTriggerReason1.ts @@ -0,0 +1,8 @@ +/// + +//// var x: str/*a*//*b*/ing; + +// Only offer refactor for empty span if explicity requested +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Extract type"); +verify.refactorAvailableForTriggerReason("invoked", "Extract type"); diff --git a/tests/cases/fourslash/refactorExtractTypeForTriggerReason2.ts b/tests/cases/fourslash/refactorExtractTypeForTriggerReason2.ts new file mode 100644 index 00000000000..0f81c3cc88b --- /dev/null +++ b/tests/cases/fourslash/refactorExtractTypeForTriggerReason2.ts @@ -0,0 +1,7 @@ +/// + +//// var x: s/*a*/tr/*b*/ing; + +goTo.select("a", "b"); +verify.refactorAvailableForTriggerReason("implicit", "Extract type"); +verify.refactorAvailableForTriggerReason("invoked", "Extract type"); diff --git a/tests/cases/fourslash/refactorOverloadListToSingleSignature1.ts b/tests/cases/fourslash/refactorOverloadListToSingleSignature1.ts new file mode 100644 index 00000000000..b2be8adb43d --- /dev/null +++ b/tests/cases/fourslash/refactorOverloadListToSingleSignature1.ts @@ -0,0 +1,14 @@ +/// + +/////*a*/declare function foo(): void; +////declare function foo(a: string): void; +////declare function foo(a: number, b: number): void; +////declare function foo(...rest: symbol[]): void;/*b*/ + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert overload list to single signature", + actionName: "Convert overload list to single signature", + actionDescription: ts.Diagnostics.Convert_overload_list_to_single_signature.message, + newContent: `declare function foo(...args: [] | [a: string] | [a: number, b: number] | [...rest: symbol[]]): void;`, +}); diff --git a/tests/cases/fourslash/refactorOverloadListToSingleSignature2.ts b/tests/cases/fourslash/refactorOverloadListToSingleSignature2.ts new file mode 100644 index 00000000000..8259dfb79b8 --- /dev/null +++ b/tests/cases/fourslash/refactorOverloadListToSingleSignature2.ts @@ -0,0 +1,49 @@ +/// + +/////*a*/declare function foo(): void; +/////** +//// * @param a a string param doc +//// */ +////declare function foo(a: string): void; +/////** +//// * @param a a number param doc +//// * @param b b number param doc +//// */ +////declare function foo(a: number, b: number): void; +/////** +//// * @param rest rest param doc +//// */ +////declare function foo(...rest: symbol[]): void;/*b*/ + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert overload list to single signature", + actionName: "Convert overload list to single signature", + actionDescription: ts.Diagnostics.Convert_overload_list_to_single_signature.message, +// we don't delete the param comment on the signature we update because deleting *part* of a comment is... hard +// and we definitely don't want to delete the whole comment. This is probably a good argument for why jsdoc should +// really be uniformly handled as AST nodes, and transformed as such :( +newContent: `/** + * @param rest rest param doc + */ +declare function foo(...args: [] | [ + /** + * a string param doc + */ + a: string +] | [ + /** + * a number param doc + */ + a: number, + /** + * b number param doc + */ + b: number +] | [ + /** + * rest param doc + */ + ...rest: symbol[] +]): void;`, +}); diff --git a/tests/cases/fourslash/refactorOverloadListToSingleSignature3.ts b/tests/cases/fourslash/refactorOverloadListToSingleSignature3.ts new file mode 100644 index 00000000000..1de08f5852e --- /dev/null +++ b/tests/cases/fourslash/refactorOverloadListToSingleSignature3.ts @@ -0,0 +1,19 @@ +/// + +/////*a*/function foo(): void; +////function foo(a: string): void; +////function foo(a: number, b: number): void; +////function foo(...rest: symbol[]): void;/*b*/ +////function foo(...args: any[]): void { +//// // body +////} + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert overload list to single signature", + actionName: "Convert overload list to single signature", + actionDescription: ts.Diagnostics.Convert_overload_list_to_single_signature.message, + newContent: `function foo(...args: [] | [a: string] | [a: number, b: number] | [...rest: symbol[]]): void { + // body +}`, +}); diff --git a/tests/cases/fourslash/refactorOverloadListToSingleSignature4.ts b/tests/cases/fourslash/refactorOverloadListToSingleSignature4.ts new file mode 100644 index 00000000000..d42130fc0f6 --- /dev/null +++ b/tests/cases/fourslash/refactorOverloadListToSingleSignature4.ts @@ -0,0 +1,23 @@ +/// + +////class A { +//// /*a*/foo(): void; +//// foo(a: string): void; +//// foo(a: number, b: number): void; +//// foo(...rest: symbol[]): void;/*b*/ +//// foo(...args: any[]): void { +//// // body +//// } +////} + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert overload list to single signature", + actionName: "Convert overload list to single signature", + actionDescription: ts.Diagnostics.Convert_overload_list_to_single_signature.message, + newContent: `class A { + foo(...args: [] | [a: string] | [a: number, b: number] | [...rest: symbol[]]): void { + // body + } +}`, +}); diff --git a/tests/cases/fourslash/refactorOverloadListToSingleSignature5.ts b/tests/cases/fourslash/refactorOverloadListToSingleSignature5.ts new file mode 100644 index 00000000000..d8aabb038fd --- /dev/null +++ b/tests/cases/fourslash/refactorOverloadListToSingleSignature5.ts @@ -0,0 +1,23 @@ +/// + +////class A { +//// /*a*/constructor(); +//// constructor(a: string); +//// constructor(a: number, b: number); +//// constructor(...rest: symbol[]);/*b*/ +//// constructor(...args: any[]) { +//// // body +//// } +////} + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert overload list to single signature", + actionName: "Convert overload list to single signature", + actionDescription: ts.Diagnostics.Convert_overload_list_to_single_signature.message, + newContent: `class A { + constructor(...args: [] | [a: string] | [a: number, b: number] | [...rest: symbol[]]) { + // body + } +}`, +}); diff --git a/tests/cases/fourslash/refactorOverloadListToSingleSignature6.ts b/tests/cases/fourslash/refactorOverloadListToSingleSignature6.ts new file mode 100644 index 00000000000..0c3c0143f26 --- /dev/null +++ b/tests/cases/fourslash/refactorOverloadListToSingleSignature6.ts @@ -0,0 +1,18 @@ +/// + +////interface A { +//// /*a*/(): void; +//// (a: string): void; +//// (a: number, b: number): void; +//// (...rest: symbol[]): void;/*b*/ +////} + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert overload list to single signature", + actionName: "Convert overload list to single signature", + actionDescription: ts.Diagnostics.Convert_overload_list_to_single_signature.message, + newContent: `interface A { + (...args: [] | [a: string] | [a: number, b: number] | [...rest: symbol[]]): void; +}`, +}); diff --git a/tests/cases/fourslash/refactorOverloadListToSingleSignature7.ts b/tests/cases/fourslash/refactorOverloadListToSingleSignature7.ts new file mode 100644 index 00000000000..90a638be021 --- /dev/null +++ b/tests/cases/fourslash/refactorOverloadListToSingleSignature7.ts @@ -0,0 +1,18 @@ +/// + +////interface A { +//// /*a*/new (): void; +//// new (a: string): void; +//// new (a: number, b: number): void; +//// new (...rest: symbol[]): void;/*b*/ +////} + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert overload list to single signature", + actionName: "Convert overload list to single signature", + actionDescription: ts.Diagnostics.Convert_overload_list_to_single_signature.message, + newContent: `interface A { + new(...args: [] | [a: string] | [a: number, b: number] | [...rest: symbol[]]): void; +}`, +}); diff --git a/tests/cases/fourslash/refactorOverloadListToSingleSignature8.ts b/tests/cases/fourslash/refactorOverloadListToSingleSignature8.ts new file mode 100644 index 00000000000..a540e8544a5 --- /dev/null +++ b/tests/cases/fourslash/refactorOverloadListToSingleSignature8.ts @@ -0,0 +1,18 @@ +/// + +////interface A { +//// /*a*/foo(): void; +//// foo(a: string): void; +//// foo(a: number, b: number): void; +//// foo(...rest: symbol[]): void;/*b*/ +////} + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert overload list to single signature", + actionName: "Convert overload list to single signature", + actionDescription: ts.Diagnostics.Convert_overload_list_to_single_signature.message, + newContent: `interface A { + foo(...args: [] | [a: string] | [a: number, b: number] | [...rest: symbol[]]): void; +}`, +}); diff --git a/tests/cases/fourslash/renameImportSpecifierPropertyName.ts b/tests/cases/fourslash/renameImportSpecifierPropertyName.ts new file mode 100644 index 00000000000..fa4d13929a0 --- /dev/null +++ b/tests/cases/fourslash/renameImportSpecifierPropertyName.ts @@ -0,0 +1,9 @@ +/// + +// @Filename: canada.ts +////export interface /**/Ginger {} + +// @Filename: dry.ts +////import { Ginger as Ale } from './canada'; + +verify.baselineRename("", {}); diff --git a/tests/cases/fourslash/renameModuleExportsProperties1.ts b/tests/cases/fourslash/renameModuleExportsProperties1.ts new file mode 100644 index 00000000000..29d74bde6cb --- /dev/null +++ b/tests/cases/fourslash/renameModuleExportsProperties1.ts @@ -0,0 +1,8 @@ +/// + +////[|class [|{| "contextRangeIndex": 0 |}A|] {}|] +////module.exports = { [|A|] } + +const [r0Def, r0, r1] = test.ranges(); +verify.renameLocations(r0, { ranges: [r0, { range: r1, prefixText: "A: " }], providePrefixAndSuffixTextForRename: true }); +verify.renameLocations(r1, { ranges: [r0, { range: r1, prefixText: "A: " }], providePrefixAndSuffixTextForRename: true }); diff --git a/tests/cases/fourslash/renameModuleExportsProperties2.ts b/tests/cases/fourslash/renameModuleExportsProperties2.ts new file mode 100644 index 00000000000..fa2c31029e6 --- /dev/null +++ b/tests/cases/fourslash/renameModuleExportsProperties2.ts @@ -0,0 +1,8 @@ +/// + +////[|class [|{| "contextRangeIndex": 0 |}A|] {}|] +////module.exports = { B: [|A|] } + +const [r0Def, r0, r1] = test.ranges(); +verify.renameLocations(r0, [r0, r1]); +verify.renameLocations(r1, [r0, r1]); diff --git a/tests/cases/fourslash/renameModuleExportsProperties3.ts b/tests/cases/fourslash/renameModuleExportsProperties3.ts new file mode 100644 index 00000000000..2f163c55f0f --- /dev/null +++ b/tests/cases/fourslash/renameModuleExportsProperties3.ts @@ -0,0 +1,10 @@ +/// + +// @allowJs: true +// @Filename: a.js +////[|class [|{| "contextRangeIndex": 0 |}A|] {}|] +////module.exports = { [|A|] } + +const [r0Def, r0, r1] = test.ranges(); +verify.renameLocations(r0, { ranges: [r0, { range: r1, prefixText: "A: " }], providePrefixAndSuffixTextForRename: true }); +verify.renameLocations(r1, { ranges: [r0, { range: r1, prefixText: "A: " }], providePrefixAndSuffixTextForRename: true }); diff --git a/tests/cases/fourslash/restArgType.ts b/tests/cases/fourslash/restArgType.ts index 69601c14ccf..057786489bf 100644 --- a/tests/cases/fourslash/restArgType.ts +++ b/tests/cases/fourslash/restArgType.ts @@ -38,12 +38,12 @@ verify.quickInfos({ 4: "(parameter) y1: string[]", 5: "(parameter) y2: string", - t1: "(parameter) f1: [string, string]", + t1: "(parameter) f1: [a1: string, a2: string]", - t2: "(parameter) f1: [string, ...string[]]", + t2: "(parameter) f1: [a1: string, ...a2: string[]]", t31: "(parameter) f1: number", - t32: "(parameter) f2: [boolean, ...string[]]", + t32: "(parameter) f2: [a2: boolean, ...c: string[]]", t4: "(parameter) f1: string[]", t5: "(parameter) f1: string", diff --git a/tests/cases/fourslash/server/jsdocCallbackTag.ts b/tests/cases/fourslash/server/jsdocCallbackTag.ts index 1d754c08608..315ad0ee173 100644 --- a/tests/cases/fourslash/server/jsdocCallbackTag.ts +++ b/tests/cases/fourslash/server/jsdocCallbackTag.ts @@ -30,9 +30,9 @@ verify.quickInfoIs("var t: FooHandler"); goTo.marker("2"); verify.quickInfoIs("var t2: FooHandler2"); goTo.marker("3"); -verify.quickInfoIs("type FooHandler2 = (eventName?: string, eventName2?: string) => any", "- What, another one?"); +verify.quickInfoIs("type FooHandler2 = (eventName?: string | undefined, eventName2?: string) => any", "- What, another one?"); goTo.marker("8"); -verify.quickInfoIs("type FooHandler = (eventName: string, eventName2: string | number, eventName3: any) => number", "- A kind of magic"); +verify.quickInfoIs("type FooHandler = (eventName: string, eventName2: number | string, eventName3: any) => number", "- A kind of magic"); verify.signatureHelp({ marker: '4', text: "t(eventName: string, eventName2: string | number, eventName3: any): number", diff --git a/tests/cases/fourslash/signatureHelpExpandedRestTuples.ts b/tests/cases/fourslash/signatureHelpExpandedRestTuples.ts new file mode 100644 index 00000000000..2808a8eb88e --- /dev/null +++ b/tests/cases/fourslash/signatureHelpExpandedRestTuples.ts @@ -0,0 +1,36 @@ +/// + +////export function complex(item: string, another: string, ...rest: [] | [settings: object, errorHandler: (err: Error) => void] | [errorHandler: (err: Error) => void, ...mixins: object[]]) { +//// +////} +//// +////complex(/*1*/); +////complex("ok", "ok", /*2*/); +////complex("ok", "ok", e => void e, {}, /*3*/); + +verify.signatureHelp( + { + marker: "1", + text: "complex(item: string, another: string): void", + overloadsCount: 3, + parameterCount: 2, + parameterName: "item", + parameterSpan: "item: string", + isVariadic: false, + }, + { + marker: "2", + text: "complex(item: string, another: string, settings: object, errorHandler: (err: Error) => void): void", + overloadsCount: 3, + parameterCount: 4, + parameterName: "settings", + parameterSpan: "settings: object", + isVariadic: false, + }, + { + marker: "3", + text: "complex(item: string, another: string, errorHandler: (err: Error) => void, ...mixins: object[]): void", + overloadsCount: 3, + isVariadic: true, + }, +); diff --git a/tests/cases/fourslash/signatureHelpForSignatureWithUnreachableType.ts b/tests/cases/fourslash/signatureHelpForSignatureWithUnreachableType.ts new file mode 100644 index 00000000000..47d96d26f9c --- /dev/null +++ b/tests/cases/fourslash/signatureHelpForSignatureWithUnreachableType.ts @@ -0,0 +1,19 @@ +/// + +// @Filename: /node_modules/foo/node_modules/bar/index.d.ts +////export interface SomeType { +//// x?: number; +////} +// @Filename: /node_modules/foo/index.d.ts +////import { SomeType } from "bar"; +////export function func(param: T): void; +////export function func(param: T, other: T): void; +// @Filename: /usage.ts +////import { func } from "foo"; +////func({/*1*/}); + +verify.signatureHelp({ + marker: "1", + overloadsCount: 2, + text: "func(param: {}): void" +}); \ No newline at end of file diff --git a/tests/cases/fourslash/textChangesPreserveNewlines8.ts b/tests/cases/fourslash/textChangesPreserveNewlines8.ts new file mode 100644 index 00000000000..e74aef6c9d0 --- /dev/null +++ b/tests/cases/fourslash/textChangesPreserveNewlines8.ts @@ -0,0 +1,29 @@ +// #37813 + +/// + +////function foo() { +//// /*1*/var x: number +//// +//// x = 10; +//// return x;/*2*/ +////} + +goTo.select("1", "2"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to function in global scope", + newContent: +`function foo() { + return /*RENAME*/newFunction(); +} + +function newFunction() { + var x: number; + + x = 10; + return x; +} +` +}); diff --git a/tests/cases/user/ts-toolbelt/index.ts b/tests/cases/user/ts-toolbelt/index.ts index 218db6ba38d..6549c08f893 100644 --- a/tests/cases/user/ts-toolbelt/index.ts +++ b/tests/cases/user/ts-toolbelt/index.ts @@ -12,7 +12,7 @@ type StdRecursiveIteration extends T.Length // this form of recursion is preferred ? 1 // because it will let the user know if : 0 // the instantiation depth has been hit -]; // (but error is sometimes swallowed (?)) +]; checks([ check, 40, Test.Pass>(), // max length is 40 ]); - -// iterates over `T` and returns the `Iteration` position when finished -type SafeRecursiveIteration> = { - 0: SafeRecursiveIteration>; - 1: I.Pos; -}[ - I.Key extends T.Length // this form of recursion is the safest - ? 1 // because `T.Length` will force - : 0 // the length to comply with the limits -]; // => won't compute if excessive length - -checks([ - check, 0, Test.Pass>() // did not compute -]); diff --git a/tests/cases/user/zone.js/tsconfig.json b/tests/cases/user/zone.js/tsconfig.json index 30e1ee5dc63..eda9e3f6287 100644 --- a/tests/cases/user/zone.js/tsconfig.json +++ b/tests/cases/user/zone.js/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "strict": true, "lib": ["esnext", "dom"], - "types": [] + "types": ["node"] }, "files": [ "index.ts",