Skip to content

Commit 602c5eb

Browse files
dependabot[bot]github-actions[bot]buke
authored
deps(deps): bump microsoft/typescript-go from ffa30a7 to ea4e944 (#9)
* deps(deps): bump microsoft/typescript-go from `ffa30a7` to `ea4e944` Bumps [microsoft/typescript-go](https://github.com/microsoft/typescript-go) from `ffa30a7` to `ea4e944`. - [Commits](microsoft/typescript-go@ffa30a7...ea4e944) --- updated-dependencies: - dependency-name: microsoft/typescript-go dependency-version: ea4e944bb6880df9c9ca43093e183d8035f764fc dependency-type: direct:production ... Signed-off-by: dependabot[bot] <[email protected]> * chore(sync): mirror internal packages into pkg/ (auto) (#10) Co-authored-by: buke <[email protected]> --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: buke <[email protected]>
1 parent 4a04608 commit 602c5eb

File tree

167 files changed

+791
-1199
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

167 files changed

+791
-1199
lines changed

microsoft/typescript-go

Submodule typescript-go updated 167 files

pkg/ast/parseoptions.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ func GetSourceFileAffectingCompilerOptions(fileName string, options *core.Compil
3131
}
3232

3333
type ExternalModuleIndicatorOptions struct {
34-
jsx bool
35-
force bool
34+
JSX bool
35+
Force bool
3636
}
3737

3838
func GetExternalModuleIndicatorOptions(fileName string, options *core.CompilerOptions, metadata SourceFileMetaData) ExternalModuleIndicatorOptions {
@@ -43,7 +43,7 @@ func GetExternalModuleIndicatorOptions(fileName string, options *core.CompilerOp
4343
switch options.GetEmitModuleDetectionKind() {
4444
case core.ModuleDetectionKindForce:
4545
// All non-declaration files are modules, declaration files still do the usual isFileProbablyExternalModule
46-
return ExternalModuleIndicatorOptions{force: true}
46+
return ExternalModuleIndicatorOptions{Force: true}
4747
case core.ModuleDetectionKindLegacy:
4848
// Files are modules if they have imports, exports, or import.meta
4949
return ExternalModuleIndicatorOptions{}
@@ -52,8 +52,8 @@ func GetExternalModuleIndicatorOptions(fileName string, options *core.CompilerOp
5252
// If jsx is react-jsx or react-jsxdev then jsx tags force module-ness
5353
// otherwise, the presence of import or export statments (or import.meta) implies module-ness
5454
return ExternalModuleIndicatorOptions{
55-
jsx: options.Jsx == core.JsxEmitReactJSX || options.Jsx == core.JsxEmitReactJSXDev,
56-
force: isFileForcedToBeModuleByFormat(fileName, options, metadata),
55+
JSX: options.Jsx == core.JsxEmitReactJSX || options.Jsx == core.JsxEmitReactJSXDev,
56+
Force: isFileForcedToBeModuleByFormat(fileName, options, metadata),
5757
}
5858
default:
5959
return ExternalModuleIndicatorOptions{}
@@ -89,13 +89,13 @@ func getExternalModuleIndicator(file *SourceFile, opts ExternalModuleIndicatorOp
8989
return nil
9090
}
9191

92-
if opts.jsx {
92+
if opts.JSX {
9393
if node := isFileModuleFromUsingJSXTag(file); node != nil {
9494
return node
9595
}
9696
}
9797

98-
if opts.force {
98+
if opts.Force {
9999
return file.AsNode()
100100
}
101101

@@ -112,6 +112,9 @@ func isFileProbablyExternalModule(sourceFile *SourceFile) *Node {
112112
}
113113

114114
func isAnExternalModuleIndicatorNode(node *Node) bool {
115+
if node.Flags&NodeFlagsReparsed != 0 {
116+
return false
117+
}
115118
return HasSyntacticModifier(node, ModifierFlagsExport) ||
116119
IsImportEqualsDeclaration(node) && IsExternalModuleReference(node.AsImportEqualsDeclaration().ModuleReference) ||
117120
IsImportDeclaration(node) || IsExportAssignment(node) || IsExportDeclaration(node)

pkg/ast/utilities.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3921,3 +3921,12 @@ func HasContextSensitiveParameters(node *Node) bool {
39213921
func IsInfinityOrNaNString(name string) bool {
39223922
return name == "Infinity" || name == "-Infinity" || name == "NaN"
39233923
}
3924+
3925+
func GetFirstConstructorWithBody(node *Node) *Node {
3926+
for _, member := range node.Members() {
3927+
if IsConstructorDeclaration(member) && NodeIsPresent(member.Body()) {
3928+
return member
3929+
}
3930+
}
3931+
return nil
3932+
}

pkg/checker/checker.go

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,12 +1518,14 @@ func (c *Checker) onFailedToResolveSymbol(errorLocation *ast.Node, name string,
15181518
suggestion := c.getSuggestedSymbolForNonexistentSymbol(errorLocation, name, meaning)
15191519
if suggestion != nil && !(suggestion.ValueDeclaration != nil && ast.IsAmbientModule(suggestion.ValueDeclaration) && ast.IsGlobalScopeAugmentation(suggestion.ValueDeclaration)) {
15201520
suggestionName := c.symbolToString(suggestion)
1521-
message := core.IfElse(meaning == ast.SymbolFlagsNamespace, diagnostics.Cannot_find_namespace_0_Did_you_mean_1, diagnostics.Cannot_find_name_0_Did_you_mean_1)
1521+
isUncheckedJS := c.isUncheckedJSSuggestion(errorLocation, suggestion, false /*excludeClasses*/)
1522+
message := core.IfElse(meaning == ast.SymbolFlagsNamespace, diagnostics.Cannot_find_namespace_0_Did_you_mean_1,
1523+
core.IfElse(isUncheckedJS, diagnostics.Could_not_find_name_0_Did_you_mean_1, diagnostics.Cannot_find_name_0_Did_you_mean_1))
15221524
diagnostic := NewDiagnosticForNode(errorLocation, message, name, suggestionName)
15231525
if suggestion.ValueDeclaration != nil {
15241526
diagnostic.AddRelatedInfo(NewDiagnosticForNode(suggestion.ValueDeclaration, diagnostics.X_0_is_declared_here, suggestionName))
15251527
}
1526-
c.diagnostics.Add(diagnostic)
1528+
c.addErrorOrSuggestion(!isUncheckedJS, diagnostic)
15271529
return
15281530
}
15291531
// And then fall back to unspecified "not found"
@@ -10873,11 +10875,10 @@ func (c *Checker) checkPropertyAccessExpressionOrQualifiedName(node *ast.Node, l
1087310875
if c.checkPrivateIdentifierPropertyAccess(leftType, right, lexicallyScopedSymbol) {
1087410876
return c.errorType
1087510877
}
10876-
// !!!
10877-
// containingClass := getContainingClassExcludingClassDecorators(right)
10878-
// if containingClass && isPlainJSFile(ast.GetSourceFileOfNode(containingClass), c.compilerOptions.checkJs) {
10879-
// c.grammarErrorOnNode(right, diagnostics.Private_field_0_must_be_declared_in_an_enclosing_class, right.Text())
10880-
// }
10878+
containingClass := getContainingClassExcludingClassDecorators(right)
10879+
if containingClass != nil && ast.IsPlainJSFile(ast.GetSourceFileOfNode(containingClass), c.compilerOptions.CheckJs) {
10880+
c.grammarErrorOnNode(right, diagnostics.Private_field_0_must_be_declared_in_an_enclosing_class, right.Text())
10881+
}
1088110882
} else {
1088210883
isSetonlyAccessor := prop.Flags&ast.SymbolFlagsSetAccessor != 0 && prop.Flags&ast.SymbolFlagsGetAccessor == 0
1088310884
if isSetonlyAccessor && assignmentKind != AssignmentKindDefinite {
@@ -10904,6 +10905,10 @@ func (c *Checker) checkPropertyAccessExpressionOrQualifiedName(node *ast.Node, l
1090410905
indexInfo = c.getApplicableIndexInfoForName(apparentType, right.Text())
1090510906
}
1090610907
if indexInfo == nil {
10908+
isUncheckedJS := c.isUncheckedJSSuggestion(node, leftType.symbol, true /*excludeClasses*/)
10909+
if !isUncheckedJS && c.isJSLiteralType(leftType) {
10910+
return c.anyType
10911+
}
1090710912
if leftType.symbol == c.globalThisSymbol {
1090810913
globalSymbol := c.globalThisSymbol.Exports[right.Text()]
1090910914
if globalSymbol != nil && globalSymbol.Flags&ast.SymbolFlagsBlockScoped != 0 {
@@ -10914,7 +10919,7 @@ func (c *Checker) checkPropertyAccessExpressionOrQualifiedName(node *ast.Node, l
1091410919
return c.anyType
1091510920
}
1091610921
if right.Text() != "" && !c.checkAndReportErrorForExtendingInterface(node) {
10917-
c.reportNonexistentProperty(right, core.IfElse(isThisTypeParameter(leftType), apparentType, leftType))
10922+
c.reportNonexistentProperty(right, core.IfElse(isThisTypeParameter(leftType), apparentType, leftType), isUncheckedJS)
1091810923
}
1091910924
return c.errorType
1092010925
}
@@ -11091,7 +11096,7 @@ func (c *Checker) checkPrivateIdentifierPropertyAccess(leftType *Type, right *as
1109111096
return false
1109211097
}
1109311098

11094-
func (c *Checker) reportNonexistentProperty(propNode *ast.Node, containingType *Type) {
11099+
func (c *Checker) reportNonexistentProperty(propNode *ast.Node, containingType *Type, isUncheckedJS bool) {
1109511100
if ast.IsJSDocNameReferenceContext(propNode) {
1109611101
return
1109711102
}
@@ -11123,7 +11128,8 @@ func (c *Checker) reportNonexistentProperty(propNode *ast.Node, containingType *
1112311128
suggestion := c.getSuggestedSymbolForNonexistentProperty(propNode, containingType)
1112411129
if suggestion != nil {
1112511130
suggestedName := ast.SymbolName(suggestion)
11126-
diagnostic = NewDiagnosticChainForNode(diagnostic, propNode, diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, missingProperty, container, suggestedName)
11131+
message := core.IfElse(isUncheckedJS, diagnostics.Property_0_may_not_exist_on_type_1_Did_you_mean_2, diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2)
11132+
diagnostic = NewDiagnosticChainForNode(diagnostic, propNode, message, missingProperty, container, suggestedName)
1112711133
if suggestion.ValueDeclaration != nil {
1112811134
diagnostic.AddRelatedInfo(NewDiagnosticForNode(suggestion.ValueDeclaration, diagnostics.X_0_is_declared_here, suggestedName))
1112911135
}
@@ -11140,7 +11146,7 @@ func (c *Checker) reportNonexistentProperty(propNode *ast.Node, containingType *
1114011146
}
1114111147
}
1114211148
}
11143-
c.diagnostics.Add(diagnostic)
11149+
c.addErrorOrSuggestion(!isUncheckedJS || diagnostic.Code() != diagnostics.Property_0_may_not_exist_on_type_1_Did_you_mean_2.Code(), diagnostic)
1114411150
}
1114511151

1114611152
func (c *Checker) getSuggestedLibForNonExistentProperty(missingProperty string, containingType *Type) string {
@@ -12609,7 +12615,8 @@ func (c *Checker) checkInExpression(left *ast.Expression, right *ast.Expression,
1260912615
// Unlike in 'checkPrivateIdentifierExpression' we now have access to the RHS type
1261012616
// which provides us with the opportunity to emit more detailed errors
1261112617
if c.symbolNodeLinks.Get(left).resolvedSymbol == nil && ast.GetContainingClass(left) != nil {
12612-
c.reportNonexistentProperty(left, rightType)
12618+
isUncheckedJS := c.isUncheckedJSSuggestion(left, rightType.symbol, true /*excludeClasses*/)
12619+
c.reportNonexistentProperty(left, rightType, isUncheckedJS)
1261312620
}
1261412621
} else {
1261512622
// The type of the left operand must be assignable to string, number, or symbol.
@@ -12714,6 +12721,9 @@ func (c *Checker) checkObjectLiteral(node *ast.Node, checkMode CheckMode) *Type
1271412721
}
1271512722
result := c.newAnonymousType(node.Symbol(), propertiesTable, nil, nil, indexInfos)
1271612723
result.objectFlags |= objectFlags | ObjectFlagsObjectLiteral | ObjectFlagsContainsObjectOrArrayLiteral
12724+
if contextualType == nil && ast.IsInJSFile(node) && !ast.IsInJsonFile(node) {
12725+
result.objectFlags |= ObjectFlagsJSLiteral
12726+
}
1271712727
if patternWithComputedProperties {
1271812728
result.objectFlags |= ObjectFlagsObjectLiteralPatternWithComputedProperties
1271912729
}
@@ -17598,6 +17608,10 @@ func (c *Checker) widenTypeForVariableLikeDeclaration(t *Type, declaration *ast.
1759817608
}
1759917609

1760017610
func (c *Checker) reportImplicitAny(declaration *ast.Node, t *Type, wideningKind WideningKind) {
17611+
if ast.IsInJSFile(declaration) && !ast.IsCheckJSEnabledForFile(ast.GetSourceFileOfNode(declaration), c.compilerOptions) {
17612+
// Only report implicit any errors/suggestions in TS and ts-check JS files
17613+
return
17614+
}
1760117615
typeAsString := c.TypeToString(c.getWidenedType(t))
1760217616
var diagnostic *diagnostics.Message
1760317617
switch declaration.Kind {
@@ -26321,6 +26335,9 @@ func (c *Checker) getPropertyTypeForIndexType(originalObjectType *Type, objectTy
2632126335
if indexType.flags&TypeFlagsNever != 0 {
2632226336
return c.neverType
2632326337
}
26338+
if c.isJSLiteralType(objectType) {
26339+
return c.anyType
26340+
}
2632426341
if accessExpression != nil && !isConstEnumObjectType(objectType) {
2632526342
if isObjectLiteralType(objectType) {
2632626343
if c.noImplicitAny && indexType.flags&(TypeFlagsStringLiteral|TypeFlagsNumberLiteral) != 0 {
@@ -26378,6 +26395,9 @@ func (c *Checker) getPropertyTypeForIndexType(originalObjectType *Type, objectTy
2637826395
if accessFlags&AccessFlagsAllowMissing != 0 && isObjectLiteralType(objectType) {
2637926396
return c.undefinedType
2638026397
}
26398+
if c.isJSLiteralType(objectType) {
26399+
return c.anyType
26400+
}
2638126401
if accessNode != nil {
2638226402
indexNode := getIndexNodeForAccessExpression(accessNode)
2638326403
if indexNode.Kind != ast.KindBigIntLiteral && indexType.flags&(TypeFlagsStringLiteral|TypeFlagsNumberLiteral) != 0 {

pkg/checker/utilities.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,3 +1825,92 @@ func nodeStartsNewLexicalEnvironment(node *ast.Node) bool {
18251825
}
18261826
return false
18271827
}
1828+
1829+
// Determines whether a did-you-mean error should be a suggestion in an unchecked JS file.
1830+
// Only applies to unchecked JS files without checkJS, // @ts-check or // @ts-nocheck
1831+
// It does not suggest when the suggestion:
1832+
// - Is from a global file that is different from the reference file, or
1833+
// - (optionally) Is a class, or is a this.x property access expression
1834+
func (c *Checker) isUncheckedJSSuggestion(node *ast.Node, suggestion *ast.Symbol, excludeClasses bool) bool {
1835+
file := ast.GetSourceFileOfNode(node)
1836+
if file != nil {
1837+
if c.compilerOptions.CheckJs.IsUnknown() && file.CheckJsDirective == nil && (file.ScriptKind == core.ScriptKindJS || file.ScriptKind == core.ScriptKindJSX) {
1838+
var declarationFile *ast.SourceFile
1839+
if suggestion != nil {
1840+
if firstDeclaration := core.FirstOrNil(suggestion.Declarations); firstDeclaration != nil {
1841+
declarationFile = ast.GetSourceFileOfNode(firstDeclaration)
1842+
}
1843+
}
1844+
suggestionHasNoExtendsOrDecorators := suggestion == nil ||
1845+
suggestion.ValueDeclaration == nil ||
1846+
!ast.IsClassLike(suggestion.ValueDeclaration) ||
1847+
len(ast.GetExtendsHeritageClauseElements(suggestion.ValueDeclaration)) != 0 ||
1848+
classOrConstructorParameterIsDecorated(suggestion.ValueDeclaration)
1849+
return !(file != declarationFile && declarationFile != nil && ast.IsGlobalSourceFile(declarationFile.AsNode())) &&
1850+
!(excludeClasses && suggestion != nil && suggestion.Flags&ast.SymbolFlagsClass != 0 && suggestionHasNoExtendsOrDecorators) &&
1851+
!(node != nil && excludeClasses && ast.IsPropertyAccessExpression(node) && node.Expression().Kind == ast.KindThisKeyword && suggestionHasNoExtendsOrDecorators)
1852+
}
1853+
}
1854+
return false
1855+
}
1856+
1857+
func classOrConstructorParameterIsDecorated(node *ast.Node) bool {
1858+
if nodeIsDecorated(node, nil, nil) {
1859+
return true
1860+
}
1861+
constructor := ast.GetFirstConstructorWithBody(node)
1862+
return constructor != nil && childIsDecorated(constructor, node)
1863+
}
1864+
1865+
func nodeIsDecorated(node *ast.Node, parent *ast.Node, grandparent *ast.Node) bool {
1866+
return ast.HasDecorators(node) && nodeCanBeDecorated(false, node, parent, grandparent)
1867+
}
1868+
1869+
func nodeOrChildIsDecorated(node *ast.Node, parent *ast.Node, grandparent *ast.Node) bool {
1870+
return nodeIsDecorated(node, parent, grandparent) || childIsDecorated(node, parent)
1871+
}
1872+
1873+
func childIsDecorated(node *ast.Node, parent *ast.Node) bool {
1874+
switch node.Kind {
1875+
case ast.KindClassDeclaration, ast.KindClassExpression:
1876+
return core.Some(node.Members(), func(m *ast.Node) bool {
1877+
return nodeOrChildIsDecorated(m, node, parent)
1878+
})
1879+
case ast.KindMethodDeclaration,
1880+
ast.KindSetAccessor,
1881+
ast.KindConstructor:
1882+
return core.Some(node.Parameters(), func(p *ast.Node) bool {
1883+
return nodeIsDecorated(p, node, parent)
1884+
})
1885+
default:
1886+
return false
1887+
}
1888+
}
1889+
1890+
// Returns if a type is or consists of a JSLiteral object type
1891+
// In addition to objects which are directly literals,
1892+
// * unions where every element is a jsliteral
1893+
// * intersections where at least one element is a jsliteral
1894+
// * and instantiable types constrained to a jsliteral
1895+
// Should all count as literals and not print errors on access or assignment of possibly existing properties.
1896+
// This mirrors the behavior of the index signature propagation, to which this behaves similarly (but doesn't affect assignability or inference).
1897+
func (c *Checker) isJSLiteralType(t *Type) bool {
1898+
if c.noImplicitAny {
1899+
return false
1900+
// Flag is meaningless under `noImplicitAny` mode
1901+
}
1902+
if t.objectFlags&ObjectFlagsJSLiteral != 0 {
1903+
return true
1904+
}
1905+
if t.flags&TypeFlagsUnion != 0 {
1906+
return core.Every(t.AsUnionType().types, c.isJSLiteralType)
1907+
}
1908+
if t.flags&TypeFlagsIntersection != 0 {
1909+
return core.Some(t.AsIntersectionType().types, c.isJSLiteralType)
1910+
}
1911+
if t.flags&TypeFlagsInstantiable != 0 {
1912+
constraint := c.getResolvedBaseConstraint(t, nil)
1913+
return constraint != t && c.isJSLiteralType(constraint)
1914+
}
1915+
return false
1916+
}

pkg/core/compileroptions.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,11 @@ func (options *CompilerOptions) GetEmitModuleDetectionKind() ModuleDetectionKind
232232
if options.ModuleDetection != ModuleDetectionKindNone {
233233
return options.ModuleDetection
234234
}
235-
switch options.GetEmitModuleKind() {
236-
case ModuleKindNode16, ModuleKindNode20, ModuleKindNodeNext:
235+
moduleKind := options.GetEmitModuleKind()
236+
if ModuleKindNode16 <= moduleKind && moduleKind <= ModuleKindNodeNext {
237237
return ModuleDetectionKindForce
238-
default:
239-
return ModuleDetectionKindAuto
240238
}
239+
return ModuleDetectionKindAuto
241240
}
242241

243242
func (options *CompilerOptions) GetResolvePackageJsonExports() bool {

pkg/format/indent.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,11 @@ func getIndentationForNodeWorker(
6666
// }, { itself contributes nothing.
6767
// prop: 1 L3 - The indentation of the second object literal is best understood by
6868
// }) looking at the relationship between the list and *first* list item.
69-
listLine, _ := getStartLineAndCharacterForNode(firstListChild, sourceFile)
70-
listIndentsChild := firstListChild != nil && listLine > containingListOrParentStartLine
69+
var listIndentsChild bool
70+
if firstListChild != nil {
71+
listLine, _ := getStartLineAndCharacterForNode(firstListChild, sourceFile)
72+
listIndentsChild = listLine > containingListOrParentStartLine
73+
}
7174
actualIndentation := getActualIndentationForListItem(current, sourceFile, options, listIndentsChild)
7275
if actualIndentation != -1 {
7376
return actualIndentation + indentationDelta

pkg/ls/format_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,66 @@ func TestGetFormattingEditsAfterKeystroke_SimpleStatement(t *testing.T) {
7070
// Should return nil or empty edits, not panic
7171
_ = edits
7272
}
73+
74+
// Test for issue: Crash in range formatting when requested on a line that is different from the containing function
75+
// This reproduces the panic when formatting a range inside a function body
76+
func TestGetFormattingEditsForRange_FunctionBody(t *testing.T) {
77+
t.Parallel()
78+
79+
testCases := []struct {
80+
name string
81+
text string
82+
startPos int
83+
endPos int
84+
}{
85+
{
86+
name: "return statement in function",
87+
text: "function foo() {\n return (1 + 2);\n}",
88+
startPos: 21, // Start of "return"
89+
endPos: 38, // End of ");"
90+
},
91+
{
92+
name: "function with newline after keyword",
93+
text: "function\nf() {\n}",
94+
startPos: 9, // After "function\n"
95+
endPos: 13, // Inside or after function
96+
},
97+
{
98+
name: "empty function body",
99+
text: "function f() {\n \n}",
100+
startPos: 15, // Inside body
101+
endPos: 17, // Inside body
102+
},
103+
{
104+
name: "after function closing brace",
105+
text: "function f() {\n}",
106+
startPos: 15, // After closing brace
107+
endPos: 15,
108+
},
109+
}
110+
111+
for _, tc := range testCases {
112+
t.Run(tc.name, func(t *testing.T) {
113+
t.Parallel()
114+
sourceFile := parser.ParseSourceFile(ast.SourceFileParseOptions{
115+
FileName: "/test.ts",
116+
Path: "/test.ts",
117+
}, tc.text, core.ScriptKindTS)
118+
119+
langService := &LanguageService{}
120+
ctx := context.Background()
121+
options := format.GetDefaultFormatCodeSettings("\n")
122+
123+
// This should not panic
124+
edits := langService.getFormattingEditsForRange(
125+
ctx,
126+
sourceFile,
127+
options,
128+
core.NewTextRange(tc.startPos, tc.endPos),
129+
)
130+
131+
// Should not panic
132+
_ = edits // Just ensuring no panic
133+
})
134+
}
135+
}

0 commit comments

Comments
 (0)