diff --git a/internal/ast/ast.go b/internal/ast/ast.go index 718bbda8b2..4c15abd4fe 100644 --- a/internal/ast/ast.go +++ b/internal/ast/ast.go @@ -8706,6 +8706,10 @@ func (node *TemplateHead) Clone(f NodeFactoryCoercible) *Node { return cloneNode(f.AsNodeFactory().NewTemplateHead(node.Text, node.RawText, node.TemplateFlags), node.AsNode(), f.AsNodeFactory().hooks) } +func IsTemplateHead(node *Node) bool { + return node.Kind == KindTemplateHead +} + // TemplateMiddle type TemplateMiddle struct { @@ -8726,6 +8730,10 @@ func (node *TemplateMiddle) Clone(f NodeFactoryCoercible) *Node { return cloneNode(f.AsNodeFactory().NewTemplateMiddle(node.Text, node.RawText, node.TemplateFlags), node.AsNode(), f.AsNodeFactory().hooks) } +func IsTemplateMiddle(node *Node) bool { + return node.Kind == KindTemplateMiddle +} + // TemplateTail type TemplateTail struct { @@ -8746,6 +8754,10 @@ func (node *TemplateTail) Clone(f NodeFactoryCoercible) *Node { return cloneNode(f.AsNodeFactory().NewTemplateTail(node.Text, node.RawText, node.TemplateFlags), node.AsNode(), f.AsNodeFactory().hooks) } +func IsTemplateTail(node *Node) bool { + return node.Kind == KindTemplateTail +} + // TemplateLiteralTypeNode type TemplateLiteralTypeNode struct { @@ -9635,6 +9647,10 @@ func (node *JSDocTypeExpression) Clone(f NodeFactoryCoercible) *Node { return cloneNode(f.AsNodeFactory().NewJSDocTypeExpression(node.Type), node.AsNode(), f.AsNodeFactory().hooks) } +func IsJSDocTypeExpression(node *Node) bool { + return node.Kind == KindJSDocTypeExpression +} + // JSDocNonNullableType type JSDocNonNullableType struct { @@ -10565,6 +10581,10 @@ func (node *JSDocTypeLiteral) Clone(f NodeFactoryCoercible) *Node { return cloneNode(f.AsNodeFactory().NewJSDocTypeLiteral(node.JSDocPropertyTags, node.IsArrayType), node.AsNode(), f.AsNodeFactory().hooks) } +func IsJSDocTypeLiteral(node *Node) bool { + return node.Kind == KindJSDocTypeLiteral +} + // JSDocSignature type JSDocSignature struct { TypeNodeBase diff --git a/internal/fourslash/_scripts/convertFourslash.mts b/internal/fourslash/_scripts/convertFourslash.mts index 72a6d879a6..5d47f7a836 100644 --- a/internal/fourslash/_scripts/convertFourslash.mts +++ b/internal/fourslash/_scripts/convertFourslash.mts @@ -190,6 +190,8 @@ function parseFourslashStatement(statement: ts.Statement): Cmd[] | undefined { return parseBaselineQuickInfo(callExpression.arguments); case "baselineSignatureHelp": return [parseBaselineSignatureHelp(callExpression.arguments)]; + case "baselineSmartSelection": + return [parseBaselineSmartSelection(callExpression.arguments)]; case "baselineGoToDefinition": case "baselineGetDefinitionAtPosition": case "baselineGoToType": @@ -1422,6 +1424,16 @@ function parseBaselineSignatureHelp(args: ts.NodeArray): Cmd { }; } +function parseBaselineSmartSelection(args: ts.NodeArray): Cmd { + if (args.length !== 0) { + // All calls are currently empty! + throw new Error("Expected no arguments in verify.baselineSmartSelection"); + } + return { + kind: "verifyBaselineSmartSelection", + }; +} + function parseKind(expr: ts.Expression): string | undefined { if (!ts.isStringLiteral(expr)) { console.error(`Expected string literal for kind, got ${expr.getText()}`); @@ -1591,6 +1603,10 @@ interface VerifyBaselineSignatureHelpCmd { kind: "verifyBaselineSignatureHelp"; } +interface VerifyBaselineSmartSelection { + kind: "verifyBaselineSmartSelection"; +} + interface VerifyBaselineRenameCmd { kind: "verifyBaselineRename" | "verifyBaselineRenameAtRangesWithText"; args: string[]; @@ -1635,6 +1651,7 @@ type Cmd = | VerifyBaselineGoToDefinitionCmd | VerifyBaselineQuickInfoCmd | VerifyBaselineSignatureHelpCmd + | VerifyBaselineSmartSelection | GoToCmd | EditCmd | VerifyQuickInfoCmd @@ -1754,6 +1771,8 @@ function generateCmd(cmd: Cmd): string { return `f.VerifyBaselineHover(t)`; case "verifyBaselineSignatureHelp": return `f.VerifyBaselineSignatureHelp(t)`; + case "verifyBaselineSmartSelection": + return `f.VerifyBaselineSelectionRanges(t)`; case "goTo": return generateGoToCommand(cmd); case "edit": diff --git a/internal/fourslash/baselineutil.go b/internal/fourslash/baselineutil.go index 83e683b1d4..1a659331d9 100644 --- a/internal/fourslash/baselineutil.go +++ b/internal/fourslash/baselineutil.go @@ -47,7 +47,7 @@ func getBaselineFileName(t *testing.T, command string) string { func getBaselineExtension(command string) string { switch command { - case "QuickInfo", "SignatureHelp": + case "QuickInfo", "SignatureHelp", "Smart Selection": return "baseline" case "Auto Imports": return "baseline.md" @@ -61,6 +61,11 @@ func getBaselineExtension(command string) string { func getBaselineOptions(command string) baseline.Options { subfolder := "fourslash/" + normalizeCommandName(command) switch command { + case "Smart Selection": + return baseline.Options{ + Subfolder: subfolder, + IsSubmodule: true, + } case "findRenameLocations": return baseline.Options{ Subfolder: subfolder, diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index c6ac77bf22..93f61817ab 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -1294,6 +1294,149 @@ func (f *FourslashTest) VerifyBaselineSignatureHelp(t *testing.T) { } } +func (f *FourslashTest) VerifyBaselineSelectionRanges(t *testing.T) { + markers := f.Markers() + var result strings.Builder + newLine := "\n" + + for i, marker := range markers { + if i > 0 { + result.WriteString(newLine + strings.Repeat("=", 80) + newLine + newLine) + } + + script := f.getScriptInfo(marker.FileName()) + fileContent := script.content + + // Add the marker position indicator + markerPos := marker.Position + baselineContent := fileContent[:markerPos] + "/**/" + fileContent[markerPos:] + newLine + result.WriteString(baselineContent) + + // Get selection ranges at this marker + params := &lsproto.SelectionRangeParams{ + TextDocument: lsproto.TextDocumentIdentifier{ + Uri: ls.FileNameToDocumentURI(marker.FileName()), + }, + Positions: []lsproto.Position{marker.LSPosition}, + } + + resMsg, selectionRangeResult, resultOk := sendRequest(t, f, lsproto.TextDocumentSelectionRangeInfo, params) + markerNameStr := *core.OrElse(marker.Name, ptrTo("(unnamed)")) + if resMsg == nil { + t.Fatalf("Nil response received for selection range request at marker '%s'", markerNameStr) + } + if !resultOk { + if resMsg.AsResponse().Error != nil { + t.Fatalf("Error response for selection range request at marker '%s': %v", markerNameStr, resMsg.AsResponse().Error) + } + t.Fatalf("Unexpected selection range response type at marker '%s': %T", markerNameStr, resMsg.AsResponse().Result) + } + + if selectionRangeResult.SelectionRanges == nil || len(*selectionRangeResult.SelectionRanges) == 0 { + result.WriteString("No selection ranges available\n") + continue + } + + selectionRange := (*selectionRangeResult.SelectionRanges)[0] + + // Add blank line after source code section + result.WriteString(newLine) + + // Walk through the selection range chain + for selectionRange != nil { + start := int(f.converters.LineAndCharacterToPosition(script, selectionRange.Range.Start)) + end := int(f.converters.LineAndCharacterToPosition(script, selectionRange.Range.End)) + + // Create a masked version of the file showing only this range + runes := []rune(fileContent) + masked := make([]rune, len(runes)) + for i, ch := range runes { + if i >= start && i < end { + // Keep characters in the selection range + if ch == ' ' { + masked[i] = '•' + } else if ch == '\n' || ch == '\r' { + masked[i] = ch // Keep line breaks as-is, will add arrow later + } else { + masked[i] = ch + } + } else { + // Replace characters outside the range + if ch == '\n' || ch == '\r' { + masked[i] = ch + } else { + masked[i] = ' ' + } + } + } + + maskedStr := string(masked) + + // Add line break arrows + maskedStr = strings.ReplaceAll(maskedStr, "\n", "↲\n") + maskedStr = strings.ReplaceAll(maskedStr, "\r", "↲\r") + + // Remove blank lines + lines := strings.Split(maskedStr, "\n") + var nonBlankLines []string + for _, line := range lines { + trimmed := strings.TrimSpace(line) + if trimmed != "" && trimmed != "↲" { + nonBlankLines = append(nonBlankLines, line) + } + } + maskedStr = strings.Join(nonBlankLines, "\n") + + // Find leading and trailing width of non-whitespace characters + maskedRunes := []rune(maskedStr) + isRealCharacter := func(ch rune) bool { + return ch != '•' && ch != '↲' && !stringutil.IsWhiteSpaceLike(ch) + } + + leadingWidth := -1 + for i, ch := range maskedRunes { + if isRealCharacter(ch) { + leadingWidth = i + break + } + } + + trailingWidth := -1 + for j := len(maskedRunes) - 1; j >= 0; j-- { + if isRealCharacter(maskedRunes[j]) { + trailingWidth = j + break + } + } + + if leadingWidth != -1 && trailingWidth != -1 && leadingWidth <= trailingWidth { + // Clean up middle section + prefix := string(maskedRunes[:leadingWidth]) + middle := string(maskedRunes[leadingWidth : trailingWidth+1]) + suffix := string(maskedRunes[trailingWidth+1:]) + + middle = strings.ReplaceAll(middle, "•", " ") + middle = strings.ReplaceAll(middle, "↲", "") + + maskedStr = prefix + middle + suffix + } + + // Add blank line before multi-line ranges + if strings.Contains(maskedStr, "\n") { + result.WriteString(newLine) + } + + result.WriteString(maskedStr) + if !strings.HasSuffix(maskedStr, "\n") { + result.WriteString(newLine) + } + + selectionRange = selectionRange.Parent + } + } + f.addResultToBaseline(t, "Smart Selection", strings.TrimSuffix(result.String(), "\n")) +} + func (f *FourslashTest) VerifyBaselineDocumentHighlights( t *testing.T, preferences *ls.UserPreferences, diff --git a/internal/fourslash/tests/gen/smartSelection_JSDocTags10_test.go b/internal/fourslash/tests/gen/smartSelection_JSDocTags10_test.go new file mode 100644 index 0000000000..a323c1da47 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_JSDocTags10_test.go @@ -0,0 +1,22 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_JSDocTags10(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `/** + * @template T + * @extends {/**/Set} + */ +class A extends B { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_JSDocTags11_test.go b/internal/fourslash/tests/gen/smartSelection_JSDocTags11_test.go new file mode 100644 index 0000000000..1eedc0f74c --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_JSDocTags11_test.go @@ -0,0 +1,21 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_JSDocTags11(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `const x = 1; +type Foo = { + /** comment */ + /*2*/readonly /*1*/status: number; +};` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_JSDocTags12_test.go b/internal/fourslash/tests/gen/smartSelection_JSDocTags12_test.go new file mode 100644 index 0000000000..7ec86103a2 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_JSDocTags12_test.go @@ -0,0 +1,20 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_JSDocTags12(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `type B = {}; +type A = { + a(/** Comment */ /*1*/p0: number, /** Comment */ /*2*/p1: number, /** Comment */ /*3*/p2: number): string; +};` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_JSDocTags13_test.go b/internal/fourslash/tests/gen/smartSelection_JSDocTags13_test.go new file mode 100644 index 0000000000..a3c4b2d4c6 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_JSDocTags13_test.go @@ -0,0 +1,23 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_JSDocTags13(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `let a; +let b: { + /** Comment */ /*1*/p0: number + /** Comment */ /*2*/p1: number + /** Comment */ /*3*/p2: number +}; +let c;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_JSDocTags1_test.go b/internal/fourslash/tests/gen/smartSelection_JSDocTags1_test.go new file mode 100644 index 0000000000..fcc56e525a --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_JSDocTags1_test.go @@ -0,0 +1,20 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_JSDocTags1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `/** + * @returns {Array<{ value: /**/string }>} + */ +function foo() { return [] }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_JSDocTags2_test.go b/internal/fourslash/tests/gen/smartSelection_JSDocTags2_test.go new file mode 100644 index 0000000000..0db6205655 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_JSDocTags2_test.go @@ -0,0 +1,20 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_JSDocTags2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `/** + * @type {/**/string} + */ +const foo;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_JSDocTags3_test.go b/internal/fourslash/tests/gen/smartSelection_JSDocTags3_test.go new file mode 100644 index 0000000000..fb4b5ecdaf --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_JSDocTags3_test.go @@ -0,0 +1,20 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_JSDocTags3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `/** + * @param {/**/string} x + */ +function foo(x) {}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_JSDocTags4_test.go b/internal/fourslash/tests/gen/smartSelection_JSDocTags4_test.go new file mode 100644 index 0000000000..7d1d7bb0fc --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_JSDocTags4_test.go @@ -0,0 +1,25 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_JSDocTags4(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `/** + * @typedef {object} Foo + * @property {string} a + * @property {number} b + * @property {/**/number} c + */ + +/** @type {Foo} */ +const foo;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_JSDocTags5_test.go b/internal/fourslash/tests/gen/smartSelection_JSDocTags5_test.go new file mode 100644 index 0000000000..c14320ca6a --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_JSDocTags5_test.go @@ -0,0 +1,25 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_JSDocTags5(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `/** + * @callback Foo + * @param {string} data + * @param {/**/number} [index] - comment + * @return {boolean} + */ + +/** @type {Foo} */ +const foo = s => !(s.length % 2);` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_JSDocTags6_test.go b/internal/fourslash/tests/gen/smartSelection_JSDocTags6_test.go new file mode 100644 index 0000000000..ac7904a3b6 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_JSDocTags6_test.go @@ -0,0 +1,24 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_JSDocTags6(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `/** + * @template T + * @param {/**/T} x + * @return {T} + */ +function foo(x) { + return x; +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_JSDocTags7_test.go b/internal/fourslash/tests/gen/smartSelection_JSDocTags7_test.go new file mode 100644 index 0000000000..fbfc577b24 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_JSDocTags7_test.go @@ -0,0 +1,22 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_JSDocTags7(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `/** + * @constructor + * @param {/**/number} data + */ +function Foo(data) { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_JSDocTags8_test.go b/internal/fourslash/tests/gen/smartSelection_JSDocTags8_test.go new file mode 100644 index 0000000000..7a6dbfa501 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_JSDocTags8_test.go @@ -0,0 +1,22 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_JSDocTags8(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `/** + * @this {/*1*/Foo} + * @param {/*2*/*} e + */ +function callback(e) { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_JSDocTags9_test.go b/internal/fourslash/tests/gen/smartSelection_JSDocTags9_test.go new file mode 100644 index 0000000000..cd4cfd9672 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_JSDocTags9_test.go @@ -0,0 +1,21 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_JSDocTags9(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `/** @enum {/**/number} */ +const Foo = { + x: 0, + y: 1, +};` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_JSDoc_test.go b/internal/fourslash/tests/gen/smartSelection_JSDoc_test.go new file mode 100644 index 0000000000..df80bc98fc --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_JSDoc_test.go @@ -0,0 +1,23 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_JSDoc(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// Not a JSDoc comment +/** + * @param {number} x The number to square + */ +function /**/square(x) { + return x * x; +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_behindCaret_test.go b/internal/fourslash/tests/gen/smartSelection_behindCaret_test.go new file mode 100644 index 0000000000..60616d9619 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_behindCaret_test.go @@ -0,0 +1,17 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_behindCaret(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `let/**/ x: string` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_bindingPatterns_test.go b/internal/fourslash/tests/gen/smartSelection_bindingPatterns_test.go new file mode 100644 index 0000000000..2af1ad8ece --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_bindingPatterns_test.go @@ -0,0 +1,17 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_bindingPatterns(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `const { /*1*/x, y: /*2*/a, .../*3*/zs = {} } = {};` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_comment1_test.go b/internal/fourslash/tests/gen/smartSelection_comment1_test.go new file mode 100644 index 0000000000..07ce0c89a1 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_comment1_test.go @@ -0,0 +1,17 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_comment1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `const a = 1; ///**/comment content` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_comment2_test.go b/internal/fourslash/tests/gen/smartSelection_comment2_test.go new file mode 100644 index 0000000000..5f85d31719 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_comment2_test.go @@ -0,0 +1,17 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_comment2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `const a = 1; //a b/**/c d` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_complex_test.go b/internal/fourslash/tests/gen/smartSelection_complex_test.go new file mode 100644 index 0000000000..f5e70e3505 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_complex_test.go @@ -0,0 +1,17 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_complex(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `type X = IsExactlyAny

extends true ? T : ({ [K in keyof P]: IsExactlyAny extends true ? K extends keyof T ? T[K] : P[/**/K] : P[K]; } & Pick>)` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_emptyRanges_test.go b/internal/fourslash/tests/gen/smartSelection_emptyRanges_test.go new file mode 100644 index 0000000000..bfe284f963 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_emptyRanges_test.go @@ -0,0 +1,23 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_emptyRanges(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `class HomePage { + componentDidMount(/*1*/) { + if (this.props.username/*2*/) { + return '/*3*/'; + } + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_function1_test.go b/internal/fourslash/tests/gen/smartSelection_function1_test.go new file mode 100644 index 0000000000..69f55b9433 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_function1_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_function1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `const f1 = () => { + /**/ +};` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_function2_test.go b/internal/fourslash/tests/gen/smartSelection_function2_test.go new file mode 100644 index 0000000000..ae9342a804 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_function2_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_function2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `function f2() { + /**/ +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_function3_test.go b/internal/fourslash/tests/gen/smartSelection_function3_test.go new file mode 100644 index 0000000000..277f17a16e --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_function3_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_function3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `const f3 = function () { + /**/ +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_functionParams1_test.go b/internal/fourslash/tests/gen/smartSelection_functionParams1_test.go new file mode 100644 index 0000000000..9e72094748 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_functionParams1_test.go @@ -0,0 +1,17 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_functionParams1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `function f(/*1*/p, /*2*/q?, /*3*/...r: any[] = []) {}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_functionParams2_test.go b/internal/fourslash/tests/gen/smartSelection_functionParams2_test.go new file mode 100644 index 0000000000..23742a790c --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_functionParams2_test.go @@ -0,0 +1,20 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_functionParams2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `function f( + a, + /**/b +) {}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_imports_test.go b/internal/fourslash/tests/gen/smartSelection_imports_test.go new file mode 100644 index 0000000000..fb6fdaf283 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_imports_test.go @@ -0,0 +1,20 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_imports(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `import { /**/x as y, z } from './z'; +import { b } from './'; + +console.log(1);` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_lastBlankLine_test.go b/internal/fourslash/tests/gen/smartSelection_lastBlankLine_test.go new file mode 100644 index 0000000000..707384913d --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_lastBlankLine_test.go @@ -0,0 +1,18 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_lastBlankLine(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `class C {} +/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_loneVariableDeclaration_test.go b/internal/fourslash/tests/gen/smartSelection_loneVariableDeclaration_test.go new file mode 100644 index 0000000000..da1f4af3a8 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_loneVariableDeclaration_test.go @@ -0,0 +1,17 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_loneVariableDeclaration(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `const /**/x = 3;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_mappedTypes_test.go b/internal/fourslash/tests/gen/smartSelection_mappedTypes_test.go new file mode 100644 index 0000000000..7467f4d8eb --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_mappedTypes_test.go @@ -0,0 +1,17 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_mappedTypes(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `type M = { /*1*/-re/*2*/adonly /*3*/[K in ke/*4*/yof any]/*5*/-/*6*/?: any };` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_objectTypes_test.go b/internal/fourslash/tests/gen/smartSelection_objectTypes_test.go new file mode 100644 index 0000000000..98fa38286b --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_objectTypes_test.go @@ -0,0 +1,21 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_objectTypes(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `type X = { + /*1*/foo?: string; + /*2*/readonly /*3*/bar: { x: num/*4*/ber }; + /*5*/meh +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_punctuationPriority_test.go b/internal/fourslash/tests/gen/smartSelection_punctuationPriority_test.go new file mode 100644 index 0000000000..d63add6b39 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_punctuationPriority_test.go @@ -0,0 +1,17 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_punctuationPriority(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `console/**/.log();` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_simple1_test.go b/internal/fourslash/tests/gen/smartSelection_simple1_test.go new file mode 100644 index 0000000000..e24d9bb2bb --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_simple1_test.go @@ -0,0 +1,24 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_simple1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `class Foo { + bar(a, b) { + if (/*1*/a === b) { + return tr/*2*/ue; + } + return false; + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_simple2_test.go b/internal/fourslash/tests/gen/smartSelection_simple2_test.go new file mode 100644 index 0000000000..a2b31dfe05 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_simple2_test.go @@ -0,0 +1,22 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_simple2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `export interface IService { + _serviceBrand: any; + + open(ho/*1*/st: number, data: any): Promise; + bar(): void/*2*/ +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_stringLiteral_test.go b/internal/fourslash/tests/gen/smartSelection_stringLiteral_test.go new file mode 100644 index 0000000000..789cac8a04 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_stringLiteral_test.go @@ -0,0 +1,18 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_stringLiteral(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `const a = 'a'; +const b = /**/'b';` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_templateStrings2_test.go b/internal/fourslash/tests/gen/smartSelection_templateStrings2_test.go new file mode 100644 index 0000000000..fa210cb690 --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_templateStrings2_test.go @@ -0,0 +1,17 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_templateStrings2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `` + "`" + `a ${b} /**/c` + "`" + `` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/fourslash/tests/gen/smartSelection_templateStrings_test.go b/internal/fourslash/tests/gen/smartSelection_templateStrings_test.go new file mode 100644 index 0000000000..ef7a4d7fbb --- /dev/null +++ b/internal/fourslash/tests/gen/smartSelection_templateStrings_test.go @@ -0,0 +1,19 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestSmartSelection_templateStrings(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `` + "`" + `a /*1*/b ${ + '/*2*/c' +} d` + "`" + `` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineSelectionRanges(t) +} diff --git a/internal/ls/selectionranges.go b/internal/ls/selectionranges.go new file mode 100644 index 0000000000..823730282d --- /dev/null +++ b/internal/ls/selectionranges.go @@ -0,0 +1,188 @@ +package ls + +import ( + "context" + + "github.com/microsoft/typescript-go/internal/ast" + "github.com/microsoft/typescript-go/internal/astnav" + "github.com/microsoft/typescript-go/internal/core" + "github.com/microsoft/typescript-go/internal/lsp/lsproto" + "github.com/microsoft/typescript-go/internal/scanner" +) + +func (l *LanguageService) ProvideSelectionRanges(ctx context.Context, params *lsproto.SelectionRangeParams) (lsproto.SelectionRangeResponse, error) { + _, sourceFile := l.getProgramAndFile(params.TextDocument.Uri) + if sourceFile == nil { + return lsproto.SelectionRangesOrNull{}, nil + } + + var results []*lsproto.SelectionRange + for _, position := range params.Positions { + pos := l.converters.LineAndCharacterToPosition(sourceFile, position) + selectionRange := getSmartSelectionRange(l, sourceFile, int(pos)) + if selectionRange != nil { + results = append(results, selectionRange) + } + } + + return lsproto.SelectionRangesOrNull{SelectionRanges: &results}, nil +} + +func getSmartSelectionRange(l *LanguageService, sourceFile *ast.SourceFile, pos int) *lsproto.SelectionRange { + factory := &ast.NodeFactory{} + + nodeContainsPosition := func(node *ast.Node) bool { + if node == nil { + return false + } + start := scanner.GetTokenPosOfNode(node, sourceFile, true /*includeJSDoc*/) + end := node.End() + return start <= pos && pos < end + } + + pushSelectionRange := func(current *lsproto.SelectionRange, start, end int) *lsproto.SelectionRange { + if start == end { + return current + } + + if !(start <= pos && pos <= end) { + return current + } + + lspRange := l.converters.ToLSPRange(sourceFile, core.NewTextRange(start, end)) + + if current != nil && current.Range == lspRange { + return current + } + + return &lsproto.SelectionRange{ + Range: lspRange, + Parent: current, + } + } + + pushSelectionCommentRange := func(current *lsproto.SelectionRange, start, end int) *lsproto.SelectionRange { + current = pushSelectionRange(current, start, end) + + commentPos := start + text := sourceFile.Text() + for commentPos < end && commentPos < len(text) && text[commentPos] == '/' { + commentPos++ + } + current = pushSelectionRange(current, commentPos, end) + + return current + } + + positionsAreOnSameLine := func(pos1, pos2 int) bool { + if pos1 == pos2 { + return true + } + lspPos1 := l.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(pos1)) + lspPos2 := l.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(pos2)) + return lspPos1.Line == lspPos2.Line + } + + shouldSkipNode := func(node *ast.Node, parent *ast.Node) bool { + if ast.IsBlock(node) { + return true + } + + if ast.IsTemplateSpan(node) || ast.IsTemplateHead(node) || ast.IsTemplateTail(node) { + return true + } + + if parent != nil && ast.IsVariableDeclarationList(node) && ast.IsVariableStatement(parent) { + return true + } + + // Skip lone variable declarations + if parent != nil && ast.IsVariableDeclaration(node) && ast.IsVariableDeclarationList(parent) { + decl := parent.AsVariableDeclarationList() + if decl != nil && len(decl.Declarations.Nodes) == 1 { + return true + } + } + + if ast.IsJSDocTypeExpression(node) || ast.IsJSDocSignature(node) || ast.IsJSDocTypeLiteral(node) { + return true + } + + return false + } + + fullRange := l.converters.ToLSPRange(sourceFile, core.NewTextRange(sourceFile.Pos(), sourceFile.End())) + result := &lsproto.SelectionRange{ + Range: fullRange, + } + + var current *ast.Node + for current = sourceFile.AsNode(); current != nil; { + var next *ast.Node + parent := current + + visit := func(node *ast.Node) *ast.Node { + if node != nil && next == nil { + var foundComment *ast.CommentRange + for comment := range scanner.GetTrailingCommentRanges(factory, sourceFile.Text(), node.End()) { + foundComment = &comment + break + } + if foundComment != nil && foundComment.Kind == ast.KindSingleLineCommentTrivia { + result = pushSelectionCommentRange(result, foundComment.Pos(), foundComment.End()) + } + + if nodeContainsPosition(node) { + // Add range for multi-line function bodies before skipping the block + if ast.IsBlock(node) && ast.IsFunctionLikeDeclaration(parent) { + if !positionsAreOnSameLine(astnav.GetStartOfNode(node, sourceFile, false), node.End()) { + start := astnav.GetStartOfNode(node, sourceFile, false) + end := node.End() + result = pushSelectionRange(result, start, end) + } + } + + if !shouldSkipNode(node, parent) { + start := astnav.GetStartOfNode(node, sourceFile, false) + end := node.End() + result = pushSelectionRange(result, start, end) + } + + next = node + } + } + return node + } + + visitNodes := func(nodes *ast.NodeList, v *ast.NodeVisitor) *ast.NodeList { + if nodes != nil && len(nodes.Nodes) > 0 { + shouldSkipList := parent != nil && ast.IsVariableDeclarationList(parent) + + if !shouldSkipList { + start := astnav.GetStartOfNode(nodes.Nodes[0], sourceFile, false) + end := nodes.Nodes[len(nodes.Nodes)-1].End() + + if start <= pos && pos < end { + result = pushSelectionRange(result, start, end) + } + } + } + return v.VisitNodes(nodes) + } + + // Visit JSDoc nodes first if they exist + if current.Flags&ast.NodeFlagsHasJSDoc != 0 { + for _, jsdoc := range current.JSDoc(sourceFile) { + visit(jsdoc) + } + } + + tempVisitor := ast.NewNodeVisitor(visit, nil, ast.NodeVisitorHooks{ + VisitNodes: visitNodes, + }) + + current.VisitEachChild(tempVisitor) + current = next + } + return result +} diff --git a/internal/ls/utilities.go b/internal/ls/utilities.go index 95659b8a60..09d5a070a4 100644 --- a/internal/ls/utilities.go +++ b/internal/ls/utilities.go @@ -1678,6 +1678,13 @@ func getChildrenFromNonJSDocNode(node *ast.Node, sourceFile *ast.SourceFile) []* childNodes = append(childNodes, child) return false }) + + // If the node has no children, don't scan for tokens. + // This prevents creating tokens for leaf nodes' own text. + if len(childNodes) == 0 { + return nil + } + var children []*ast.Node pos := node.Pos() for _, child := range childNodes { diff --git a/internal/lsp/server.go b/internal/lsp/server.go index 1eafc75712..275e1c92df 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -487,6 +487,7 @@ var handlers = sync.OnceValue(func() handlerMap { registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentDocumentSymbolInfo, (*Server).handleDocumentSymbol) registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentRenameInfo, (*Server).handleRename) registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentDocumentHighlightInfo, (*Server).handleDocumentHighlight) + registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentSelectionRangeInfo, (*Server).handleSelectionRange) registerRequestHandler(handlers, lsproto.WorkspaceSymbolInfo, (*Server).handleWorkspaceSymbol) registerRequestHandler(handlers, lsproto.CompletionItemResolveInfo, (*Server).handleCompletionItemResolve) @@ -666,6 +667,9 @@ func (s *Server) handleInitialize(ctx context.Context, params *lsproto.Initializ DocumentHighlightProvider: &lsproto.BooleanOrDocumentHighlightOptions{ Boolean: ptrTo(true), }, + SelectionRangeProvider: &lsproto.BooleanOrSelectionRangeOptionsOrSelectionRangeRegistrationOptions{ + Boolean: ptrTo(true), + }, }, } @@ -904,6 +908,10 @@ func (s *Server) handleDocumentHighlight(ctx context.Context, ls *ls.LanguageSer return ls.ProvideDocumentHighlights(ctx, params.TextDocument.Uri, params.Position) } +func (s *Server) handleSelectionRange(ctx context.Context, ls *ls.LanguageService, params *lsproto.SelectionRangeParams) (lsproto.SelectionRangeResponse, error) { + return ls.ProvideSelectionRanges(ctx, params) +} + func (s *Server) Log(msg ...any) { fmt.Fprintln(s.stderr, msg...) } diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDoc.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDoc.baseline new file mode 100644 index 0000000000..46201c57a2 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDoc.baseline @@ -0,0 +1,22 @@ +// === Smart Selection === +// Not a JSDoc comment +/** + * @param {number} x The number to square + */ +function /**/square(x) { + return x * x; +} + + square ↲ + +function square(x) { + return x * x; +} + +// Not a JSDoc comment +/** + * @param {number} x The number to square + */ +function square(x) { + return x * x; +} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDoc.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDoc.baseline.diff new file mode 100644 index 0000000000..e2db7538f0 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDoc.baseline.diff @@ -0,0 +1,22 @@ +--- old.smartSelection_JSDoc.baseline ++++ new.smartSelection_JSDoc.baseline +@@= skipped -6, +6 lines =@@ + return x * x; + } + +- +- square +- +- +-function square(x) { +- return x * x; +-} +- +-/** +- * @param {number} x The number to square +- */ ++ square ↲ ++ + function square(x) { + return x * x; + } \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags1.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags1.baseline new file mode 100644 index 0000000000..dc05be2dfe --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags1.baseline @@ -0,0 +1,22 @@ +// === Smart Selection === +/** + * @returns {Array<{ value: /**/string }>} + */ +function foo() { return [] } + + string ↲ + value: string ↲ + { value: string } ↲ + Array<{ value: string }> ↲ + + @returns {Array<{ value: string }>}↲ +• ↲ + +/** + * @returns {Array<{ value: string }>} + */↲ + +/** + * @returns {Array<{ value: string }>} + */ +function foo() { return [] } \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags1.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags1.baseline.diff new file mode 100644 index 0000000000..feb6ca51ef --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags1.baseline.diff @@ -0,0 +1,36 @@ +--- old.smartSelection_JSDocTags1.baseline ++++ new.smartSelection_JSDocTags1.baseline +@@= skipped -3, +3 lines =@@ + */ + function foo() { return [] } + +- +- string +- +- +- value: string +- +- +- { value: string } +- +- +- Array<{ value: string }> +- ++ string ↲ ++ value: string ↲ ++ { value: string } ↲ ++ Array<{ value: string }> ↲ + + @returns {Array<{ value: string }>}↲ +-• +- ++• ↲ + + /** + * @returns {Array<{ value: string }>} +- */ +- ++ */↲ + + /** + * @returns {Array<{ value: string }>} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags10.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags10.baseline new file mode 100644 index 0000000000..8a3eba07c9 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags10.baseline @@ -0,0 +1,26 @@ +// === Smart Selection === +/** + * @template T + * @extends {/**/Set} + */ +class A extends B { +} + + Set ↲ + Set ↲ + @extends {Set}↲ + + @template T + * @extends {Set}↲ + +/** + * @template T + * @extends {Set} + */↲ + +/** + * @template T + * @extends {Set} + */ +class A extends B { +} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags10.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags10.baseline.diff new file mode 100644 index 0000000000..414ab264a0 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags10.baseline.diff @@ -0,0 +1,31 @@ +--- old.smartSelection_JSDocTags10.baseline ++++ new.smartSelection_JSDocTags10.baseline +@@= skipped -5, +5 lines =@@ + class A extends B { + } + +- +- Set +- +- +- Set +- +- +- @extends {Set} +- ++ Set ↲ ++ Set ↲ ++ @extends {Set}↲ ++ ++ @template T ++ * @extends {Set}↲ + + /** + * @template T + * @extends {Set} +- */ +- ++ */↲ + + /** + * @template T \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags11.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags11.baseline new file mode 100644 index 0000000000..a3e89dbed1 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags11.baseline @@ -0,0 +1,52 @@ +// === Smart Selection === +const x = 1; +type Foo = { + /** comment */ + /**/readonly status: number; +}; + + readonly ↲ + readonly status: number;↲ + + { + /** comment */ + readonly status: number; +} + +type Foo = { + /** comment */ + readonly status: number; +}; + +const x = 1; +type Foo = { + /** comment */ + readonly status: number; +}; + +================================================================================ + +const x = 1; +type Foo = { + /** comment */ + readonly /**/status: number; +}; + + status ↲ + readonly status: number;↲ + + { + /** comment */ + readonly status: number; +} + +type Foo = { + /** comment */ + readonly status: number; +}; + +const x = 1; +type Foo = { + /** comment */ + readonly status: number; +}; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags11.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags11.baseline.diff new file mode 100644 index 0000000000..b436c05fa8 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags11.baseline.diff @@ -0,0 +1,54 @@ +--- old.smartSelection_JSDocTags11.baseline ++++ new.smartSelection_JSDocTags11.baseline +@@= skipped -4, +4 lines =@@ + /**/readonly status: number; + }; + +- +- readonly +- +- +- readonly status +- +- +- readonly status: number; +- +- +- /** comment */ +- readonly status: number; +- +- +- ↲ +-••/** comment */ ++ readonly ↲ + readonly status: number;↲ +- + + { + /** comment */ +@@= skipped -43, +27 lines =@@ + readonly /**/status: number; + }; + +- +- status +- +- +- readonly status +- +- +- readonly status: number; +- +- +- /** comment */ +- readonly status: number; +- +- +- ↲ +-••/** comment */ ++ status ↲ + readonly status: number;↲ +- + + { + /** comment */ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags12.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags12.baseline new file mode 100644 index 0000000000..bc09cfe3ed --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags12.baseline @@ -0,0 +1,73 @@ +// === Smart Selection === +type B = {}; +type A = { + a(/** Comment */ /**/p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +}; + + p0 ↲ + p0: number ↲ + p0: number, /** Comment */ p1: number, /** Comment */ p2: number ↲ + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string;↲ + + { + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +} + +type A = { + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +}; + +type B = {}; +type A = { + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +}; + +================================================================================ + +type B = {}; +type A = { + a(/** Comment */ p0: number, /** Comment */ /**/p1: number, /** Comment */ p2: number): string; +}; + + p1 ↲ + p1: number ↲ + p0: number, /** Comment */ p1: number, /** Comment */ p2: number ↲ + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string;↲ + + { + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +} + +type A = { + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +}; + +type B = {}; +type A = { + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +}; + +================================================================================ + +type B = {}; +type A = { + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ /**/p2: number): string; +}; + + p2 ↲ + p2: number ↲ + p0: number, /** Comment */ p1: number, /** Comment */ p2: number ↲ + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string;↲ + + { + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +} + +type A = { + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +}; + +type B = {}; +type A = { + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +}; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags12.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags12.baseline.diff new file mode 100644 index 0000000000..eabb41d041 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags12.baseline.diff @@ -0,0 +1,92 @@ +--- old.smartSelection_JSDocTags12.baseline ++++ new.smartSelection_JSDocTags12.baseline +@@= skipped -3, +3 lines =@@ + a(/** Comment */ /**/p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; + }; + +- +- p0 +- +- +- p0: number +- +- +- /** Comment */ p0: number +- +- +- /** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number +- +- +- a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +- +- +- ↲ +-••••a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string;↲ +- ++ p0 ↲ ++ p0: number ↲ ++ p0: number, /** Comment */ p1: number, /** Comment */ p2: number ↲ ++ a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string;↲ + + { + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +@@= skipped -40, +25 lines =@@ + a(/** Comment */ p0: number, /** Comment */ /**/p1: number, /** Comment */ p2: number): string; + }; + +- +- p1 +- +- +- p1: number +- +- +- /** Comment */ p1: number +- +- +- /** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number +- +- +- a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +- +- +- ↲ +-••••a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string;↲ +- ++ p1 ↲ ++ p1: number ↲ ++ p0: number, /** Comment */ p1: number, /** Comment */ p2: number ↲ ++ a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string;↲ + + { + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +@@= skipped -40, +25 lines =@@ + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ /**/p2: number): string; + }; + +- +- p2 +- +- +- p2: number +- +- +- /** Comment */ p2: number +- +- +- /** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number +- +- +- a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; +- +- +- ↲ +-••••a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string;↲ +- ++ p2 ↲ ++ p2: number ↲ ++ p0: number, /** Comment */ p1: number, /** Comment */ p2: number ↲ ++ a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string;↲ + + { + a(/** Comment */ p0: number, /** Comment */ p1: number, /** Comment */ p2: number): string; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags13.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags13.baseline new file mode 100644 index 0000000000..097324d32b --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags13.baseline @@ -0,0 +1,109 @@ +// === Smart Selection === +let a; +let b: { + /** Comment */ /**/p0: number + /** Comment */ p1: number + /** Comment */ p2: number +}; +let c; + + p0 ↲ + p0: number↲ + + p0: number + /** Comment */ p1: number + /** Comment */ p2: number↲ + + { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +} ↲ + +let b: { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +};↲ + +let a; +let b: { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +}; +let c; + +================================================================================ + +let a; +let b: { + /** Comment */ p0: number + /** Comment */ /**/p1: number + /** Comment */ p2: number +}; +let c; + + p1 ↲ + p1: number↲ + + p0: number + /** Comment */ p1: number + /** Comment */ p2: number↲ + + { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +} ↲ + +let b: { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +};↲ + +let a; +let b: { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +}; +let c; + +================================================================================ + +let a; +let b: { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ /**/p2: number +}; +let c; + + p2 ↲ + p2: number↲ + + p0: number + /** Comment */ p1: number + /** Comment */ p2: number↲ + + { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +} ↲ + +let b: { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +};↲ + +let a; +let b: { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +}; +let c; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags13.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags13.baseline.diff new file mode 100644 index 0000000000..229032e887 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags13.baseline.diff @@ -0,0 +1,126 @@ +--- old.smartSelection_JSDocTags13.baseline ++++ new.smartSelection_JSDocTags13.baseline +@@= skipped -6, +6 lines =@@ + }; + let c; + +- +- p0 +- ++ p0 ↲ ++ p0: number↲ + + p0: number +- +- +- /** Comment */ p0: number +- +- +- ↲ +-••••/** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number↲ + +- + { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +-} +- ++} ↲ + + let b: { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +-}; +- ++};↲ + + let a; + let b: { +@@= skipped -48, +37 lines =@@ + }; + let c; + +- +- p1 +- +- +- p1: number +- +- +- /** Comment */ p1: number +- +- +- ↲ +-••••/** Comment */ p0: number ++ p1 ↲ ++ p1: number↲ ++ ++ p0: number + /** Comment */ p1: number + /** Comment */ p2: number↲ + +- + { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +-} +- ++} ↲ + + let b: { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +-}; +- ++};↲ + + let a; + let b: { +@@= skipped -48, +37 lines =@@ + }; + let c; + +- +- p2 +- +- +- p2: number +- +- +- /** Comment */ p2: number +- +- +- ↲ +-••••/** Comment */ p0: number ++ p2 ↲ ++ p2: number↲ ++ ++ p0: number + /** Comment */ p1: number + /** Comment */ p2: number↲ + +- + { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +-} +- ++} ↲ + + let b: { + /** Comment */ p0: number + /** Comment */ p1: number + /** Comment */ p2: number +-}; +- ++};↲ + + let a; + let b: { \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags2.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags2.baseline new file mode 100644 index 0000000000..9096e04a80 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags2.baseline @@ -0,0 +1,19 @@ +// === Smart Selection === +/** + * @type {/**/string} + */ +const foo; + + string ↲ + + @type {string}↲ +• ↲ + +/** + * @type {string} + */↲ + +/** + * @type {string} + */ +const foo; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags2.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags2.baseline.diff new file mode 100644 index 0000000000..39de1ed1bc --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags2.baseline.diff @@ -0,0 +1,24 @@ +--- old.smartSelection_JSDocTags2.baseline ++++ new.smartSelection_JSDocTags2.baseline +@@= skipped -3, +3 lines =@@ + */ + const foo; + +- +- string +- ++ string ↲ + + @type {string}↲ +-• +- ++• ↲ + + /** + * @type {string} +- */ +- ++ */↲ + + /** + * @type {string} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags3.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags3.baseline new file mode 100644 index 0000000000..11c5873726 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags3.baseline @@ -0,0 +1,19 @@ +// === Smart Selection === +/** + * @param {/**/string} x + */ +function foo(x) {} + + string ↲ + + @param {string} x↲ +• ↲ + +/** + * @param {string} x + */↲ + +/** + * @param {string} x + */ +function foo(x) {} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags3.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags3.baseline.diff new file mode 100644 index 0000000000..ab5625443c --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags3.baseline.diff @@ -0,0 +1,25 @@ +--- old.smartSelection_JSDocTags3.baseline ++++ new.smartSelection_JSDocTags3.baseline +@@= skipped -3, +3 lines =@@ + */ + function foo(x) {} + +- +- string +- +- +- @param {string} x +- ++ string ↲ ++ ++ @param {string} x↲ ++• ↲ + + /** + * @param {string} x +- */ +- ++ */↲ + + /** + * @param {string} x \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags4.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags4.baseline new file mode 100644 index 0000000000..5501c65dcb --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags4.baseline @@ -0,0 +1,37 @@ +// === Smart Selection === +/** + * @typedef {object} Foo + * @property {string} a + * @property {number} b + * @property {/**/number} c + */ + +/** @type {Foo} */ +const foo; + + number ↲ + + @property {number} c↲ +• ↲ + + @typedef {object} Foo + * @property {string} a + * @property {number} b + * @property {number} c↲ +• ↲ + +/** + * @typedef {object} Foo + * @property {string} a + * @property {number} b + * @property {number} c + */↲ + +/** + * @typedef {object} Foo + * @property {string} a + * @property {number} b + * @property {number} c + */ +/** @type {Foo} */ +const foo; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags4.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags4.baseline.diff new file mode 100644 index 0000000000..f17991ca59 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags4.baseline.diff @@ -0,0 +1,54 @@ +--- old.smartSelection_JSDocTags4.baseline ++++ new.smartSelection_JSDocTags4.baseline +@@= skipped -8, +8 lines =@@ + /** @type {Foo} */ + const foo; + +- +- number +- +- +- @property {number} c +- +- +-/** +- * @typedef {object} Foo +- * @property {string} a +- * @property {number} b +- * @property {number} c +- */ +- +- +-/** +- * @typedef {object} Foo +- * @property {string} a +- * @property {number} b +- * @property {number} c +- */ +- ++ number ↲ ++ ++ @property {number} c↲ ++• ↲ ++ ++ @typedef {object} Foo ++ * @property {string} a ++ * @property {number} b ++ * @property {number} c↲ ++• ↲ ++ ++/** ++ * @typedef {object} Foo ++ * @property {string} a ++ * @property {number} b ++ * @property {number} c ++ */↲ ++ ++/** ++ * @typedef {object} Foo ++ * @property {string} a ++ * @property {number} b ++ * @property {number} c ++ */ + /** @type {Foo} */ + const foo; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags5.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags5.baseline new file mode 100644 index 0000000000..30c03e037b --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags5.baseline @@ -0,0 +1,41 @@ +// === Smart Selection === +/** + * @callback Foo + * @param {string} data + * @param {/**/number} [index] - comment + * @return {boolean} + */ + +/** @type {Foo} */ +const foo = s => !(s.length % 2); + + number ↲ + + @param {number} [index] - comment + *• ↲ + + @param {string} data + * @param {number} [index] - comment + *• ↲ + + @callback Foo + * @param {string} data + * @param {number} [index] - comment + * @return {boolean}↲ +• ↲ + +/** + * @callback Foo + * @param {string} data + * @param {number} [index] - comment + * @return {boolean} + */↲ + +/** + * @callback Foo + * @param {string} data + * @param {number} [index] - comment + * @return {boolean} + */ +/** @type {Foo} */ +const foo = s => !(s.length % 2); \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags5.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags5.baseline.diff new file mode 100644 index 0000000000..3403d78084 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags5.baseline.diff @@ -0,0 +1,56 @@ +--- old.smartSelection_JSDocTags5.baseline ++++ new.smartSelection_JSDocTags5.baseline +@@= skipped -8, +8 lines =@@ + /** @type {Foo} */ + const foo = s => !(s.length % 2); + +- +- number +- ++ number ↲ + + @param {number} [index] - comment +- +- +-/** +- * @callback Foo +- * @param {string} data +- * @param {number} [index] - comment +- * @return {boolean} +- */ +- +- +-/** +- * @callback Foo +- * @param {string} data +- * @param {number} [index] - comment +- * @return {boolean} +- */ +- ++ *• ↲ ++ ++ @param {string} data ++ * @param {number} [index] - comment ++ *• ↲ ++ ++ @callback Foo ++ * @param {string} data ++ * @param {number} [index] - comment ++ * @return {boolean}↲ ++• ↲ ++ ++/** ++ * @callback Foo ++ * @param {string} data ++ * @param {number} [index] - comment ++ * @return {boolean} ++ */↲ ++ ++/** ++ * @callback Foo ++ * @param {string} data ++ * @param {number} [index] - comment ++ * @return {boolean} ++ */ + /** @type {Foo} */ + const foo = s => !(s.length % 2); \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags6.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags6.baseline new file mode 100644 index 0000000000..e61baed7c5 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags6.baseline @@ -0,0 +1,34 @@ +// === Smart Selection === +/** + * @template T + * @param {/**/T} x + * @return {T} + */ +function foo(x) { + return x; +} + + T ↲ + + @param {T} x + *• ↲ + + @template T + * @param {T} x + * @return {T}↲ +• ↲ + +/** + * @template T + * @param {T} x + * @return {T} + */↲ + +/** + * @template T + * @param {T} x + * @return {T} + */ +function foo(x) { + return x; +} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags6.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags6.baseline.diff new file mode 100644 index 0000000000..866cc3980a --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags6.baseline.diff @@ -0,0 +1,29 @@ +--- old.smartSelection_JSDocTags6.baseline ++++ new.smartSelection_JSDocTags6.baseline +@@= skipped -7, +7 lines =@@ + return x; + } + +- +- T +- ++ T ↲ + + @param {T} x ++ *• ↲ + ++ @template T ++ * @param {T} x ++ * @return {T}↲ ++• ↲ + + /** + * @template T + * @param {T} x + * @return {T} +- */ +- ++ */↲ + + /** + * @template T \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags7.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags7.baseline new file mode 100644 index 0000000000..f11d6a5ef2 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags7.baseline @@ -0,0 +1,28 @@ +// === Smart Selection === +/** + * @constructor + * @param {/**/number} data + */ +function Foo(data) { +} + + number ↲ + + @param {number} data↲ +• ↲ + + @constructor + * @param {number} data↲ +• ↲ + +/** + * @constructor + * @param {number} data + */↲ + +/** + * @constructor + * @param {number} data + */ +function Foo(data) { +} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags7.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags7.baseline.diff new file mode 100644 index 0000000000..7192c0ba73 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags7.baseline.diff @@ -0,0 +1,30 @@ +--- old.smartSelection_JSDocTags7.baseline ++++ new.smartSelection_JSDocTags7.baseline +@@= skipped -5, +5 lines =@@ + function Foo(data) { + } + +- +- number +- +- +- @param {number} data +- ++ number ↲ ++ ++ @param {number} data↲ ++• ↲ ++ ++ @constructor ++ * @param {number} data↲ ++• ↲ + + /** + * @constructor + * @param {number} data +- */ +- ++ */↲ + + /** + * @constructor \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags8.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags8.baseline new file mode 100644 index 0000000000..a75ccd40a2 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags8.baseline @@ -0,0 +1,58 @@ +// === Smart Selection === +/** + * @this {/**/Foo} + * @param {*} e + */ +function callback(e) { +} + + Foo ↲ + + @this {Foo} + *• ↲ + + @this {Foo} + * @param {*} e↲ +• ↲ + +/** + * @this {Foo} + * @param {*} e + */↲ + +/** + * @this {Foo} + * @param {*} e + */ +function callback(e) { +} + +================================================================================ + +/** + * @this {Foo} + * @param {/**/*} e + */ +function callback(e) { +} + + * ↲ + + @param {*} e↲ +• ↲ + + @this {Foo} + * @param {*} e↲ +• ↲ + +/** + * @this {Foo} + * @param {*} e + */↲ + +/** + * @this {Foo} + * @param {*} e + */ +function callback(e) { +} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags8.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags8.baseline.diff new file mode 100644 index 0000000000..d193bd94bf --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags8.baseline.diff @@ -0,0 +1,58 @@ +--- old.smartSelection_JSDocTags8.baseline ++++ new.smartSelection_JSDocTags8.baseline +@@= skipped -5, +5 lines =@@ + function callback(e) { + } + +- +- Foo +- +- +- @this {Foo} +- ++ Foo ↲ ++ ++ @this {Foo} ++ *• ↲ ++ ++ @this {Foo} ++ * @param {*} e↲ ++• ↲ + + /** + * @this {Foo} + * @param {*} e +- */ +- ++ */↲ + + /** + * @this {Foo} +@@= skipped -29, +30 lines =@@ + function callback(e) { + } + +- +- * +- +- +- @param {*} e +- ++ * ↲ ++ ++ @param {*} e↲ ++• ↲ ++ ++ @this {Foo} ++ * @param {*} e↲ ++• ↲ + + /** + * @this {Foo} + * @param {*} e +- */ +- ++ */↲ + + /** + * @this {Foo} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags9.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags9.baseline new file mode 100644 index 0000000000..02e046a1ae --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags9.baseline @@ -0,0 +1,16 @@ +// === Smart Selection === +/** @enum {/**/number} */ +const Foo = { + x: 0, + y: 1, +}; + + {number}• ↲ + @enum {number}• ↲ +/** @enum {number} */↲ + +/** @enum {number} */ +const Foo = { + x: 0, + y: 1, +}; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags9.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags9.baseline.diff new file mode 100644 index 0000000000..755605b141 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_JSDocTags9.baseline.diff @@ -0,0 +1,21 @@ +--- old.smartSelection_JSDocTags9.baseline ++++ new.smartSelection_JSDocTags9.baseline +@@= skipped -4, +4 lines =@@ + y: 1, + }; + +- +- number +- +- +- @enum {number}• +- +- +-/** @enum {number} */ +- ++ {number}• ↲ ++ @enum {number}• ↲ ++/** @enum {number} */↲ + + /** @enum {number} */ + const Foo = { \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_behindCaret.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_behindCaret.baseline new file mode 100644 index 0000000000..5bbf265e58 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_behindCaret.baseline @@ -0,0 +1,4 @@ +// === Smart Selection === +let/**/ x: string + +let x: string \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_behindCaret.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_behindCaret.baseline.diff new file mode 100644 index 0000000000..ddbddf3615 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_behindCaret.baseline.diff @@ -0,0 +1,8 @@ +--- old.smartSelection_behindCaret.baseline ++++ new.smartSelection_behindCaret.baseline +@@= skipped -0, +0 lines =@@ + // === Smart Selection === + let/**/ x: string + +-let + let x: string \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_bindingPatterns.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_bindingPatterns.baseline new file mode 100644 index 0000000000..d6110452ef --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_bindingPatterns.baseline @@ -0,0 +1,27 @@ +// === Smart Selection === +const { /**/x, y: a, ...zs = {} } = {}; + + x + x, y: a, ...zs = {} + { x, y: a, ...zs = {} } +const { x, y: a, ...zs = {} } = {}; + +================================================================================ + +const { x, y: /**/a, ...zs = {} } = {}; + + a + y: a + x, y: a, ...zs = {} + { x, y: a, ...zs = {} } +const { x, y: a, ...zs = {} } = {}; + +================================================================================ + +const { x, y: a, .../**/zs = {} } = {}; + + zs + ...zs = {} + x, y: a, ...zs = {} + { x, y: a, ...zs = {} } +const { x, y: a, ...zs = {} } = {}; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_bindingPatterns.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_bindingPatterns.baseline.diff new file mode 100644 index 0000000000..501f81c821 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_bindingPatterns.baseline.diff @@ -0,0 +1,10 @@ +--- old.smartSelection_bindingPatterns.baseline ++++ new.smartSelection_bindingPatterns.baseline +@@= skipped -20, +20 lines =@@ + const { x, y: a, .../**/zs = {} } = {}; + + zs +- ...zs + ...zs = {} + x, y: a, ...zs = {} + { x, y: a, ...zs = {} } \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_comment1.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_comment1.baseline new file mode 100644 index 0000000000..2ce4a0f7c0 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_comment1.baseline @@ -0,0 +1,6 @@ +// === Smart Selection === +const a = 1; ///**/comment content + + comment content + //comment content +const a = 1; //comment content \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_comment2.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_comment2.baseline new file mode 100644 index 0000000000..4ce50a231c --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_comment2.baseline @@ -0,0 +1,6 @@ +// === Smart Selection === +const a = 1; //a b/**/c d + + a bc d + //a bc d +const a = 1; //a bc d \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_complex.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_complex.baseline new file mode 100644 index 0000000000..f844df6a1d --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_complex.baseline @@ -0,0 +1,12 @@ +// === Smart Selection === +type X = IsExactlyAny

extends true ? T : ({ [K in keyof P]: IsExactlyAny extends true ? K extends keyof T ? T[K] : P[/**/K] : P[K]; } & Pick>) + + K + P[K] + K extends keyof T ? T[K] : P[K] + IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K] + { [K in keyof P]: IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K]; } + { [K in keyof P]: IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K]; } & Pick> + ({ [K in keyof P]: IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K]; } & Pick>) + IsExactlyAny

extends true ? T : ({ [K in keyof P]: IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K]; } & Pick>) +type X = IsExactlyAny

extends true ? T : ({ [K in keyof P]: IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K]; } & Pick>) \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_complex.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_complex.baseline.diff new file mode 100644 index 0000000000..940e0969cb --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_complex.baseline.diff @@ -0,0 +1,11 @@ +--- old.smartSelection_complex.baseline ++++ new.smartSelection_complex.baseline +@@= skipped -4, +4 lines =@@ + P[K] + K extends keyof T ? T[K] : P[K] + IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K] +- IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K]; +- [K in keyof P]: IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K]; + { [K in keyof P]: IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K]; } + { [K in keyof P]: IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K]; } & Pick> + ({ [K in keyof P]: IsExactlyAny extends true ? K extends keyof T ? T[K] : P[K] : P[K]; } & Pick>) \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_emptyRanges.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_emptyRanges.baseline new file mode 100644 index 0000000000..f17e19b22e --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_emptyRanges.baseline @@ -0,0 +1,95 @@ +// === Smart Selection === +class HomePage { + componentDidMount(/**/) { + if (this.props.username) { + return ''; + } + } +} + + + componentDidMount() { + if (this.props.username) { + return ''; + } + }↲ + +class HomePage { + componentDidMount() { + if (this.props.username) { + return ''; + } + } +} + +================================================================================ + +class HomePage { + componentDidMount() { + if (this.props.username/**/) { + return ''; + } + } +} + + + if (this.props.username) { + return ''; + }↲ + + { + if (this.props.username) { + return ''; + } + }↲ + + componentDidMount() { + if (this.props.username) { + return ''; + } + }↲ + +class HomePage { + componentDidMount() { + if (this.props.username) { + return ''; + } + } +} + +================================================================================ + +class HomePage { + componentDidMount() { + if (this.props.username) { + return '/**/'; + } + } +} + + '' ↲ + return '';↲ + + if (this.props.username) { + return ''; + }↲ + + { + if (this.props.username) { + return ''; + } + }↲ + + componentDidMount() { + if (this.props.username) { + return ''; + } + }↲ + +class HomePage { + componentDidMount() { + if (this.props.username) { + return ''; + } + } +} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_emptyRanges.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_emptyRanges.baseline.diff new file mode 100644 index 0000000000..194bd64baa --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_emptyRanges.baseline.diff @@ -0,0 +1,128 @@ +--- old.smartSelection_emptyRanges.baseline ++++ new.smartSelection_emptyRanges.baseline +@@= skipped -7, +7 lines =@@ + } + + +- ) +- +- + componentDidMount() { + if (this.props.username) { + return ''; + } +- } +- +- +- ↲ +-••componentDidMount() { +- if (this.props.username) { +- return ''; +- } + }↲ +- + + class HomePage { + componentDidMount() { +@@= skipped -37, +25 lines =@@ + } + + +- username +- +- +- this.props.username +- +- + if (this.props.username) { +- return ''; +- } +- +- +- ↲ +-••••if (this.props.username) { + return ''; + }↲ +-•• +- + + { + if (this.props.username) { + return ''; + } +- } +- ++ }↲ + + componentDidMount() { + if (this.props.username) { + return ''; + } +- } +- +- +- ↲ +-••componentDidMount() { +- if (this.props.username) { +- return ''; +- } + }↲ +- + + class HomePage { + componentDidMount() { +@@= skipped -58, +34 lines =@@ + } + } + +- +- '' +- +- +- return ''; +- +- +- ↲ +-••••••return '';↲ +-•••• +- ++ '' ↲ ++ return '';↲ + + if (this.props.username) { +- return ''; +- } +- +- +- ↲ +-••••if (this.props.username) { + return ''; + }↲ +-•• +- + + { + if (this.props.username) { + return ''; + } +- } +- ++ }↲ + + componentDidMount() { + if (this.props.username) { + return ''; + } +- } +- +- +- ↲ +-••componentDidMount() { +- if (this.props.username) { +- return ''; +- } + }↲ +- + + class HomePage { + componentDidMount() { \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_function1.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_function1.baseline new file mode 100644 index 0000000000..6344b9c647 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_function1.baseline @@ -0,0 +1,17 @@ +// === Smart Selection === +const f1 = () => { + /**/ +}; + + + { + +} + + () => { + +} + +const f1 = () => { + +}; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_function2.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_function2.baseline new file mode 100644 index 0000000000..1b4f84b37c --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_function2.baseline @@ -0,0 +1,13 @@ +// === Smart Selection === +function f2() { + /**/ +} + + + { + +} + +function f2() { + +} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_function3.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_function3.baseline new file mode 100644 index 0000000000..afd3e7948c --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_function3.baseline @@ -0,0 +1,17 @@ +// === Smart Selection === +const f3 = function () { + /**/ +} + + + { + +} + + function () { + +} + +const f3 = function () { + +} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_functionParams1.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_functionParams1.baseline new file mode 100644 index 0000000000..b09fe5cf38 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_functionParams1.baseline @@ -0,0 +1,24 @@ +// === Smart Selection === +function f(/**/p, q?, ...r: any[] = []) {} + + p + p, q?, ...r: any[] = [] +function f(p, q?, ...r: any[] = []) {} + +================================================================================ + +function f(p, /**/q?, ...r: any[] = []) {} + + q + q? + p, q?, ...r: any[] = [] +function f(p, q?, ...r: any[] = []) {} + +================================================================================ + +function f(p, q?, /**/...r: any[] = []) {} + + ... + ...r: any[] = [] + p, q?, ...r: any[] = [] +function f(p, q?, ...r: any[] = []) {} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_functionParams1.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_functionParams1.baseline.diff new file mode 100644 index 0000000000..e16b3ff653 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_functionParams1.baseline.diff @@ -0,0 +1,11 @@ +--- old.smartSelection_functionParams1.baseline ++++ new.smartSelection_functionParams1.baseline +@@= skipped -18, +18 lines =@@ + function f(p, q?, /**/...r: any[] = []) {} + + ... +- ...r +- ...r: any[] + ...r: any[] = [] + p, q?, ...r: any[] = [] + function f(p, q?, ...r: any[] = []) {} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_functionParams2.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_functionParams2.baseline new file mode 100644 index 0000000000..f9c497907a --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_functionParams2.baseline @@ -0,0 +1,15 @@ +// === Smart Selection === +function f( + a, + /**/b +) {} + + b↲ + + a, + b↲ + +function f( + a, + b +) {} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_functionParams2.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_functionParams2.baseline.diff new file mode 100644 index 0000000000..669d9d0f32 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_functionParams2.baseline.diff @@ -0,0 +1,21 @@ +--- old.smartSelection_functionParams2.baseline ++++ new.smartSelection_functionParams2.baseline +@@= skipped -3, +3 lines =@@ + /**/b + ) {} + +- +- b +- +- +- ↲ +-••a, +- b↲ +- ++ b↲ ++ ++ a, ++ b↲ + + function f( + a, \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_imports.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_imports.baseline new file mode 100644 index 0000000000..f1208f23a3 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_imports.baseline @@ -0,0 +1,15 @@ +// === Smart Selection === +import { /**/x as y, z } from './z'; +import { b } from './'; + +console.log(1); + + x ↲ + x as y ↲ + x as y, z ↲ + { x as y, z } ↲ +import { x as y, z } from './z';↲ + +import { x as y, z } from './z'; +import { b } from './'; +console.log(1); \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_imports.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_imports.baseline.diff new file mode 100644 index 0000000000..f0ecf62be0 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_imports.baseline.diff @@ -0,0 +1,38 @@ +--- old.smartSelection_imports.baseline ++++ new.smartSelection_imports.baseline +@@= skipped -3, +3 lines =@@ + + console.log(1); + +- +- x +- +- +- x as y +- +- +- x as y, z +- +- +- { x as y, z } +- +- +-import { x as y, z } from './z'; +- +- +-import { x as y, z } from './z'; +-import { b } from './'; +- +- +-import { x as y, z } from './z'; +-import { b } from './'; +- ++ x ↲ ++ x as y ↲ ++ x as y, z ↲ ++ { x as y, z } ↲ ++import { x as y, z } from './z';↲ ++ ++import { x as y, z } from './z'; ++import { b } from './'; + console.log(1); \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_lastBlankLine.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_lastBlankLine.baseline new file mode 100644 index 0000000000..ad833f2342 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_lastBlankLine.baseline @@ -0,0 +1,5 @@ +// === Smart Selection === +class C {} +/**/ + +class C {}↲ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_lastBlankLine.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_lastBlankLine.baseline.diff new file mode 100644 index 0000000000..70c334f791 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_lastBlankLine.baseline.diff @@ -0,0 +1,8 @@ +--- old.smartSelection_lastBlankLine.baseline ++++ new.smartSelection_lastBlankLine.baseline +@@= skipped -1, +1 lines =@@ + class C {} + /**/ + +- + class C {}↲ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_loneVariableDeclaration.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_loneVariableDeclaration.baseline new file mode 100644 index 0000000000..c1151f045f --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_loneVariableDeclaration.baseline @@ -0,0 +1,5 @@ +// === Smart Selection === +const /**/x = 3; + + x +const x = 3; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_mappedTypes.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_mappedTypes.baseline new file mode 100644 index 0000000000..e7f008d407 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_mappedTypes.baseline @@ -0,0 +1,44 @@ +// === Smart Selection === +type M = { /**/-readonly [K in keyof any]-?: any }; + + - + { -readonly [K in keyof any]-?: any } +type M = { -readonly [K in keyof any]-?: any }; + +================================================================================ + +type M = { -re/**/adonly [K in keyof any]-?: any }; + + { -readonly [K in keyof any]-?: any } +type M = { -readonly [K in keyof any]-?: any }; + +================================================================================ + +type M = { -readonly /**/[K in keyof any]-?: any }; + + { -readonly [K in keyof any]-?: any } +type M = { -readonly [K in keyof any]-?: any }; + +================================================================================ + +type M = { -readonly [K in ke/**/yof any]-?: any }; + + keyof any + K in keyof any + { -readonly [K in keyof any]-?: any } +type M = { -readonly [K in keyof any]-?: any }; + +================================================================================ + +type M = { -readonly [K in keyof any]/**/-?: any }; + + - + { -readonly [K in keyof any]-?: any } +type M = { -readonly [K in keyof any]-?: any }; + +================================================================================ + +type M = { -readonly [K in keyof any]-/**/?: any }; + + { -readonly [K in keyof any]-?: any } +type M = { -readonly [K in keyof any]-?: any }; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_mappedTypes.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_mappedTypes.baseline.diff new file mode 100644 index 0000000000..5a6c3570d4 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_mappedTypes.baseline.diff @@ -0,0 +1,67 @@ +--- old.smartSelection_mappedTypes.baseline ++++ new.smartSelection_mappedTypes.baseline +@@= skipped -1, +1 lines =@@ + type M = { /**/-readonly [K in keyof any]-?: any }; + + - +- -readonly +- -readonly [K in keyof any]-? +- -readonly [K in keyof any]-?: any + { -readonly [K in keyof any]-?: any } + type M = { -readonly [K in keyof any]-?: any }; + +@@= skipped -10, +7 lines =@@ + + type M = { -re/**/adonly [K in keyof any]-?: any }; + +- readonly +- -readonly +- -readonly [K in keyof any]-? +- -readonly [K in keyof any]-?: any + { -readonly [K in keyof any]-?: any } + type M = { -readonly [K in keyof any]-?: any }; + +@@= skipped -11, +7 lines =@@ + + type M = { -readonly /**/[K in keyof any]-?: any }; + +- [ +- [K in keyof any] +- -readonly [K in keyof any]-? +- -readonly [K in keyof any]-?: any + { -readonly [K in keyof any]-?: any } + type M = { -readonly [K in keyof any]-?: any }; + +@@= skipped -11, +7 lines =@@ + + type M = { -readonly [K in ke/**/yof any]-?: any }; + +- keyof + keyof any + K in keyof any +- [K in keyof any] +- -readonly [K in keyof any]-? +- -readonly [K in keyof any]-?: any + { -readonly [K in keyof any]-?: any } + type M = { -readonly [K in keyof any]-?: any }; + +@@= skipped -14, +10 lines =@@ + type M = { -readonly [K in keyof any]/**/-?: any }; + + - +- -? +- -readonly [K in keyof any]-? +- -readonly [K in keyof any]-?: any + { -readonly [K in keyof any]-?: any } + type M = { -readonly [K in keyof any]-?: any }; + +@@= skipped -10, +7 lines =@@ + + type M = { -readonly [K in keyof any]-/**/?: any }; + +- ? +- -? +- -readonly [K in keyof any]-? +- -readonly [K in keyof any]-?: any + { -readonly [K in keyof any]-?: any } + type M = { -readonly [K in keyof any]-?: any }; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_objectTypes.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_objectTypes.baseline new file mode 100644 index 0000000000..2cd2a914e1 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_objectTypes.baseline @@ -0,0 +1,134 @@ +// === Smart Selection === +type X = { + /**/foo?: string; + readonly bar: { x: number }; + meh +} + + foo ↲ + foo?: string;↲ + + foo?: string; + readonly bar: { x: number }; + meh↲ + + { + foo?: string; + readonly bar: { x: number }; + meh +} + +type X = { + foo?: string; + readonly bar: { x: number }; + meh +} + +================================================================================ + +type X = { + foo?: string; + /**/readonly bar: { x: number }; + meh +} + + readonly ↲ + readonly bar: { x: number };↲ + + foo?: string; + readonly bar: { x: number }; + meh↲ + + { + foo?: string; + readonly bar: { x: number }; + meh +} + +type X = { + foo?: string; + readonly bar: { x: number }; + meh +} + +================================================================================ + +type X = { + foo?: string; + readonly /**/bar: { x: number }; + meh +} + + bar ↲ + readonly bar: { x: number };↲ + + foo?: string; + readonly bar: { x: number }; + meh↲ + + { + foo?: string; + readonly bar: { x: number }; + meh +} + +type X = { + foo?: string; + readonly bar: { x: number }; + meh +} + +================================================================================ + +type X = { + foo?: string; + readonly bar: { x: num/**/ber }; + meh +} + + number ↲ + x: number ↲ + { x: number } ↲ + readonly bar: { x: number };↲ + + foo?: string; + readonly bar: { x: number }; + meh↲ + + { + foo?: string; + readonly bar: { x: number }; + meh +} + +type X = { + foo?: string; + readonly bar: { x: number }; + meh +} + +================================================================================ + +type X = { + foo?: string; + readonly bar: { x: number }; + /**/meh +} + + meh↲ + + foo?: string; + readonly bar: { x: number }; + meh↲ + + { + foo?: string; + readonly bar: { x: number }; + meh +} + +type X = { + foo?: string; + readonly bar: { x: number }; + meh +} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_objectTypes.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_objectTypes.baseline.diff new file mode 100644 index 0000000000..66f80dbaef --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_objectTypes.baseline.diff @@ -0,0 +1,128 @@ +--- old.smartSelection_objectTypes.baseline ++++ new.smartSelection_objectTypes.baseline +@@= skipped -4, +4 lines =@@ + meh + } + +- +- foo +- +- +- foo? +- ++ foo ↲ ++ foo?: string;↲ + + foo?: string; +- +- +- ↲ +-••foo?: string; + readonly bar: { x: number }; + meh↲ +- + + { + foo?: string; +@@= skipped -36, +27 lines =@@ + meh + } + +- +- readonly +- +- +- readonly bar +- +- +- readonly bar: { x: number }; +- +- +- ↲ +-••foo?: string; ++ readonly ↲ ++ readonly bar: { x: number };↲ ++ ++ foo?: string; + readonly bar: { x: number }; + meh↲ +- + + { + foo?: string; +@@= skipped -36, +27 lines =@@ + meh + } + +- +- bar +- +- +- readonly bar +- +- +- readonly bar: { x: number }; +- +- +- ↲ +-••foo?: string; ++ bar ↲ ++ readonly bar: { x: number };↲ ++ ++ foo?: string; + readonly bar: { x: number }; + meh↲ +- + + { + foo?: string; +@@= skipped -36, +27 lines =@@ + meh + } + +- +- number +- +- +- x: number +- +- +- { x: number } +- +- +- readonly bar: { x: number }; +- +- +- ↲ +-••foo?: string; ++ number ↲ ++ x: number ↲ ++ { x: number } ↲ ++ readonly bar: { x: number };↲ ++ ++ foo?: string; + readonly bar: { x: number }; + meh↲ +- + + { + foo?: string; +@@= skipped -39, +29 lines =@@ + /**/meh + } + +- +- meh +- +- +- ↲ +-••foo?: string; ++ meh↲ ++ ++ foo?: string; + readonly bar: { x: number }; + meh↲ +- + + { + foo?: string; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_punctuationPriority.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_punctuationPriority.baseline new file mode 100644 index 0000000000..d23bdd4dd3 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_punctuationPriority.baseline @@ -0,0 +1,6 @@ +// === Smart Selection === +console/**/.log(); + +console.log +console.log() +console.log(); \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_punctuationPriority.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_punctuationPriority.baseline.diff new file mode 100644 index 0000000000..2ca3c1bf93 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_punctuationPriority.baseline.diff @@ -0,0 +1,10 @@ +--- old.smartSelection_punctuationPriority.baseline ++++ new.smartSelection_punctuationPriority.baseline +@@= skipped -0, +0 lines =@@ + // === Smart Selection === + console/**/.log(); + +-console + console.log + console.log() + console.log(); \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_simple1.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_simple1.baseline new file mode 100644 index 0000000000..8027901532 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_simple1.baseline @@ -0,0 +1,90 @@ +// === Smart Selection === +class Foo { + bar(a, b) { + if (/**/a === b) { + return true; + } + return false; + } +} + + a ↲ + a === b ↲ + + if (a === b) { + return true; + }↲ + + if (a === b) { + return true; + } + return false;↲ + + { + if (a === b) { + return true; + } + return false; + }↲ + + bar(a, b) { + if (a === b) { + return true; + } + return false; + }↲ + +class Foo { + bar(a, b) { + if (a === b) { + return true; + } + return false; + } +} + +================================================================================ + +class Foo { + bar(a, b) { + if (a === b) { + return tr/**/ue; + } + return false; + } +} + + true ↲ + return true;↲ + + if (a === b) { + return true; + }↲ + + if (a === b) { + return true; + } + return false;↲ + + { + if (a === b) { + return true; + } + return false; + }↲ + + bar(a, b) { + if (a === b) { + return true; + } + return false; + }↲ + +class Foo { + bar(a, b) { + if (a === b) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_simple1.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_simple1.baseline.diff new file mode 100644 index 0000000000..3dca3d25ec --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_simple1.baseline.diff @@ -0,0 +1,124 @@ +--- old.smartSelection_simple1.baseline ++++ new.smartSelection_simple1.baseline +@@= skipped -7, +7 lines =@@ + } + } + +- +- a +- +- +- a === b +- ++ a ↲ ++ a === b ↲ + + if (a === b) { + return true; +- } +- +- +- ↲ +-••••••if (a === b) { ++ }↲ ++ ++ if (a === b) { + return true; + } + return false;↲ +-•• +- + + { + if (a === b) { + return true; + } + return false; +- } +- ++ }↲ + + bar(a, b) { + if (a === b) { + return true; + } + return false; +- } +- +- +- ↲ +-••bar(a, b) { +- if (a === b) { +- return true; +- } +- return false; + }↲ +- + + class Foo { + bar(a, b) { +@@= skipped -65, +46 lines =@@ + } + } + +- +- true +- +- +- return true; +- +- +- ↲ +-••••••••••return true;↲ +-•••••• +- +- +- if (a === b) { +- return true; +- } +- +- +- ↲ +-••••••if (a === b) { ++ true ↲ ++ return true;↲ ++ ++ if (a === b) { ++ return true; ++ }↲ ++ ++ if (a === b) { + return true; + } + return false;↲ +-•• +- + + { + if (a === b) { + return true; + } + return false; +- } +- ++ }↲ + + bar(a, b) { + if (a === b) { + return true; + } + return false; +- } +- +- +- ↲ +-••bar(a, b) { +- if (a === b) { +- return true; +- } +- return false; + }↲ +- + + class Foo { + bar(a, b) { \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_simple2.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_simple2.baseline new file mode 100644 index 0000000000..34d63f7949 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_simple2.baseline @@ -0,0 +1,38 @@ +// === Smart Selection === +export interface IService { + _serviceBrand: any; + + open(ho/**/st: number, data: any): Promise; + bar(): void +} + + host ↲ + host: number ↲ + host: number, data: any ↲ + open(host: number, data: any): Promise;↲ + + _serviceBrand: any; + open(host: number, data: any): Promise; + bar(): void↲ + +export interface IService { + _serviceBrand: any; + open(host: number, data: any): Promise; + bar(): void +} + +================================================================================ + +export interface IService { + _serviceBrand: any; + + open(host: number, data: any): Promise; + bar(): void/**/ +} + + +export interface IService { + _serviceBrand: any; + open(host: number, data: any): Promise; + bar(): void +} \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_simple2.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_simple2.baseline.diff new file mode 100644 index 0000000000..ca0b9e1cd8 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_simple2.baseline.diff @@ -0,0 +1,61 @@ +--- old.smartSelection_simple2.baseline ++++ new.smartSelection_simple2.baseline +@@= skipped -5, +5 lines =@@ + bar(): void + } + +- +- host +- +- +- host: number +- +- +- host: number, data: any +- +- +- open(host: number, data: any): Promise; +- +- +- ↲ +-••_serviceBrand: any; +- ++ host ↲ ++ host: number ↲ ++ host: number, data: any ↲ ++ open(host: number, data: any): Promise;↲ ++ ++ _serviceBrand: any; + open(host: number, data: any): Promise; + bar(): void↲ + +- + export interface IService { + _serviceBrand: any; +- + open(host: number, data: any): Promise; + bar(): void + } +@@= skipped -37, +25 lines =@@ + } + + +- void +- +- +- bar(): void +- +- +- ↲ +-••_serviceBrand: any; +- +- open(host: number, data: any): Promise; +- bar(): void↲ +- +- + export interface IService { + _serviceBrand: any; +- + open(host: number, data: any): Promise; + bar(): void + } \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_stringLiteral.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_stringLiteral.baseline new file mode 100644 index 0000000000..883f9f5ab3 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_stringLiteral.baseline @@ -0,0 +1,9 @@ +// === Smart Selection === +const a = 'a'; +const b = /**/'b'; + + 'b' +const b = 'b'; + +const a = 'a'; +const b = 'b'; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_stringLiteral.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_stringLiteral.baseline.diff new file mode 100644 index 0000000000..0bde7503b4 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_stringLiteral.baseline.diff @@ -0,0 +1,12 @@ +--- old.smartSelection_stringLiteral.baseline ++++ new.smartSelection_stringLiteral.baseline +@@= skipped -1, +1 lines =@@ + const a = 'a'; + const b = /**/'b'; + +- + 'b' +- + const b = 'b'; + + const a = 'a'; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_templateStrings.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_templateStrings.baseline new file mode 100644 index 0000000000..ada0f0c185 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_templateStrings.baseline @@ -0,0 +1,24 @@ +// === Smart Selection === +`a /**/b ${ + 'c' +} d` + + +`a b ${ + 'c' +} d` + +================================================================================ + +`a b ${ + '/**/c' +} d` + + 'c'↲ + + 'c' +} d` + +`a b ${ + 'c' +} d` \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_templateStrings.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_templateStrings.baseline.diff new file mode 100644 index 0000000000..ad54e4e730 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_templateStrings.baseline.diff @@ -0,0 +1,38 @@ +--- old.smartSelection_templateStrings.baseline ++++ new.smartSelection_templateStrings.baseline +@@= skipped -3, +3 lines =@@ + } d` + + +- a b ${ +- 'c' +-} d +- + `a b ${ + 'c' + } d` +@@= skipped -14, +10 lines =@@ + '/**/c' + } d` + +- +- c +- +- +- 'c' +- +- +- ${ +- 'c' +-} +- +- a b ${ +- 'c' +-} d ++ 'c'↲ ++ ++ 'c' ++} d` + + `a b ${ + 'c' \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_templateStrings2.baseline b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_templateStrings2.baseline new file mode 100644 index 0000000000..02d752f0e4 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_templateStrings2.baseline @@ -0,0 +1,5 @@ +// === Smart Selection === +`a ${b} /**/c` + + b} c` +`a ${b} c` \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_templateStrings2.baseline.diff b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_templateStrings2.baseline.diff new file mode 100644 index 0000000000..d16641c618 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/smartSelection/smartSelection_templateStrings2.baseline.diff @@ -0,0 +1,9 @@ +--- old.smartSelection_templateStrings2.baseline ++++ new.smartSelection_templateStrings2.baseline +@@= skipped -0, +0 lines =@@ + // === Smart Selection === + `a ${b} /**/c` + +- a ${b} c ++ b} c` + `a ${b} c` \ No newline at end of file