Skip to content

Commit 2f91510

Browse files
authored
Don't use cached type node when expanding (#4050)
1 parent a4c6528 commit 2f91510

4 files changed

Lines changed: 265 additions & 8 deletions

File tree

internal/checker/nodebuilderimpl.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3000,7 +3000,9 @@ func (b *NodeBuilderImpl) visitAndTransformType(t *Type, transform func(b *NodeB
30003000
// of types allows us to catch circular references to instantiations of the same anonymous type
30013001

30023002
key := CompositeTypeCacheIdentity{typeId, b.ctx.flags, b.ctx.internalFlags}
3003-
if b.ctx.maxExpansionDepth <= 0 && b.ctx.enclosingDeclaration != nil && b.links.Has(b.ctx.enclosingDeclaration) {
3003+
// Don't rely on type cache if we're expanding a type, because we need to compute `canIncreaseExpansionDepth`.
3004+
canUseCache := b.ctx.maxExpansionDepth < 0
3005+
if canUseCache && b.ctx.enclosingDeclaration != nil && b.links.Has(b.ctx.enclosingDeclaration) {
30043006
links := b.links.Get(b.ctx.enclosingDeclaration)
30053007
cachedResult, ok := links.serializedTypes[key]
30063008
if ok {
@@ -3030,7 +3032,7 @@ func (b *NodeBuilderImpl) visitAndTransformType(t *Type, transform func(b *NodeB
30303032
startLength := b.ctx.approximateLength
30313033
result := transform(b, t)
30323034
addedLength := b.ctx.approximateLength - startLength
3033-
if !b.ctx.reportedDiagnostic && !b.ctx.encounteredError {
3035+
if canUseCache && !b.ctx.reportedDiagnostic && !b.ctx.encounteredError {
30343036
links := b.links.Get(b.ctx.enclosingDeclaration)
30353037
if links.serializedTypes == nil {
30363038
links.serializedTypes = make(map[CompositeTypeCacheIdentity]*SerializedTypeEntry)

internal/checker/printer.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,11 @@ func (c *Checker) typeToStringEx(t *Type, enclosingDeclaration *ast.Node, flags
198198
combinedFlags = combinedFlags | nodebuilder.FlagsNoTruncation
199199
}
200200
nodeBuilder := c.getNodeBuilder()
201-
if vc != nil {
202-
nodeBuilder.verbosity = vc
203-
}
201+
oldVerbosity := nodeBuilder.verbosity
202+
nodeBuilder.verbosity = vc
203+
defer func() {
204+
nodeBuilder.verbosity = oldVerbosity
205+
}()
204206
typeNode := nodeBuilder.TypeToTypeNode(t, enclosingDeclaration, combinedFlags, nodebuilder.InternalFlagsNone, nil)
205207
if typeNode == nil {
206208
panic("should always get typenode")
@@ -320,9 +322,11 @@ func (c *Checker) signatureToStringEx(signature *Signature, enclosingDeclaration
320322
}
321323

322324
nodeBuilder := c.getNodeBuilder()
323-
if vc != nil {
324-
nodeBuilder.verbosity = vc
325-
}
325+
oldVerbosity := nodeBuilder.verbosity
326+
nodeBuilder.verbosity = vc
327+
defer func() {
328+
nodeBuilder.verbosity = oldVerbosity
329+
}()
326330
combinedFlags := toNodeBuilderFlags(flags) | nodebuilder.FlagsIgnoreErrors | nodebuilder.FlagsWriteTypeParametersInQualifiedName
327331
sig := nodeBuilder.SignatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, combinedFlags, nodebuilder.InternalFlagsNone, nil)
328332
p := createPrinterWithRemoveCommentsOmitTrailingSemicolonNeverAsciiEscape(nodeBuilder.EmitContext())
@@ -412,7 +416,11 @@ func (c *Checker) SignatureToSignatureDeclaration(signature *Signature, kind ast
412416
// ExpandSymbolForHover produces declaration strings for a symbol with verbosity support for expandable hover.
413417
func (c *Checker) ExpandSymbolForHover(symbol *ast.Symbol, meaning ast.SymbolFlags, vc *VerbosityContext) string {
414418
nodeBuilder := c.getNodeBuilder()
419+
oldVerbosity := nodeBuilder.verbosity
415420
nodeBuilder.verbosity = vc
421+
defer func() {
422+
nodeBuilder.verbosity = oldVerbosity
423+
}()
416424
nodes := nodeBuilder.ExpandSymbolForHover(symbol, meaning)
417425
if len(nodes) == 0 {
418426
return ""
@@ -435,7 +443,11 @@ func (c *Checker) ExpandSymbolForHover(symbol *ast.Symbol, meaning ast.SymbolFla
435443
// TypeParameterToStringEx renders a type parameter declaration (e.g. "T extends Foo") with optional verbosity support.
436444
func (c *Checker) TypeParameterToStringEx(t *Type, enclosingDeclaration *ast.Node, vc *VerbosityContext) string {
437445
nodeBuilder := c.getNodeBuilder()
446+
oldVerbosity := nodeBuilder.verbosity
438447
nodeBuilder.verbosity = vc
448+
defer func() {
449+
nodeBuilder.verbosity = oldVerbosity
450+
}()
439451
typeParamNode := nodeBuilder.TypeParameterToDeclaration(t, enclosingDeclaration, nodebuilder.FlagsIgnoreErrors, nodebuilder.InternalFlagsNone, nil)
440452
if typeParamNode == nil {
441453
return c.TypeToString(t)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package fourslash_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/microsoft/typescript-go/internal/fourslash"
7+
"github.com/microsoft/typescript-go/internal/testutil"
8+
)
9+
10+
func TestQuickinfoVerbosityIncreaseDecrease(t *testing.T) {
11+
fourslash.SkipIfFailing(t)
12+
t.Parallel()
13+
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
14+
const content = `export const JOB_STATES = ["created", "active", "completed", "failed", "retry", "cancelled", "archive"] as const
15+
export type JobState = (typeof JOB_STATES)[number]
16+
type Color = "default" | "primary" | "secondary" | "success" | "warning" | "danger"
17+
const JobsStateToColor/*a*/: Record<
18+
JobState,
19+
{
20+
color: Color
21+
label: string
22+
labelPlural: string
23+
}
24+
> = {
25+
created: {
26+
color: "success",
27+
label: "Направљен",
28+
labelPlural: "Направљени",
29+
},
30+
active: {
31+
color: "success",
32+
label: "Активан",
33+
labelPlural: "Активни",
34+
},
35+
completed: {
36+
color: "success",
37+
label: "Успешан",
38+
labelPlural: "Успешни",
39+
},
40+
cancelled: {
41+
color: "default",
42+
label: "Отаказан",
43+
labelPlural: "Отаказни",
44+
},
45+
failed: {
46+
color: "danger",
47+
label: "Пао",
48+
labelPlural: "Пали",
49+
},
50+
archive: {
51+
color: "default",
52+
label: "Архивиран",
53+
labelPlural: "Архивирани",
54+
},
55+
retry: {
56+
color: "warning",
57+
label: "Понавља се",
58+
labelPlural: "Понављају се",
59+
},
60+
}`
61+
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
62+
defer done()
63+
f.VerifyBaselineHoverWithVerbosity(t, map[string][]int{"a": {0, 1, 0}})
64+
}
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
// === QuickInfo ===
2+
=== /quickinfoVerbosityIncreaseDecrease.ts ===
3+
// export const JOB_STATES = ["created", "active", "completed", "failed", "retry", "cancelled", "archive"] as const
4+
// export type JobState = (typeof JOB_STATES)[number]
5+
// type Color = "default" | "primary" | "secondary" | "success" | "warning" | "danger"
6+
// const JobsStateToColor: Record<
7+
// ^^^^^^^^^^^^^^^^
8+
// | ----------------------------------------------------------------------
9+
// | ```typescript
10+
// | const JobsStateToColor: Record<"active" | "archive" | "cancelled" | "completed" | "created" | "failed" | "retry", {
11+
// | color: Color;
12+
// | label: string;
13+
// | labelPlural: string;
14+
// | }>
15+
// | ```
16+
// |
17+
// | (verbosity level: 0)
18+
// | ----------------------------------------------------------------------
19+
// ^^^^^^^^^^^^^^^^
20+
// | ----------------------------------------------------------------------
21+
// | ```typescript
22+
// | const JobsStateToColor: Record<"active" | "archive" | "cancelled" | "completed" | "created" | "failed" | "retry", {
23+
// | color: "danger" | "default" | "primary" | "secondary" | "success" | "warning";
24+
// | label: string;
25+
// | labelPlural: string;
26+
// | }>
27+
// | ```
28+
// |
29+
// | (verbosity level: 1)
30+
// | ----------------------------------------------------------------------
31+
// ^^^^^^^^^^^^^^^^
32+
// | ----------------------------------------------------------------------
33+
// | ```typescript
34+
// | const JobsStateToColor: Record<"active" | "archive" | "cancelled" | "completed" | "created" | "failed" | "retry", {
35+
// | color: Color;
36+
// | label: string;
37+
// | labelPlural: string;
38+
// | }>
39+
// | ```
40+
// |
41+
// | (verbosity level: 0)
42+
// | ----------------------------------------------------------------------
43+
// JobState,
44+
// {
45+
// color: Color
46+
// label: string
47+
// labelPlural: string
48+
// }
49+
// > = {
50+
// created: {
51+
// color: "success",
52+
// label: "Направљен",
53+
// labelPlural: "Направљени",
54+
// },
55+
// active: {
56+
// color: "success",
57+
// label: "Активан",
58+
// labelPlural: "Активни",
59+
// },
60+
// completed: {
61+
// color: "success",
62+
// label: "Успешан",
63+
// labelPlural: "Успешни",
64+
// },
65+
// cancelled: {
66+
// color: "default",
67+
// label: "Отаказан",
68+
// labelPlural: "Отаказни",
69+
// },
70+
// failed: {
71+
// color: "danger",
72+
// label: "Пао",
73+
// labelPlural: "Пали",
74+
// },
75+
// archive: {
76+
// color: "default",
77+
// label: "Архивиран",
78+
// labelPlural: "Архивирани",
79+
// },
80+
// retry: {
81+
// color: "warning",
82+
// label: "Понавља се",
83+
// labelPlural: "Понављају се",
84+
// },
85+
// }
86+
[
87+
{
88+
"marker": {
89+
"Position": 270,
90+
"LSPosition": {
91+
"line": 3,
92+
"character": 22
93+
},
94+
"Name": "a",
95+
"Data": {}
96+
},
97+
"item": {
98+
"hover": {
99+
"contents": {
100+
"kind": "markdown",
101+
"value": "```typescript\nconst JobsStateToColor: Record<\"active\" | \"archive\" | \"cancelled\" | \"completed\" | \"created\" | \"failed\" | \"retry\", {\n color: Color;\n label: string;\n labelPlural: string;\n}>\n```\n"
102+
},
103+
"range": {
104+
"start": {
105+
"line": 3,
106+
"character": 6
107+
},
108+
"end": {
109+
"line": 3,
110+
"character": 22
111+
}
112+
},
113+
"canIncreaseVerbosity": true
114+
},
115+
"verbosityLevel": 0
116+
}
117+
},
118+
{
119+
"marker": {
120+
"Position": 270,
121+
"LSPosition": {
122+
"line": 3,
123+
"character": 22
124+
},
125+
"Name": "a",
126+
"Data": {}
127+
},
128+
"item": {
129+
"hover": {
130+
"contents": {
131+
"kind": "markdown",
132+
"value": "```typescript\nconst JobsStateToColor: Record<\"active\" | \"archive\" | \"cancelled\" | \"completed\" | \"created\" | \"failed\" | \"retry\", {\n color: \"danger\" | \"default\" | \"primary\" | \"secondary\" | \"success\" | \"warning\";\n label: string;\n labelPlural: string;\n}>\n```\n"
133+
},
134+
"range": {
135+
"start": {
136+
"line": 3,
137+
"character": 6
138+
},
139+
"end": {
140+
"line": 3,
141+
"character": 22
142+
}
143+
}
144+
},
145+
"verbosityLevel": 1
146+
}
147+
},
148+
{
149+
"marker": {
150+
"Position": 270,
151+
"LSPosition": {
152+
"line": 3,
153+
"character": 22
154+
},
155+
"Name": "a",
156+
"Data": {}
157+
},
158+
"item": {
159+
"hover": {
160+
"contents": {
161+
"kind": "markdown",
162+
"value": "```typescript\nconst JobsStateToColor: Record<\"active\" | \"archive\" | \"cancelled\" | \"completed\" | \"created\" | \"failed\" | \"retry\", {\n color: Color;\n label: string;\n labelPlural: string;\n}>\n```\n"
163+
},
164+
"range": {
165+
"start": {
166+
"line": 3,
167+
"character": 6
168+
},
169+
"end": {
170+
"line": 3,
171+
"character": 22
172+
}
173+
},
174+
"canIncreaseVerbosity": true
175+
},
176+
"verbosityLevel": 0
177+
}
178+
}
179+
]

0 commit comments

Comments
 (0)