Skip to content

Commit 7a95cda

Browse files
committed
feat: add missing properties and JSX attributes code fixes
1 parent 6ad8c56 commit 7a95cda

37 files changed

Lines changed: 3473 additions & 115 deletions

‎tsc/internal/checker/exports.go‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,18 @@ func (c *Checker) GetPropertiesOfType(t *Type) []*ast.Symbol {
152152
return c.getPropertiesOfType(t)
153153
}
154154

155+
func (c *Checker) GetJsxAttributesType(node *ast.Node) *Type {
156+
return c.checkExpressionCached(node)
157+
}
158+
159+
func (c *Checker) GetUnmatchedProperties(source *Type, target *Type, requireOptionalProperties bool, matchDiscriminantProperties bool) []*ast.Symbol {
160+
return c.getUnmatchedProperties(source, target, requireOptionalProperties, matchDiscriminantProperties)
161+
}
162+
163+
func (c *Checker) IsDeeplyNestedType(t *Type, stack []*Type, maxDepth int) bool {
164+
return c.isDeeplyNestedType(t, stack, maxDepth)
165+
}
166+
155167
func (c *Checker) GetPropertyOfType(t *Type, name string) *ast.Symbol {
156168
return c.getPropertyOfType(t, name)
157169
}
@@ -172,6 +184,10 @@ func (c *Checker) IsPropertyAccessible(node *ast.Node, isSuper bool, isWrite boo
172184
return c.isPropertyAccessible(node, isSuper, isWrite, containingType, property)
173185
}
174186

187+
func (c *Checker) IsConstructorAccessible(node *ast.Node, signatures []*Signature) bool {
188+
return c.getConstructorAccessibilityError(node, signatures, ast.ModifierFlagsNonPublicAccessibilityModifier) == nil
189+
}
190+
175191
func (c *Checker) GetTypeOfPropertyOfContextualType(t *Type, name string) *Type {
176192
return c.getTypeOfPropertyOfContextualType(t, name)
177193
}
@@ -188,6 +204,10 @@ func (c *Checker) GetSignaturesOfType(t *Type, kind SignatureKind) []*Signature
188204
return c.getSignaturesOfType(t, kind)
189205
}
190206

207+
func (c *Checker) GetMinArgumentCount(signature *Signature) int {
208+
return c.getMinArgumentCount(signature)
209+
}
210+
191211
func (c *Checker) GetDeclaredTypeOfSymbol(symbol *ast.Symbol) *Type {
192212
return c.getDeclaredTypeOfSymbol(symbol)
193213
}

‎tsc/internal/fourslash/fourslash.go‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1687,6 +1687,7 @@ type VerifyCodeFixOptions struct {
16871687
// VerifyCodeFixAllOptions are the options for VerifyCodeFixAll.
16881688
type VerifyCodeFixAllOptions struct {
16891689
FixID string
1690+
Description string
16901691
NewFileContent string
16911692
}
16921693

@@ -1931,7 +1932,8 @@ func (f *FourslashTest) VerifyCodeFixAll(t *testing.T, options VerifyCodeFixAllO
19311932
// We look for actions that are NOT single-diagnostic fixes (i.e., have no Diagnostics attached).
19321933
var fixAllCandidates []*lsproto.CodeAction
19331934
for _, action := range actions {
1934-
if action.Diagnostics == nil || len(*action.Diagnostics) == 0 {
1935+
if (action.Diagnostics == nil || len(*action.Diagnostics) == 0) &&
1936+
(options.Description == "" || action.Title == options.Description) {
19351937
fixAllCandidates = append(fixAllCandidates, action)
19361938
}
19371939
}

‎tsc/internal/fourslash/tests/codeFixAddMissingAttributes10_test.go‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package fourslash_test
33
import (
44
"testing"
55

6+
"github.com/microsoft/TypeScript/tsc/internal/diagnostics"
67
"github.com/microsoft/TypeScript/tsc/internal/fourslash"
8+
"github.com/microsoft/TypeScript/tsc/internal/locale"
79
"github.com/microsoft/TypeScript/tsc/internal/testutil"
810
)
911

@@ -21,7 +23,8 @@ const A = (props: { [K in D]: K }) =>
2123
2224
const Bar = () =>
2325
[|<A></A>|]`
24-
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
26+
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content+addMissingAttributesJsxDeclarations)
2527
defer done()
26-
f.VerifyCodeFixNotAvailable(t, "fixMissingAttributes")
28+
f.VerifyNumberOfErrorsInCurrentFile(t, 1)
29+
f.VerifyCodeFixNotAvailable(t, diagnostics.Add_missing_attributes.Localize(locale.Default))
2730
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package fourslash_test
2+
3+
import (
4+
"strconv"
5+
"testing"
6+
7+
"github.com/microsoft/TypeScript/tsc/internal/diagnostics"
8+
"github.com/microsoft/TypeScript/tsc/internal/fourslash"
9+
"github.com/microsoft/TypeScript/tsc/internal/locale"
10+
"github.com/microsoft/TypeScript/tsc/internal/testutil"
11+
)
12+
13+
func TestCodeFixAddMissingAttributes11(t *testing.T) {
14+
t.Parallel()
15+
for i, test := range []struct {
16+
content string
17+
result string
18+
fileResult string
19+
filename string
20+
}{
21+
{
22+
content: `// @jsx: preserve
23+
// @Filename: a.tsx
24+
interface T { a: number; b?: string }
25+
const A = (a: T) => null;
26+
const a = [|<A />|];`,
27+
result: `<A a={0} />`,
28+
},
29+
{
30+
content: `// @jsx: preserve
31+
// @Filename: /a.ts
32+
export enum E { a, b }
33+
export class C {}
34+
// @Filename: /b.tsx
35+
import { E as B, C as D } from "./a";
36+
const A = (a: { a: B; b: D }) => null;
37+
const a = [|<A />|];`,
38+
result: `<A a={B.a} b={new D} />`,
39+
filename: "/b.tsx",
40+
},
41+
{
42+
content: `// @jsx: preserve
43+
// @Filename: a.tsx
44+
declare namespace JSX {
45+
interface Element {}
46+
interface ElementChildrenAttribute { children: {} }
47+
}
48+
const A = (a: { children: string; b: number }) => null;
49+
const a = [|<A>text</A>|];`,
50+
result: `<A b={0}>text</A>`,
51+
},
52+
{
53+
content: `// @jsx: preserve
54+
// @Filename: a.tsx
55+
declare namespace JSX {
56+
interface Element {}
57+
interface ElementChildrenAttribute { c: {} }
58+
}
59+
const A = (a: { c: string; b: number }) => null;
60+
const a = [|<A>{"text"}</A>|];`,
61+
result: `<A b={0}>{"text"}</A>`,
62+
},
63+
{
64+
content: `// @jsx: preserve
65+
// @Filename: a.tsx
66+
declare namespace JSX {
67+
interface Element {}
68+
interface ElementChildrenAttribute { children: {} }
69+
}
70+
const A = (a: { children: string; b: number }) => null;
71+
const a = [|<A>{}</A>|];`,
72+
result: `<A children={""} b={0}>{}</A>`,
73+
},
74+
{
75+
content: `// @jsx: preserve
76+
// @Filename: a.tsx
77+
const A = (a: { a: number; b: string }) => null;
78+
declare const b: { a?: number };
79+
const a = [|<A {...b} />|];`,
80+
result: `<A a={0} b={""} {...b} />`,
81+
},
82+
{
83+
content: `// @jsx: preserve
84+
// @Filename: a.tsx
85+
const A = (a: { a: number; b: string }) => null;
86+
declare const b: { a: number } | {};
87+
const a = [|<A {...b} />|];`,
88+
result: `<A a={0} b={""} {...b} />`,
89+
},
90+
{
91+
content: `// @jsx: preserve
92+
// @Filename: a.tsx
93+
const A = (a: { a: number; b: string }) => null;
94+
declare const b: { a?: number };
95+
const a = [|<A {...b} a={1} />|];`,
96+
result: `<A b={""} {...b} a={1} />`,
97+
},
98+
{
99+
content: `// @jsx: preserve
100+
// @Filename: a.tsx
101+
const A = (a: { a: number }) => null;
102+
declare const b: { a?: number };
103+
const a = [|<A {...b} />|];`,
104+
result: `<A a={0} {...b} />`,
105+
},
106+
{
107+
content: `// @jsx: preserve
108+
// @Filename: a.tsx
109+
const A = (a: { a: number; b: string }) => null;
110+
declare const b: { a?: number };
111+
declare const c: { a: number };
112+
const a = [|<A {...c} {...b} />|];`,
113+
result: `<A b={""} {...c} {...b} />`,
114+
},
115+
{
116+
content: `// @jsx: preserve
117+
// @Filename: /a.ts
118+
export enum E { a, b }
119+
export class C {}
120+
// @Filename: /b.tsx
121+
import type { C as D, E as B } from "./a";
122+
const A = (a: { a: B; b: D }) => null;
123+
const a = [|<A />|];`,
124+
fileResult: `import { C as D, E as B } from "./a";
125+
const A = (a: { a: B; b: D }) => null;
126+
const a = <A a={B.a} b={new D} />;`,
127+
filename: "/b.tsx",
128+
},
129+
} {
130+
t.Run(strconv.Itoa(i+1), func(t *testing.T) {
131+
t.Parallel()
132+
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
133+
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, test.content)
134+
defer done()
135+
if test.filename != "" {
136+
f.GoToFile(t, test.filename)
137+
}
138+
f.VerifyCodeFix(t, fourslash.VerifyCodeFixOptions{
139+
Description: diagnostics.Add_missing_attributes.Localize(locale.Default),
140+
NewFileContent: test.fileResult,
141+
NewRangeContent: test.result,
142+
ApplyChanges: true,
143+
})
144+
f.VerifyNoErrors(t)
145+
})
146+
}
147+
}

0 commit comments

Comments
 (0)