diff --git a/internal/ast/utilities.go b/internal/ast/utilities.go index 72ba07ee60..fff659314b 100644 --- a/internal/ast/utilities.go +++ b/internal/ast/utilities.go @@ -1386,7 +1386,7 @@ func GetNameOfDeclaration(declaration *Node) *Node { return nonAssignedName } if IsFunctionExpression(declaration) || IsArrowFunction(declaration) || IsClassExpression(declaration) { - return getAssignedName(declaration) + return GetAssignedName(declaration) } return nil } @@ -1415,7 +1415,7 @@ func GetNonAssignedNameOfDeclaration(declaration *Node) *Node { return declaration.Name() } -func getAssignedName(node *Node) *Node { +func GetAssignedName(node *Node) *Node { parent := node.Parent if parent != nil { switch parent.Kind { @@ -3441,6 +3441,91 @@ func IsRightSideOfPropertyAccess(node *Node) bool { return node.Parent.Kind == KindPropertyAccessExpression && node.Parent.Name() == node } +func IsArgumentExpressionOfElementAccess(node *Node) bool { + return node.Parent != nil && node.Parent.Kind == KindElementAccessExpression && node.Parent.AsElementAccessExpression().ArgumentExpression == node +} + +func ClimbPastPropertyAccess(node *Node) *Node { + if IsRightSideOfPropertyAccess(node) { + return node.Parent + } + return node +} + +func climbPastPropertyOrElementAccess(node *Node) *Node { + if IsRightSideOfPropertyAccess(node) || IsArgumentExpressionOfElementAccess(node) { + return node.Parent + } + return node +} + +func selectExpressionOfCallOrNewExpressionOrDecorator(node *Node) *Node { + if IsCallExpression(node) || IsNewExpression(node) || IsDecorator(node) { + return node.Expression() + } + return nil +} + +func selectTagOfTaggedTemplateExpression(node *Node) *Node { + if IsTaggedTemplateExpression(node) { + return node.AsTaggedTemplateExpression().Tag + } + return nil +} + +func selectTagNameOfJsxOpeningLikeElement(node *Node) *Node { + if IsJsxOpeningElement(node) || IsJsxSelfClosingElement(node) { + return node.TagName() + } + return nil +} + +func IsCallExpressionTarget(node *Node, includeElementAccess bool, skipPastOuterExpressions bool) bool { + return isCalleeWorker(node, IsCallExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions) +} + +func IsNewExpressionTarget(node *Node, includeElementAccess bool, skipPastOuterExpressions bool) bool { + return isCalleeWorker(node, IsNewExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions) +} + +func IsCallOrNewExpressionTarget(node *Node, includeElementAccess bool, skipPastOuterExpressions bool) bool { + return isCalleeWorker(node, IsCallOrNewExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions) +} + +func IsTaggedTemplateTag(node *Node, includeElementAccess bool, skipPastOuterExpressions bool) bool { + return isCalleeWorker(node, IsTaggedTemplateExpression, selectTagOfTaggedTemplateExpression, includeElementAccess, skipPastOuterExpressions) +} + +func IsDecoratorTarget(node *Node, includeElementAccess bool, skipPastOuterExpressions bool) bool { + return isCalleeWorker(node, IsDecorator, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions) +} + +func IsJsxOpeningLikeElementTagName(node *Node, includeElementAccess bool, skipPastOuterExpressions bool) bool { + return isCalleeWorker(node, IsJsxOpeningLikeElement, selectTagNameOfJsxOpeningLikeElement, includeElementAccess, skipPastOuterExpressions) +} + +func isCalleeWorker( + node *Node, + pred func(*Node) bool, + calleeSelector func(*Node) *Node, + includeElementAccess bool, + skipPastOuterExpressions bool, +) bool { + var target *Node + if includeElementAccess { + target = climbPastPropertyOrElementAccess(node) + } else { + target = ClimbPastPropertyAccess(node) + } + if skipPastOuterExpressions { + // Only skip outer expressions if the target is actually an expression node + if IsExpression(target) { + target = SkipOuterExpressions(target, OEKAll) + } + } + return target != nil && target.Parent != nil && pred(target.Parent) && calleeSelector(target.Parent) == target +} + func IsRightSideOfQualifiedNameOrPropertyAccess(node *Node) bool { parent := node.Parent switch parent.Kind { diff --git a/internal/fourslash/_scripts/convertFourslash.mts b/internal/fourslash/_scripts/convertFourslash.mts index f92a261c28..61b789df13 100644 --- a/internal/fourslash/_scripts/convertFourslash.mts +++ b/internal/fourslash/_scripts/convertFourslash.mts @@ -204,6 +204,8 @@ function parseFourslashStatement(statement: ts.Statement): Cmd[] | undefined { return parseNoSignatureHelpForTriggerReason(callExpression.arguments); case "baselineSmartSelection": return [parseBaselineSmartSelection(callExpression.arguments)]; + case "baselineCallHierarchy": + return [parseBaselineCallHierarchy(callExpression.arguments)]; case "baselineGoToDefinition": case "baselineGetDefinitionAtPosition": case "baselineGoToType": @@ -2025,6 +2027,15 @@ function parseBaselineSmartSelection(args: ts.NodeArray): Cmd { }; } +function parseBaselineCallHierarchy(args: ts.NodeArray): Cmd { + if (args.length !== 0) { + throw new Error("Expected no arguments in verify.baselineCallHierarchy"); + } + return { + kind: "verifyBaselineCallHierarchy", + }; +} + function parseKind(expr: ts.Expression): string | undefined { if (!ts.isStringLiteral(expr)) { console.error(`Expected string literal for kind, got ${expr.getText()}`); @@ -2399,6 +2410,10 @@ interface VerifyBaselineSmartSelection { kind: "verifyBaselineSmartSelection"; } +interface VerifyBaselineCallHierarchy { + kind: "verifyBaselineCallHierarchy"; +} + interface VerifyBaselineRenameCmd { kind: "verifyBaselineRename" | "verifyBaselineRenameAtRangesWithText"; args: string[]; @@ -2511,6 +2526,7 @@ type Cmd = | VerifyNoSignatureHelpCmd | VerifySignatureHelpPresentCmd | VerifyNoSignatureHelpForTriggerReasonCmd + | VerifyBaselineCallHierarchy | GoToCmd | EditCmd | VerifyQuickInfoCmd @@ -2777,6 +2793,8 @@ function generateCmd(cmd: Cmd): string { return `f.VerifyBaselineSignatureHelp(t)`; case "verifyBaselineSmartSelection": return `f.VerifyBaselineSelectionRanges(t)`; + case "verifyBaselineCallHierarchy": + return `f.VerifyBaselineCallHierarchy(t)`; case "goTo": return generateGoToCommand(cmd); case "edit": diff --git a/internal/fourslash/baselineutil.go b/internal/fourslash/baselineutil.go index b49fb6b28b..7f2fdf27a0 100644 --- a/internal/fourslash/baselineutil.go +++ b/internal/fourslash/baselineutil.go @@ -22,6 +22,7 @@ import ( const ( autoImportsCmd baselineCommand = "Auto Imports" + callHierarchyCmd baselineCommand = "Call Hierarchy" documentHighlightsCmd baselineCommand = "documentHighlights" findAllReferencesCmd baselineCommand = "findAllReferences" goToDefinitionCmd baselineCommand = "goToDefinition" @@ -71,6 +72,8 @@ func getBaselineExtension(command baselineCommand) string { switch command { case quickInfoCmd, signatureHelpCmd, smartSelectionCmd, inlayHintsCmd, nonSuggestionDiagnosticsCmd: return "baseline" + case callHierarchyCmd: + return "callHierarchy.txt" case autoImportsCmd: return "baseline.md" default: @@ -91,6 +94,21 @@ func (f *FourslashTest) getBaselineOptions(command baselineCommand, testPath str Subfolder: subfolder, IsSubmodule: true, } + case callHierarchyCmd: + return baseline.Options{ + Subfolder: subfolder, + IsSubmodule: true, + DiffFixupOld: func(s string) string { + // TypeScript baselines have "/tests/cases/fourslash/" prefix in file paths + // Handle /server/ subdirectory - need to remove both prefixes + s = strings.ReplaceAll(s, "/tests/cases/fourslash/server/", "/") + s = strings.ReplaceAll(s, "/tests/cases/fourslash/", "/") + // SymbolKind enum differences between Strada and tsgo + s = strings.ReplaceAll(s, "kind: getter", "kind: property") + s = strings.ReplaceAll(s, "kind: script", "kind: file") + return s + }, + } case renameCmd: return baseline.Options{ Subfolder: subfolder, diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index dbf7f02d82..d3e20df39c 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -7,6 +7,7 @@ import ( "maps" "runtime" "slices" + "strconv" "strings" "testing" "unicode/utf8" @@ -268,7 +269,23 @@ func getBaseFileNameFromTest(t *testing.T) string { name := t.Name() name = core.LastOrNil(strings.Split(name, "/")) name = strings.TrimPrefix(name, "Test") - return stringutil.LowerFirstChar(name) + name = stringutil.LowerFirstChar(name) + + // Special case: TypeScript has "callHierarchyFunctionAmbiguity.N" with periods + switch name { + case "callHierarchyFunctionAmbiguity1": + name = "callHierarchyFunctionAmbiguity.1" + case "callHierarchyFunctionAmbiguity2": + name = "callHierarchyFunctionAmbiguity.2" + case "callHierarchyFunctionAmbiguity3": + name = "callHierarchyFunctionAmbiguity.3" + case "callHierarchyFunctionAmbiguity4": + name = "callHierarchyFunctionAmbiguity.4" + case "callHierarchyFunctionAmbiguity5": + name = "callHierarchyFunctionAmbiguity.5" + } + + return name } func (f *FourslashTest) nextID() int32 { @@ -1751,6 +1768,310 @@ func (f *FourslashTest) VerifyBaselineSelectionRanges(t *testing.T) { f.addResultToBaseline(t, smartSelectionCmd, strings.TrimSuffix(result.String(), "\n")) } +func (f *FourslashTest) VerifyBaselineCallHierarchy(t *testing.T) { + fileName := f.activeFilename + position := f.currentCaretPosition + + params := &lsproto.CallHierarchyPrepareParams{ + TextDocument: lsproto.TextDocumentIdentifier{ + Uri: lsconv.FileNameToDocumentURI(fileName), + }, + Position: position, + } + + prepareResult := sendRequest(t, f, lsproto.TextDocumentPrepareCallHierarchyInfo, params) + if prepareResult.CallHierarchyItems == nil || len(*prepareResult.CallHierarchyItems) == 0 { + f.addResultToBaseline(t, callHierarchyCmd, "No call hierarchy items available") + return + } + + var result strings.Builder + + for _, callHierarchyItem := range *prepareResult.CallHierarchyItems { + seen := make(map[callHierarchyItemKey]bool) + itemFileName := callHierarchyItem.Uri.FileName() + script := f.getScriptInfo(itemFileName) + formatCallHierarchyItem(t, f, script, &result, *callHierarchyItem, callHierarchyItemDirectionRoot, seen, "") + } + + f.addResultToBaseline(t, callHierarchyCmd, strings.TrimSuffix(result.String(), "\n")) +} + +type callHierarchyItemDirection int + +const ( + callHierarchyItemDirectionRoot callHierarchyItemDirection = iota + callHierarchyItemDirectionIncoming + callHierarchyItemDirectionOutgoing +) + +type callHierarchyItemKey struct { + uri lsproto.DocumentUri + range_ lsproto.Range + direction callHierarchyItemDirection +} + +func symbolKindToLowercase(kind lsproto.SymbolKind) string { + return strings.ToLower(kind.String()) +} + +func formatCallHierarchyItem( + t *testing.T, + f *FourslashTest, + file *scriptInfo, + result *strings.Builder, + callHierarchyItem lsproto.CallHierarchyItem, + direction callHierarchyItemDirection, + seen map[callHierarchyItemKey]bool, + prefix string, +) { + key := callHierarchyItemKey{ + uri: callHierarchyItem.Uri, + range_: callHierarchyItem.Range, + direction: direction, + } + alreadySeen := seen[key] + seen[key] = true + + type incomingCallResult struct { + skip bool + seen bool + values []*lsproto.CallHierarchyIncomingCall + } + type outgoingCallResult struct { + skip bool + seen bool + values []*lsproto.CallHierarchyOutgoingCall + } + + var incomingCalls incomingCallResult + var outgoingCalls outgoingCallResult + + if direction == callHierarchyItemDirectionOutgoing { + incomingCalls.skip = true + } else if alreadySeen { + incomingCalls.seen = true + } else { + incomingParams := &lsproto.CallHierarchyIncomingCallsParams{ + Item: &callHierarchyItem, + } + incomingResult := sendRequest(t, f, lsproto.CallHierarchyIncomingCallsInfo, incomingParams) + if incomingResult.CallHierarchyIncomingCalls != nil { + incomingCalls.values = *incomingResult.CallHierarchyIncomingCalls + } + } + + if direction == callHierarchyItemDirectionIncoming { + outgoingCalls.skip = true + } else if alreadySeen { + outgoingCalls.seen = true + } else { + outgoingParams := &lsproto.CallHierarchyOutgoingCallsParams{ + Item: &callHierarchyItem, + } + outgoingResult := sendRequest(t, f, lsproto.CallHierarchyOutgoingCallsInfo, outgoingParams) + if outgoingResult.CallHierarchyOutgoingCalls != nil { + outgoingCalls.values = *outgoingResult.CallHierarchyOutgoingCalls + } + } + + trailingPrefix := prefix + result.WriteString(fmt.Sprintf("%s╭ name: %s\n", prefix, callHierarchyItem.Name)) + result.WriteString(fmt.Sprintf("%s├ kind: %s\n", prefix, symbolKindToLowercase(callHierarchyItem.Kind))) + if callHierarchyItem.Detail != nil && *callHierarchyItem.Detail != "" { + result.WriteString(fmt.Sprintf("%s├ containerName: %s\n", prefix, *callHierarchyItem.Detail)) + } + result.WriteString(fmt.Sprintf("%s├ file: %s\n", prefix, callHierarchyItem.Uri.FileName())) + result.WriteString(prefix + "├ span:\n") + formatCallHierarchyItemSpan(f, file, result, callHierarchyItem.Range, prefix+"│ ", prefix+"│ ") + result.WriteString(prefix + "├ selectionSpan:\n") + formatCallHierarchyItemSpan(f, file, result, callHierarchyItem.SelectionRange, prefix+"│ ", prefix+"│ ") + + // Handle incoming calls + if incomingCalls.seen { + if outgoingCalls.skip { + result.WriteString(trailingPrefix + "╰ incoming: ...\n") + } else { + result.WriteString(prefix + "├ incoming: ...\n") + } + } else if !incomingCalls.skip { + if len(incomingCalls.values) == 0 { + if outgoingCalls.skip { + result.WriteString(trailingPrefix + "╰ incoming: none\n") + } else { + result.WriteString(prefix + "├ incoming: none\n") + } + } else { + result.WriteString(prefix + "├ incoming:\n") + for i, incomingCall := range incomingCalls.values { + fromFileName := incomingCall.From.Uri.FileName() + fromFile := f.getScriptInfo(fromFileName) + result.WriteString(prefix + "│ ╭ from:\n") + formatCallHierarchyItem(t, f, fromFile, result, *incomingCall.From, callHierarchyItemDirectionIncoming, seen, prefix+"│ │ ") + result.WriteString(prefix + "│ ├ fromSpans:\n") + + fromSpansTrailingPrefix := trailingPrefix + "╰ ╰ " + if i < len(incomingCalls.values)-1 { + fromSpansTrailingPrefix = prefix + "│ ╰ " + } else if !outgoingCalls.skip && (!outgoingCalls.seen || len(outgoingCalls.values) > 0) { + fromSpansTrailingPrefix = prefix + "│ ╰ " + } + formatCallHierarchyItemSpans(f, fromFile, result, incomingCall.FromRanges, prefix+"│ │ ", fromSpansTrailingPrefix) + } + } + } + + // Handle outgoing calls + if outgoingCalls.seen { + result.WriteString(trailingPrefix + "╰ outgoing: ...\n") + } else if !outgoingCalls.skip { + if len(outgoingCalls.values) == 0 { + result.WriteString(trailingPrefix + "╰ outgoing: none\n") + } else { + result.WriteString(prefix + "├ outgoing:\n") + for i, outgoingCall := range outgoingCalls.values { + toFileName := outgoingCall.To.Uri.FileName() + toFile := f.getScriptInfo(toFileName) + result.WriteString(prefix + "│ ╭ to:\n") + formatCallHierarchyItem(t, f, toFile, result, *outgoingCall.To, callHierarchyItemDirectionOutgoing, seen, prefix+"│ │ ") + result.WriteString(prefix + "│ ├ fromSpans:\n") + + fromSpansTrailingPrefix := trailingPrefix + "╰ ╰ " + if i < len(outgoingCalls.values)-1 { + fromSpansTrailingPrefix = prefix + "│ ╰ " + } + formatCallHierarchyItemSpans(f, file, result, outgoingCall.FromRanges, prefix+"│ │ ", fromSpansTrailingPrefix) + } + } + } +} + +func formatCallHierarchyItemSpan( + f *FourslashTest, + file *scriptInfo, + result *strings.Builder, + span lsproto.Range, + prefix string, + closingPrefix string, +) { + startLc := span.Start + endLc := span.End + startPos := f.converters.LineAndCharacterToPosition(file, span.Start) + endPos := f.converters.LineAndCharacterToPosition(file, span.End) + + // Compute line starts for the file + lineStarts := computeLineStarts(file.content) + + // Find the line boundaries - expand to full lines + contextStart := int(startPos) + contextEnd := int(endPos) + + // Expand to start of first line + for contextStart > 0 && file.content[contextStart-1] != '\n' && file.content[contextStart-1] != '\r' { + contextStart-- + } + + // Expand to end of last line + for contextEnd < len(file.content) && file.content[contextEnd] != '\n' && file.content[contextEnd] != '\r' { + contextEnd++ + } + + // Get actual line and character positions for the context + contextStartLine := int(startLc.Line) + contextEndLine := int(endLc.Line) + + // Calculate line number padding + lineNumWidth := len(strconv.Itoa(contextEndLine+1)) + 2 + + result.WriteString(fmt.Sprintf("%s╭ %s:%d:%d-%d:%d\n", prefix, file.fileName, startLc.Line+1, startLc.Character+1, endLc.Line+1, endLc.Character+1)) + + for lineNum := contextStartLine; lineNum <= contextEndLine; lineNum++ { + lineStart := lineStarts[lineNum] + lineEnd := len(file.content) + if lineNum+1 < len(lineStarts) { + lineEnd = lineStarts[lineNum+1] + } + + // Get the line content, trimming trailing newlines + lineContent := file.content[lineStart:lineEnd] + lineContent = strings.TrimRight(lineContent, "\r\n") + + // Format with line number + lineNumStr := fmt.Sprintf("%d:", lineNum+1) + paddedLineNum := strings.Repeat(" ", lineNumWidth-len(lineNumStr)-1) + lineNumStr + if lineContent == "" { + result.WriteString(fmt.Sprintf("%s│ %s\n", prefix, paddedLineNum)) + } else { + result.WriteString(fmt.Sprintf("%s│ %s %s\n", prefix, paddedLineNum, lineContent)) + } + + // Add selection carets if this line contains part of the span + if lineNum >= int(startLc.Line) && lineNum <= int(endLc.Line) { + selStart := 0 + selEnd := len(lineContent) + + if lineNum == int(startLc.Line) { + selStart = int(startLc.Character) + } + if lineNum == int(endLc.Line) { + selEnd = int(endLc.Character) + } + + // Don't show carets for empty selections + isEmpty := startLc.Line == endLc.Line && startLc.Character == endLc.Character + if isEmpty { + // For empty selections, show a single "<" character + padding := strings.Repeat(" ", lineNumWidth+selStart) + result.WriteString(fmt.Sprintf("%s│ %s<\n", prefix, padding)) + } else { + // Calculate selection length (at least 1) + selLength := selEnd - selStart + selLength = max(selLength, 1) // Trim to actual content on the line + if lineNum < int(endLc.Line) { + // For lines before the last, trim to line content length + if selEnd > len(lineContent) { + selEnd = len(lineContent) + selLength = selEnd - selStart + } + } + + padding := strings.Repeat(" ", lineNumWidth+selStart) + carets := strings.Repeat("^", selLength) + result.WriteString(fmt.Sprintf("%s│ %s%s\n", prefix, padding, carets)) + } + } + } + + result.WriteString(closingPrefix + "╰\n") +} + +func computeLineStarts(content string) []int { + lineStarts := []int{0} + for i, ch := range content { + if ch == '\n' { + lineStarts = append(lineStarts, i+1) + } + } + return lineStarts +} + +func formatCallHierarchyItemSpans( + f *FourslashTest, + file *scriptInfo, + result *strings.Builder, + spans []lsproto.Range, + prefix string, + trailingPrefix string, +) { + for i, span := range spans { + closingPrefix := prefix + if i == len(spans)-1 { + closingPrefix = trailingPrefix + } + formatCallHierarchyItemSpan(f, file, result, span, prefix, closingPrefix) + } +} + func (f *FourslashTest) VerifyBaselineDocumentHighlights( t *testing.T, preferences *lsutil.UserPreferences, diff --git a/internal/fourslash/tests/gen/callHierarchyAccessor_test.go b/internal/fourslash/tests/gen/callHierarchyAccessor_test.go new file mode 100644 index 0000000000..eef2979811 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyAccessor_test.go @@ -0,0 +1,29 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyAccessor(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `function foo() { + new C().bar; +} + +class C { + get /**/bar() { + return baz(); + } +} + +function baz() { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyCallExpressionByConstNamedFunctionExpression_test.go b/internal/fourslash/tests/gen/callHierarchyCallExpressionByConstNamedFunctionExpression_test.go new file mode 100644 index 0000000000..1805a5a0b4 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyCallExpressionByConstNamedFunctionExpression_test.go @@ -0,0 +1,29 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyCallExpressionByConstNamedFunctionExpression(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `function foo() { + bar(); +} + +const bar = function () { + baz(); +} + +function baz() { +} + +/**/bar()` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyClassPropertyArrowFunction_test.go b/internal/fourslash/tests/gen/callHierarchyClassPropertyArrowFunction_test.go new file mode 100644 index 0000000000..1ff33260ec --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyClassPropertyArrowFunction_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 TestCallHierarchyClassPropertyArrowFunction(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `class C { + caller = () => { + this.callee(); + } + + /**/callee = () => { + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyClassStaticBlock2_test.go b/internal/fourslash/tests/gen/callHierarchyClassStaticBlock2_test.go new file mode 100644 index 0000000000..b0103cba48 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyClassStaticBlock2_test.go @@ -0,0 +1,38 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyClassStaticBlock2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `class C { + /**/static { + function foo() { + bar(); + } + + function bar() { + baz(); + quxx(); + baz(); + } + + foo(); + } +} + +function baz() { +} + +function quxx() { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyClassStaticBlock_test.go b/internal/fourslash/tests/gen/callHierarchyClassStaticBlock_test.go new file mode 100644 index 0000000000..a1d028da78 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyClassStaticBlock_test.go @@ -0,0 +1,38 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyClassStaticBlock(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `class C { + static { + function foo() { + bar(); + } + + function /**/bar() { + baz(); + quxx(); + baz(); + } + + foo(); + } +} + +function baz() { +} + +function quxx() { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyClass_test.go b/internal/fourslash/tests/gen/callHierarchyClass_test.go new file mode 100644 index 0000000000..59084555e5 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyClass_test.go @@ -0,0 +1,27 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyClass(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `function foo() { + bar(); +} + +function /**/bar() { + new Baz(); +} + +class Baz { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyConstNamedArrowFunction_test.go b/internal/fourslash/tests/gen/callHierarchyConstNamedArrowFunction_test.go new file mode 100644 index 0000000000..8c8f0f89f8 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyConstNamedArrowFunction_test.go @@ -0,0 +1,27 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyConstNamedArrowFunction(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `function foo() { + bar(); +} + +const /**/bar = () => { + baz(); +} + +function baz() { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyConstNamedClassExpression_test.go b/internal/fourslash/tests/gen/callHierarchyConstNamedClassExpression_test.go new file mode 100644 index 0000000000..e23a9b6f68 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyConstNamedClassExpression_test.go @@ -0,0 +1,29 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyConstNamedClassExpression(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `function foo() { + new Bar(); +} + +const /**/Bar = class { + constructor() { + baz(); + } +} + +function baz() { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyConstNamedFunctionExpression_test.go b/internal/fourslash/tests/gen/callHierarchyConstNamedFunctionExpression_test.go new file mode 100644 index 0000000000..2a56777abf --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyConstNamedFunctionExpression_test.go @@ -0,0 +1,27 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyConstNamedFunctionExpression(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `function foo() { + bar(); +} + +const /**/bar = function () { + baz(); +} + +function baz() { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyContainerNameServer_test.go b/internal/fourslash/tests/gen/callHierarchyContainerNameServer_test.go new file mode 100644 index 0000000000..0500b18584 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyContainerNameServer_test.go @@ -0,0 +1,53 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyContainerNameServer(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `function /**/f() {} + +class A { + static sameName() { + f(); + } +} + +class B { + sameName() { + A.sameName(); + } +} + +const Obj = { + get sameName() { + return new B().sameName; + } +}; + +namespace Foo { + function sameName() { + return Obj.sameName; + } + + export class C { + constructor() { + sameName(); + } + } +} + +module Foo.Bar { + const sameName = () => new Foo.C(); +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.MarkTestAsStradaServer() + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyContainerName_test.go b/internal/fourslash/tests/gen/callHierarchyContainerName_test.go new file mode 100644 index 0000000000..fcd08b77c5 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyContainerName_test.go @@ -0,0 +1,52 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyContainerName(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `function /**/f() {} + +class A { + static sameName() { + f(); + } +} + +class B { + sameName() { + A.sameName(); + } +} + +const Obj = { + get sameName() { + return new B().sameName; + } +}; + +namespace Foo { + function sameName() { + return Obj.sameName; + } + + export class C { + constructor() { + sameName(); + } + } +} + +module Foo.Bar { + const sameName = () => new Foo.C(); +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyCrossFile_test.go b/internal/fourslash/tests/gen/callHierarchyCrossFile_test.go new file mode 100644 index 0000000000..1467878f7d --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyCrossFile_test.go @@ -0,0 +1,29 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyCrossFile(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @filename: /a.ts +export function /**/createModelReference() {} +// @filename: /b.ts +import { createModelReference } from "./a"; +function openElementsAtEditor() { + createModelReference(); +} +// @filename: /c.ts +import { createModelReference } from "./a"; +function registerDefaultLanguageCommand() { + createModelReference(); +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyDecorator_test.go b/internal/fourslash/tests/gen/callHierarchyDecorator_test.go new file mode 100644 index 0000000000..f9c4022129 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyDecorator_test.go @@ -0,0 +1,28 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyDecorator(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @experimentalDecorators: true +@bar +class Foo { +} + +function /**/bar() { + baz(); +} + +function baz() { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyExportDefaultClass_test.go b/internal/fourslash/tests/gen/callHierarchyExportDefaultClass_test.go new file mode 100644 index 0000000000..c4c848f82c --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyExportDefaultClass_test.go @@ -0,0 +1,32 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyExportDefaultClass(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @filename: main.ts +import Bar from "./other"; + +function foo() { + new Bar(); +} +// @filename: other.ts +export /**/default class { + constructor() { + baz(); + } +} + +function baz() { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyExportDefaultFunction_test.go b/internal/fourslash/tests/gen/callHierarchyExportDefaultFunction_test.go new file mode 100644 index 0000000000..3e64c7179f --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyExportDefaultFunction_test.go @@ -0,0 +1,30 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyExportDefaultFunction(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @filename: main.ts +import bar from "./other"; + +function foo() { + bar(); +} +// @filename: other.ts +export /**/default function () { + baz(); +} + +function baz() { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyExportEqualsFunction_test.go b/internal/fourslash/tests/gen/callHierarchyExportEqualsFunction_test.go new file mode 100644 index 0000000000..ba00b1d6de --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyExportEqualsFunction_test.go @@ -0,0 +1,30 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyExportEqualsFunction(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @filename: main.ts +import bar = require("./other"); + +function foo() { + bar(); +} +// @filename: other.ts +export = /**/function () { + baz(); +} + +function baz() { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyFile_test.go b/internal/fourslash/tests/gen/callHierarchyFile_test.go new file mode 100644 index 0000000000..b10a814a58 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyFile_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 TestCallHierarchyFile(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `foo(); +function /**/foo() { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity1_test.go b/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity1_test.go new file mode 100644 index 0000000000..f99348b6d1 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity1_test.go @@ -0,0 +1,26 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyFunctionAmbiguity1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @filename: a.d.ts +declare function foo(x?: number): void; +// @filename: b.d.ts +declare function foo(x?: string): void; +declare function foo(x?: boolean): void; +// @filename: main.ts +function bar() { + /**/foo(); +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity2_test.go b/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity2_test.go new file mode 100644 index 0000000000..9af650ce83 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity2_test.go @@ -0,0 +1,26 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyFunctionAmbiguity2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @filename: a.d.ts +declare function /**/foo(x?: number): void; +// @filename: b.d.ts +declare function foo(x?: string): void; +declare function foo(x?: boolean): void; +// @filename: main.ts +function bar() { + foo(); +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity3_test.go b/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity3_test.go new file mode 100644 index 0000000000..667c1e1ed7 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity3_test.go @@ -0,0 +1,26 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyFunctionAmbiguity3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @filename: a.d.ts +declare function foo(x?: number): void; +// @filename: b.d.ts +declare function /**/foo(x?: string): void; +declare function foo(x?: boolean): void; +// @filename: main.ts +function bar() { + foo(); +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity4_test.go b/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity4_test.go new file mode 100644 index 0000000000..b2e2e40d11 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity4_test.go @@ -0,0 +1,26 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyFunctionAmbiguity4(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @filename: a.d.ts +declare function foo(x?: number): void; +// @filename: b.d.ts +declare function foo(x?: string): void; +declare function /**/foo(x?: boolean): void; +// @filename: main.ts +function bar() { + foo(); +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity5_test.go b/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity5_test.go new file mode 100644 index 0000000000..f4fbc075c7 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyFunctionAmbiguity5_test.go @@ -0,0 +1,26 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyFunctionAmbiguity5(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @filename: a.d.ts +declare function foo(x?: number): void; +// @filename: b.d.ts +declare function foo(x?: string): void; +declare function foo(x?: boolean): void; +// @filename: main.ts +function /**/bar() { + foo(); +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyFunction_test.go b/internal/fourslash/tests/gen/callHierarchyFunction_test.go new file mode 100644 index 0000000000..0106d01f3d --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyFunction_test.go @@ -0,0 +1,32 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyFunction(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `function foo() { + bar(); +} + +function /**/bar() { + baz(); + quxx(); + baz(); +} + +function baz() { +} + +function quxx() { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyInterfaceMethod_test.go b/internal/fourslash/tests/gen/callHierarchyInterfaceMethod_test.go new file mode 100644 index 0000000000..51bf532886 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyInterfaceMethod_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 TestCallHierarchyInterfaceMethod(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `interface I { + /**/foo(): void; +} + +const obj: I = { foo() {} }; + +obj.foo();` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyJsxElement_test.go b/internal/fourslash/tests/gen/callHierarchyJsxElement_test.go new file mode 100644 index 0000000000..7d15e7ab35 --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyJsxElement_test.go @@ -0,0 +1,29 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyJsxElement(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @jsx: preserve +// @filename: main.tsx +function foo() { + return ; +} + +function /**/Bar() { + baz(); +} + +function baz() { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/fourslash/tests/gen/callHierarchyTaggedTemplate_test.go b/internal/fourslash/tests/gen/callHierarchyTaggedTemplate_test.go new file mode 100644 index 0000000000..2ff353d83b --- /dev/null +++ b/internal/fourslash/tests/gen/callHierarchyTaggedTemplate_test.go @@ -0,0 +1,27 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCallHierarchyTaggedTemplate(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `function foo() { + bar` + "`" + `a${1}b` + "`" + `; +} + +function /**/bar(array: TemplateStringsArray, ...args: any[]) { + baz(); +} + +function baz() { +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyBaselineCallHierarchy(t) +} diff --git a/internal/ls/callhierarchy.go b/internal/ls/callhierarchy.go new file mode 100644 index 0000000000..766d0eb64f --- /dev/null +++ b/internal/ls/callhierarchy.go @@ -0,0 +1,1043 @@ +package ls + +import ( + "context" + "slices" + "strings" + + "github.com/microsoft/typescript-go/internal/ast" + "github.com/microsoft/typescript-go/internal/astnav" + "github.com/microsoft/typescript-go/internal/checker" + "github.com/microsoft/typescript-go/internal/compiler" + "github.com/microsoft/typescript-go/internal/core" + "github.com/microsoft/typescript-go/internal/debug" + "github.com/microsoft/typescript-go/internal/ls/lsconv" + "github.com/microsoft/typescript-go/internal/lsp/lsproto" + "github.com/microsoft/typescript-go/internal/printer" + "github.com/microsoft/typescript-go/internal/scanner" +) + +type CallHierarchyDeclaration = *ast.Node + +// Indictates whether a node is named function or class expression. +func isNamedExpression(node *ast.Node) bool { + if node == nil { + return false + } + if !ast.IsFunctionExpression(node) && !ast.IsClassExpression(node) { + return false + } + name := node.Name() + return name != nil && ast.IsIdentifier(name) +} + +func isVariableLike(node *ast.Node) bool { + if node == nil { + return false + } + return ast.IsPropertyDeclaration(node) || ast.IsVariableDeclaration(node) +} + +// Indicates whether a node is a function, arrow, or class expression assigned to a constant variable or class property. +func isAssignedExpression(node *ast.Node) bool { + if node == nil { + return false + } + if !(ast.IsFunctionExpression(node) || ast.IsArrowFunction(node) || ast.IsClassExpression(node)) { + return false + } + if node.Name() != nil { + return false + } + parent := node.Parent + if !isVariableLike(parent) { + return false + } + + if parent.Initializer() != node { + return false + } + + name := parent.Name() + if !ast.IsIdentifier(name) { + return false + } + + return (ast.GetCombinedNodeFlags(parent)&ast.NodeFlagsConst) != 0 || ast.IsPropertyDeclaration(parent) +} + +// Indicates whether a node could possibly be a call hierarchy declaration. +// +// See `resolveCallHierarchyDeclaration` for the specific rules. +func isPossibleCallHierarchyDeclaration(node *ast.Node) bool { + if node == nil { + return false + } + return ast.IsSourceFile(node) || + ast.IsModuleDeclaration(node) || + ast.IsFunctionDeclaration(node) || + ast.IsFunctionExpression(node) || + ast.IsClassDeclaration(node) || + ast.IsClassExpression(node) || + ast.IsClassStaticBlockDeclaration(node) || + ast.IsMethodDeclaration(node) || + ast.IsMethodSignatureDeclaration(node) || + ast.IsGetAccessorDeclaration(node) || + ast.IsSetAccessorDeclaration(node) +} + +// Indicates whether a node is a valid a call hierarchy declaration. +// +// See `resolveCallHierarchyDeclaration` for the specific rules. +func isValidCallHierarchyDeclaration(node *ast.Node) bool { + if node == nil { + return false + } + + if ast.IsSourceFile(node) { + return true + } + + if ast.IsModuleDeclaration(node) { + return ast.IsIdentifier(node.Name()) + } + + return ast.IsFunctionDeclaration(node) || + ast.IsClassDeclaration(node) || + ast.IsClassStaticBlockDeclaration(node) || + ast.IsMethodDeclaration(node) || + ast.IsMethodSignatureDeclaration(node) || + ast.IsGetAccessorDeclaration(node) || + ast.IsSetAccessorDeclaration(node) || + isNamedExpression(node) || + isAssignedExpression(node) +} + +// Gets the node that can be used as a reference to a call hierarchy declaration. +func getCallHierarchyDeclarationReferenceNode(node *ast.Node) *ast.Node { + if node == nil { + return nil + } + + if ast.IsSourceFile(node) { + return node + } + + if name := node.Name(); name != nil { + return name + } + + if isAssignedExpression(node) { + return node.Parent.Name() + } + + if modifiers := node.Modifiers(); modifiers != nil { + for _, mod := range modifiers.Nodes { + if mod.Kind == ast.KindDefaultKeyword { + return mod + } + } + } + + debug.Assert(false, "Expected call hierarchy declaration to have a reference node") + return nil +} + +// Gets the symbol for a call hierarchy declaration. +func getSymbolOfCallHierarchyDeclaration(c *checker.Checker, node *ast.Node) *ast.Symbol { + if ast.IsClassStaticBlockDeclaration(node) { + return nil + } + location := getCallHierarchyDeclarationReferenceNode(node) + if location == nil { + return nil + } + return c.GetSymbolAtLocation(location) +} + +// Gets the text and range for the name of a call hierarchy declaration. +func getCallHierarchyItemName(program *compiler.Program, node *ast.Node) (text string, pos int, end int) { + if ast.IsSourceFile(node) { + sourceFile := node.AsSourceFile() + return sourceFile.FileName(), 0, 0 + } + + if (ast.IsFunctionDeclaration(node) || ast.IsClassDeclaration(node)) && node.Name() == nil { + if modifiers := node.Modifiers(); modifiers != nil { + for _, mod := range modifiers.Nodes { + if mod.Kind == ast.KindDefaultKeyword { + sourceFile := ast.GetSourceFileOfNode(node) + start := scanner.SkipTrivia(sourceFile.Text(), mod.Pos()) + return "default", start, mod.End() + } + } + } + } + + if ast.IsClassStaticBlockDeclaration(node) { + sourceFile := ast.GetSourceFileOfNode(node) + pos := scanner.SkipTrivia(sourceFile.Text(), moveRangePastModifiers(node).Pos()) + end := pos + 6 // "static".length + c, done := program.GetTypeCheckerForFile(context.Background(), sourceFile) + defer done() + symbol := c.GetSymbolAtLocation(node.Parent) + prefix := "" + if symbol != nil { + prefix = c.SymbolToString(symbol) + " " + } + return prefix + "static {}", pos, end + } + + var declName *ast.Node + if isAssignedExpression(node) { + declName = node.Parent.Name() + } else { + declName = ast.GetNameOfDeclaration(node) + } + + debug.AssertIsDefined(declName, "Expected call hierarchy item to have a name") + + if ast.IsIdentifier(declName) { + text = declName.Text() + } else if ast.IsStringOrNumericLiteralLike(declName) { + text = declName.Text() + } else if ast.IsComputedPropertyName(declName) { + expr := declName.Expression() + if ast.IsStringOrNumericLiteralLike(expr) { + text = expr.Text() + } + } + + if text == "" { + c, done := program.GetTypeCheckerForFile(context.Background(), ast.GetSourceFileOfNode(node)) + defer done() + symbol := c.GetSymbolAtLocation(declName) + if symbol != nil { + text = c.SymbolToString(symbol) + } + } + + // get the text from printing the node on a single line without comments... + if text == "" { + sourceFile := ast.GetSourceFileOfNode(node) + writer, putWriter := printer.GetSingleLineStringWriter() + defer putWriter() + p := printer.NewPrinter(printer.PrinterOptions{RemoveComments: true}, printer.PrintHandlers{}, nil) + p.Write(node, sourceFile, writer, nil) + text = writer.String() + } + + sourceFile := ast.GetSourceFileOfNode(node) + namePos := scanner.SkipTrivia(sourceFile.Text(), declName.Pos()) + + return text, namePos, declName.End() +} + +func getCallHierarchyItemContainerName(node *ast.Node) string { + if isAssignedExpression(node) { + parent := node.Parent + if ast.IsPropertyDeclaration(parent) && ast.IsClassLike(parent.Parent) { + if ast.IsClassExpression(parent.Parent) { + if assignedName := ast.GetAssignedName(parent.Parent); assignedName != nil { + return assignedName.Text() + } + } else { + if name := parent.Parent.Name(); name != nil { + return name.Text() + } + } + } + if ast.IsModuleBlock(parent.Parent.Parent.Parent) { + modParent := parent.Parent.Parent.Parent.Parent + if ast.IsModuleDeclaration(modParent) { + if name := modParent.Name(); name != nil && ast.IsIdentifier(name) { + return name.Text() + } + } + } + return "" + } + + switch node.Kind { + case ast.KindGetAccessor, ast.KindSetAccessor, ast.KindMethodDeclaration: + if node.Parent.Kind == ast.KindObjectLiteralExpression { + if assignedName := ast.GetAssignedName(node.Parent); assignedName != nil { + return assignedName.Text() + } + } + if name := ast.GetNameOfDeclaration(node.Parent); name != nil { + return name.Text() + } + case ast.KindFunctionDeclaration, ast.KindClassDeclaration, ast.KindModuleDeclaration: + if ast.IsModuleBlock(node.Parent) { + if ast.IsModuleDeclaration(node.Parent.Parent) { + if name := node.Parent.Parent.Name(); name != nil && ast.IsIdentifier(name) { + return name.Text() + } + } + } + } + + return "" +} + +func moveRangePastModifiers(node *ast.Node) core.TextRange { + if modifiers := node.Modifiers(); modifiers != nil && len(modifiers.Nodes) > 0 { + lastMod := modifiers.Nodes[len(modifiers.Nodes)-1] + return core.NewTextRange(lastMod.End(), node.End()) + } + return core.NewTextRange(node.Pos(), node.End()) +} + +// Finds the implementation of a function-like declaration, if one exists. +func findImplementation(c *checker.Checker, node *ast.Node) *ast.Node { + if node == nil { + return nil + } + + if !ast.IsFunctionLikeDeclaration(node) { + return node + } + + if node.Body() != nil { + return node + } + + if ast.IsConstructorDeclaration(node) { + return ast.GetFirstConstructorWithBody(node.Parent) + } + + if ast.IsFunctionDeclaration(node) || ast.IsMethodDeclaration(node) { + symbol := getSymbolOfCallHierarchyDeclaration(c, node) + if symbol != nil && symbol.ValueDeclaration != nil { + if ast.IsFunctionLikeDeclaration(symbol.ValueDeclaration) && symbol.ValueDeclaration.Body() != nil { + return symbol.ValueDeclaration + } + } + return nil + } + + return node +} + +func findAllInitialDeclarations(c *checker.Checker, node *ast.Node) []*ast.Node { + if ast.IsClassStaticBlockDeclaration(node) { + return nil + } + + symbol := getSymbolOfCallHierarchyDeclaration(c, node) + if symbol == nil || symbol.Declarations == nil { + return nil + } + + type declKey struct { + file string + pos int + } + + indices := make([]int, len(symbol.Declarations)) + for i := range indices { + indices[i] = i + } + keys := make([]declKey, len(symbol.Declarations)) + for i, decl := range symbol.Declarations { + keys[i] = declKey{ + file: ast.GetSourceFileOfNode(decl).FileName(), + pos: decl.Pos(), + } + } + + slices.SortFunc(indices, func(a, b int) int { + if keys[a].file != keys[b].file { + return strings.Compare(keys[a].file, keys[b].file) + } + return keys[a].pos - keys[b].pos + }) + + var declarations []*ast.Node + var lastDecl *ast.Node + + for _, i := range indices { + decl := symbol.Declarations[i] + if isValidCallHierarchyDeclaration(decl) { + if lastDecl == nil || lastDecl.Parent != decl.Parent || lastDecl.End() != decl.Pos() { + declarations = append(declarations, decl) + } + lastDecl = decl + } + } + + return declarations +} + +// Find the implementation or the first declaration for a call hierarchy declaration. +func findImplementationOrAllInitialDeclarations(c *checker.Checker, node *ast.Node) any { + if ast.IsClassStaticBlockDeclaration(node) { + return node + } + + if ast.IsFunctionLikeDeclaration(node) { + if impl := findImplementation(c, node); impl != nil { + return impl + } + if decls := findAllInitialDeclarations(c, node); decls != nil { + return decls + } + return node + } + + if decls := findAllInitialDeclarations(c, node); decls != nil { + return decls + } + return node +} + +// Resolves the call hierarchy declaration for a node. +func resolveCallHierarchyDeclaration(program *compiler.Program, location *ast.Node) (result any) { + // A call hierarchy item must refer to either a SourceFile, Module Declaration, Class Static Block, or something intrinsically callable that has a name: + // - Class Declarations + // - Class Expressions (with a name) + // - Function Declarations + // - Function Expressions (with a name or assigned to a const variable) + // - Arrow Functions (assigned to a const variable) + // - Constructors + // - Class `static {}` initializer blocks + // - Methods + // - Accessors + // + // If a call is contained in a non-named callable Node (function expression, arrow function, etc.), then + // its containing `CallHierarchyItem` is a containing function or SourceFile that matches the above list. + + c, done := program.GetTypeChecker(context.Background()) + defer done() + + followingSymbol := false + + for location != nil { + if isValidCallHierarchyDeclaration(location) { + return findImplementationOrAllInitialDeclarations(c, location) + } + + if isPossibleCallHierarchyDeclaration(location) { + ancestor := ast.FindAncestor(location, isValidCallHierarchyDeclaration) + if ancestor != nil { + return findImplementationOrAllInitialDeclarations(c, ancestor) + } + } + + if ast.IsDeclarationName(location) { + if isValidCallHierarchyDeclaration(location.Parent) { + return findImplementationOrAllInitialDeclarations(c, location.Parent) + } + if isPossibleCallHierarchyDeclaration(location.Parent) { + ancestor := ast.FindAncestor(location.Parent, isValidCallHierarchyDeclaration) + if ancestor != nil { + return findImplementationOrAllInitialDeclarations(c, ancestor) + } + } + if isVariableLike(location.Parent) { + initializer := location.Parent.Initializer() + if initializer != nil && isAssignedExpression(initializer) { + return initializer + } + } + return nil + } + + if ast.IsConstructorDeclaration(location) { + if isValidCallHierarchyDeclaration(location.Parent) { + return location.Parent + } + return nil + } + + if location.Kind == ast.KindStaticKeyword && ast.IsClassStaticBlockDeclaration(location.Parent) { + location = location.Parent + continue + } + + // #39453 + if ast.IsVariableDeclaration(location) { + if initializer := location.Initializer(); initializer != nil && isAssignedExpression(initializer) { + return initializer + } + } + + if !followingSymbol { + symbol := c.GetSymbolAtLocation(location) + if symbol != nil { + if (symbol.Flags & ast.SymbolFlagsAlias) != 0 { + symbol = c.GetAliasedSymbol(symbol) + } + if symbol.ValueDeclaration != nil { + followingSymbol = true + location = symbol.ValueDeclaration + continue + } + } + } + + return nil + } + + return nil +} + +// Creates a `CallHierarchyItem` for a call hierarchy declaration. +func (l *LanguageService) createCallHierarchyItem(program *compiler.Program, node *ast.Node) *lsproto.CallHierarchyItem { + sourceFile := ast.GetSourceFileOfNode(node) + nameText, namePos, nameEnd := getCallHierarchyItemName(program, node) + containerName := getCallHierarchyItemContainerName(node) + + kind := getSymbolKindFromNode(node) + + fullStart := scanner.SkipTriviaEx(sourceFile.Text(), node.Pos(), &scanner.SkipTriviaOptions{StopAtComments: true}) + script := l.getScript(sourceFile.FileName()) + span := l.converters.ToLSPRange(script, core.NewTextRange(fullStart, node.End())) + selectionSpan := l.converters.ToLSPRange(script, core.NewTextRange(namePos, nameEnd)) + + item := &lsproto.CallHierarchyItem{ + Name: nameText, + Kind: kind, + Uri: lsconv.FileNameToDocumentURI(sourceFile.FileName()), + Range: span, + SelectionRange: selectionSpan, + } + + if containerName != "" { + item.Detail = &containerName + } + + return item +} + +type callSite struct { + declaration *ast.Node + textRange core.TextRange + sourceFile *ast.Node +} + +func convertEntryToCallSite(entry *ReferenceEntry) *callSite { + if entry.kind != entryKindNode { + return nil + } + + node := entry.node + if !ast.IsCallOrNewExpressionTarget(node, true /*includeElementAccess*/, true /*skipPastOuterExpressions*/) && + !ast.IsTaggedTemplateTag(node, true, true) && + !ast.IsDecoratorTarget(node, true, true) && + !ast.IsJsxOpeningLikeElementTagName(node, true, true) && + !ast.IsRightSideOfPropertyAccess(node) && + !ast.IsArgumentExpressionOfElementAccess(node) { + return nil + } + + sourceFile := ast.GetSourceFileOfNode(node) + ancestor := ast.FindAncestor(node, isValidCallHierarchyDeclaration) + if ancestor == nil { + ancestor = sourceFile.AsNode() + } + + start := scanner.SkipTrivia(sourceFile.Text(), node.Pos()) + return &callSite{ + declaration: ancestor, + textRange: core.NewTextRange(start, node.End()), + sourceFile: sourceFile.AsNode(), + } +} + +func getCallSiteGroupKey(site *callSite) ast.NodeId { + return ast.GetNodeId(site.declaration) +} + +func (l *LanguageService) convertCallSiteGroupToIncomingCall(program *compiler.Program, entries []*callSite) *lsproto.CallHierarchyIncomingCall { + fromRanges := make([]lsproto.Range, len(entries)) + for i, entry := range entries { + script := l.getScript(entry.sourceFile.AsSourceFile().FileName()) + fromRanges[i] = l.converters.ToLSPRange(script, entry.textRange) + } + + slices.SortFunc(fromRanges, func(a, b lsproto.Range) int { + return lsproto.CompareRanges(&a, &b) + }) + + return &lsproto.CallHierarchyIncomingCall{ + From: l.createCallHierarchyItem(program, entries[0].declaration), + FromRanges: fromRanges, + } +} + +// Gets the call sites that call into the provided call hierarchy declaration. +func (l *LanguageService) getIncomingCalls(ctx context.Context, program *compiler.Program, declaration *ast.Node) []*lsproto.CallHierarchyIncomingCall { + // Source files and modules have no incoming calls. + if ast.IsSourceFile(declaration) || ast.IsModuleDeclaration(declaration) || ast.IsClassStaticBlockDeclaration(declaration) { + return nil + } + + location := getCallHierarchyDeclarationReferenceNode(declaration) + if location == nil { + return nil + } + + sourceFiles := program.GetSourceFiles() + options := refOptions{use: referenceUseReferences} + symbolsAndEntries := l.getReferencedSymbolsForNode(ctx, 0, location, program, sourceFiles, options, nil) + + var refEntries []*ReferenceEntry + for _, symbolAndEntry := range symbolsAndEntries { + refEntries = append(refEntries, symbolAndEntry.references...) + } + + var callSites []*callSite + for _, entry := range refEntries { + if site := convertEntryToCallSite(entry); site != nil { + callSites = append(callSites, site) + } + } + + if len(callSites) == 0 { + return nil + } + + grouped := make(map[ast.NodeId][]*callSite) + for _, site := range callSites { + key := getCallSiteGroupKey(site) + grouped[key] = append(grouped[key], site) + } + + var result []*lsproto.CallHierarchyIncomingCall + for _, sites := range grouped { + result = append(result, l.convertCallSiteGroupToIncomingCall(program, sites)) + } + + slices.SortFunc(result, func(a, b *lsproto.CallHierarchyIncomingCall) int { + if uriComp := strings.Compare(string(a.From.Uri), string(b.From.Uri)); uriComp != 0 { + return uriComp + } + if len(a.FromRanges) == 0 || len(b.FromRanges) == 0 { + return 0 + } + return lsproto.CompareRanges(&a.FromRanges[0], &b.FromRanges[0]) + }) + + return result +} + +type callSiteCollector struct { + program *compiler.Program + callSites []*callSite +} + +func (c *callSiteCollector) recordCallSite(node *ast.Node) { + var target *ast.Node + + switch { + case ast.IsTaggedTemplateExpression(node): + target = node.AsTaggedTemplateExpression().Tag + case ast.IsJsxOpeningElement(node): + target = node.TagName() + case ast.IsJsxSelfClosingElement(node): + target = node.TagName() + case ast.IsPropertyAccessExpression(node) || ast.IsElementAccessExpression(node): + target = node + case ast.IsClassStaticBlockDeclaration(node): + target = node + case ast.IsCallExpression(node): + target = node.Expression() + case ast.IsNewExpression(node): + target = node.Expression() + case ast.IsDecorator(node): + target = node.Expression() + } + + if target == nil { + return + } + + declaration := resolveCallHierarchyDeclaration(c.program, target) + if declaration == nil { + return + } + + sourceFile := ast.GetSourceFileOfNode(target) + start := scanner.SkipTrivia(sourceFile.Text(), target.Pos()) + textRange := core.NewTextRange(start, target.End()) + + switch decl := declaration.(type) { + case *ast.Node: + c.callSites = append(c.callSites, &callSite{ + declaration: decl, + textRange: textRange, + sourceFile: sourceFile.AsNode(), + }) + case []*ast.Node: + for _, d := range decl { + c.callSites = append(c.callSites, &callSite{ + declaration: d, + textRange: textRange, + sourceFile: sourceFile.AsNode(), + }) + } + } +} + +func (c *callSiteCollector) collect(node *ast.Node) { + if node == nil { + return + } + + // do not descend into ambient nodes. + if (node.Flags & ast.NodeFlagsAmbient) != 0 { + return + } + + // do not descend into other call site declarations, other than class member names + if isValidCallHierarchyDeclaration(node) { + if ast.IsClassLike(node) { + for _, member := range node.Members() { + if member.Name() != nil && ast.IsComputedPropertyName(member.Name()) { + c.collect(member.Name().Expression()) + } + } + } + return + } + + switch node.Kind { + case ast.KindIdentifier, + ast.KindImportEqualsDeclaration, + ast.KindImportDeclaration, + ast.KindExportDeclaration, + ast.KindInterfaceDeclaration, + ast.KindTypeAliasDeclaration: + // do not descend into nodes that cannot contain callable nodes + return + case ast.KindClassStaticBlockDeclaration: + c.recordCallSite(node) + return + case ast.KindTypeAssertionExpression, ast.KindAsExpression: + // do not descend into the type side of an assertion + c.collect(node.Expression()) + return + case ast.KindVariableDeclaration, ast.KindParameter: + // do not descend into the type of a variable or parameter declaration + c.collect(node.Name()) + c.collect(node.Initializer()) + return + case ast.KindCallExpression: + // do not descend into the type arguments of a call expression + c.recordCallSite(node) + c.collect(node.Expression()) + for _, arg := range node.Arguments() { + c.collect(arg) + } + return + case ast.KindNewExpression: + // do not descend into the type arguments of a new expression + c.recordCallSite(node) + c.collect(node.Expression()) + for _, arg := range node.Arguments() { + c.collect(arg) + } + return + case ast.KindTaggedTemplateExpression: + // do not descend into the type arguments of a tagged template expression + c.recordCallSite(node) + taggedTemplate := node.AsTaggedTemplateExpression() + c.collect(taggedTemplate.Tag) + c.collect(taggedTemplate.Template) + return + case ast.KindJsxOpeningElement, ast.KindJsxSelfClosingElement: + // do not descend into the type arguments of a JsxOpeningLikeElement + c.recordCallSite(node) + c.collect(node.TagName()) + c.collect(node.Attributes()) + return + case ast.KindDecorator: + c.recordCallSite(node) + c.collect(node.Expression()) + return + case ast.KindPropertyAccessExpression, ast.KindElementAccessExpression: + c.recordCallSite(node) + node.ForEachChild(func(child *ast.Node) bool { + c.collect(child) + return false + }) + return + case ast.KindSatisfiesExpression: + // do not descend into the type side of an assertion + c.collect(node.Expression()) + return + } + + if ast.IsPartOfTypeNode(node) { + // do not descend into types + return + } + + node.ForEachChild(func(child *ast.Node) bool { + c.collect(child) + return false + }) +} + +func collectCallSites(program *compiler.Program, c *checker.Checker, node *ast.Node) []*callSite { + collector := &callSiteCollector{ + program: program, + callSites: make([]*callSite, 0), + } + + switch node.Kind { + case ast.KindSourceFile: + for _, stmt := range node.Statements() { + collector.collect(stmt) + } + + case ast.KindModuleDeclaration: + if body := node.Body(); !ast.HasSyntacticModifier(node, ast.ModifierFlagsAmbient) && body != nil && ast.IsModuleBlock(body) { + for _, stmt := range body.Statements() { + collector.collect(stmt) + } + } + + case ast.KindFunctionDeclaration, ast.KindFunctionExpression, ast.KindArrowFunction, + ast.KindMethodDeclaration, ast.KindGetAccessor, ast.KindSetAccessor: + impl := findImplementation(c, node) + if impl != nil { + for _, param := range impl.Parameters() { + collector.collect(param) + } + collector.collect(impl.Body()) + } + + case ast.KindClassDeclaration, ast.KindClassExpression: + if modifiers := node.Modifiers(); modifiers != nil { + for _, mod := range modifiers.Nodes { + collector.collect(mod) + } + } + + heritage := ast.GetClassExtendsHeritageElement(node) + if heritage != nil { + collector.collect(heritage.Expression()) + } + + for _, member := range node.Members() { + if ast.CanHaveModifiers(member) && member.Modifiers() != nil { + for _, mod := range member.Modifiers().Nodes { + collector.collect(mod) + } + } + + if ast.IsPropertyDeclaration(member) { + collector.collect(member.Initializer()) + } else if ast.IsConstructorDeclaration(member) { + if body := member.Body(); body != nil { + for _, param := range member.Parameters() { + collector.collect(param) + } + collector.collect(body) + } + } else if ast.IsClassStaticBlockDeclaration(member) { + collector.collect(member) + } + } + + case ast.KindClassStaticBlockDeclaration: + staticBlock := node.AsClassStaticBlockDeclaration() + collector.collect(staticBlock.Body) + + default: + debug.AssertNever(node) + } + + return collector.callSites +} + +func (l *LanguageService) convertCallSiteGroupToOutgoingCall(program *compiler.Program, entries []*callSite) *lsproto.CallHierarchyOutgoingCall { + fromRanges := make([]lsproto.Range, len(entries)) + for i, entry := range entries { + script := l.getScript(entry.sourceFile.AsSourceFile().FileName()) + fromRanges[i] = l.converters.ToLSPRange(script, entry.textRange) + } + + slices.SortFunc(fromRanges, func(a, b lsproto.Range) int { + return lsproto.CompareRanges(&a, &b) + }) + + return &lsproto.CallHierarchyOutgoingCall{ + To: l.createCallHierarchyItem(program, entries[0].declaration), + FromRanges: fromRanges, + } +} + +// Gets the call sites that call out of the provided call hierarchy declaration. +func (l *LanguageService) getOutgoingCalls(program *compiler.Program, declaration *ast.Node) []*lsproto.CallHierarchyOutgoingCall { + if (declaration.Flags&ast.NodeFlagsAmbient) != 0 || ast.IsMethodSignatureDeclaration(declaration) { + return nil + } + + c, done := program.GetTypeChecker(context.Background()) + defer done() + + callSites := collectCallSites(program, c, declaration) + + if len(callSites) == 0 { + return nil + } + + grouped := make(map[ast.NodeId][]*callSite) + for _, site := range callSites { + key := getCallSiteGroupKey(site) + grouped[key] = append(grouped[key], site) + } + + var result []*lsproto.CallHierarchyOutgoingCall + for _, sites := range grouped { + result = append(result, l.convertCallSiteGroupToOutgoingCall(program, sites)) + } + + slices.SortFunc(result, func(a, b *lsproto.CallHierarchyOutgoingCall) int { + if uriComp := strings.Compare(string(a.To.Uri), string(b.To.Uri)); uriComp != 0 { + return uriComp + } + if len(a.FromRanges) == 0 || len(b.FromRanges) == 0 { + return 0 + } + return lsproto.CompareRanges(&a.FromRanges[0], &b.FromRanges[0]) + }) + + return result +} + +func (l *LanguageService) ProvidePrepareCallHierarchy( + ctx context.Context, + documentURI lsproto.DocumentUri, + position lsproto.Position, +) (lsproto.CallHierarchyPrepareResponse, error) { + program, file := l.getProgramAndFile(documentURI) + node := astnav.GetTouchingPropertyName(file, int(l.converters.LineAndCharacterToPosition(file, position))) + + if node.Kind == ast.KindSourceFile { + return lsproto.CallHierarchyItemsOrNull{}, nil + } + + declaration := resolveCallHierarchyDeclaration(program, node) + if declaration == nil { + return lsproto.CallHierarchyItemsOrNull{}, nil + } + + var items []*lsproto.CallHierarchyItem + switch decl := declaration.(type) { + case *ast.Node: + items = []*lsproto.CallHierarchyItem{l.createCallHierarchyItem(program, decl)} + case []*ast.Node: + items = make([]*lsproto.CallHierarchyItem, len(decl)) + for i, d := range decl { + items[i] = l.createCallHierarchyItem(program, d) + } + } + + if items == nil { + return lsproto.CallHierarchyItemsOrNull{}, nil + } + return lsproto.CallHierarchyItemsOrNull{CallHierarchyItems: &items}, nil +} + +func (l *LanguageService) ProvideCallHierarchyIncomingCalls( + ctx context.Context, + item *lsproto.CallHierarchyItem, +) (lsproto.CallHierarchyIncomingCallsResponse, error) { + program := l.GetProgram() + fileName := item.Uri.FileName() + file := program.GetSourceFile(fileName) + if file == nil { + return lsproto.CallHierarchyIncomingCallsOrNull{}, nil + } + + pos := int(l.converters.LineAndCharacterToPosition(file, item.SelectionRange.Start)) + var node *ast.Node + if pos == 0 { + node = file.AsNode() + } else { + node = astnav.GetTouchingPropertyName(file, pos) + } + + if node == nil { + return lsproto.CallHierarchyIncomingCallsOrNull{}, nil + } + + declaration := resolveCallHierarchyDeclaration(program, node) + if declaration == nil { + return lsproto.CallHierarchyIncomingCallsOrNull{}, nil + } + + var decl *ast.Node + switch d := declaration.(type) { + case *ast.Node: + decl = d + case []*ast.Node: + if len(d) > 0 { + decl = d[0] + } + } + + if decl == nil { + return lsproto.CallHierarchyIncomingCallsOrNull{}, nil + } + + calls := l.getIncomingCalls(ctx, program, decl) + if calls == nil { + return lsproto.CallHierarchyIncomingCallsOrNull{}, nil + } + return lsproto.CallHierarchyIncomingCallsOrNull{CallHierarchyIncomingCalls: &calls}, nil +} + +func (l *LanguageService) ProvideCallHierarchyOutgoingCalls( + ctx context.Context, + item *lsproto.CallHierarchyItem, +) (lsproto.CallHierarchyOutgoingCallsResponse, error) { + program := l.GetProgram() + fileName := item.Uri.FileName() + file := program.GetSourceFile(fileName) + if file == nil { + return lsproto.CallHierarchyOutgoingCallsOrNull{}, nil + } + + pos := int(l.converters.LineAndCharacterToPosition(file, item.SelectionRange.Start)) + var node *ast.Node + if pos == 0 { + node = file.AsNode() + } else { + node = astnav.GetTouchingPropertyName(file, pos) + } + + if node == nil { + return lsproto.CallHierarchyOutgoingCallsOrNull{}, nil + } + + declaration := resolveCallHierarchyDeclaration(program, node) + if declaration == nil { + return lsproto.CallHierarchyOutgoingCallsOrNull{}, nil + } + + var decl *ast.Node + switch d := declaration.(type) { + case *ast.Node: + decl = d + case []*ast.Node: + if len(d) > 0 { + decl = d[0] + } + } + + if decl == nil { + return lsproto.CallHierarchyOutgoingCallsOrNull{}, nil + } + + calls := l.getOutgoingCalls(program, decl) + if calls == nil { + return lsproto.CallHierarchyOutgoingCallsOrNull{}, nil + } + return lsproto.CallHierarchyOutgoingCallsOrNull{CallHierarchyOutgoingCalls: &calls}, nil +} diff --git a/internal/ls/findallreferences.go b/internal/ls/findallreferences.go index 4f84c8b4bf..afe9099743 100644 --- a/internal/ls/findallreferences.go +++ b/internal/ls/findallreferences.go @@ -1421,7 +1421,7 @@ func getReferencedSymbolsForSymbol(originalSymbol *ast.Symbol, node *ast.Node, s // When renaming at an export specifier, rename the export and not the thing being exported. // state.getReferencesAtExportSpecifier(exportSpecifier.Name(), symbol, exportSpecifier.AsExportSpecifier(), state.createSearch(node, originalSymbol, comingFromUnknown /*comingFrom*/, "", nil), true /*addReferencesHere*/, true /*alwaysGetReferences*/) } else if node != nil && node.Kind == ast.KindDefaultKeyword && symbol.Name == ast.InternalSymbolNameDefault && symbol.Parent != nil { - state.addReference(node, symbol, entryKindNone) + state.addReference(node, symbol, entryKindNode) state.searchForImportsOfExport(node, symbol, &ExportInfo{exportingModuleSymbol: symbol.Parent, exportKind: ExportKindDefault}) } else { search := state.createSearch(node, symbol, ImpExpKindUnknown /*comingFrom*/, "", state.populateSearchSymbolSet(symbol, node, options.use == referenceUseRename, options.useAliasesForRename, options.implementations)) @@ -1573,33 +1573,12 @@ func getReferenceEntriesForShorthandPropertyAssignment(node *ast.Node, checker * } } -func climbPastPropertyAccess(node *ast.Node) *ast.Node { - if ast.IsRightSideOfPropertyAccess(node) { - return node.Parent - } - return node -} - -func isNewExpressionTarget(node *ast.Node) bool { - if node.Parent == nil { - return false - } - return node.Parent.Kind == ast.KindNewExpression && node.Parent.Expression() == node -} - -func isCallExpressionTarget(node *ast.Node) bool { - if node.Parent == nil { - return false - } - return node.Parent.Kind == ast.KindCallExpression && node.Parent.Expression() == node -} - func isMethodOrAccessor(node *ast.Node) bool { return node.Kind == ast.KindMethodDeclaration || node.Kind == ast.KindGetAccessor || node.Kind == ast.KindSetAccessor } func tryGetClassByExtendingIdentifier(node *ast.Node) *ast.ClassLikeDeclaration { - return ast.TryGetClassExtendingExpressionWithTypeArguments(climbPastPropertyAccess(node).Parent) + return ast.TryGetClassExtendingExpressionWithTypeArguments(ast.ClimbPastPropertyAccess(node).Parent) } func getClassConstructorSymbol(classSymbol *ast.Symbol) *ast.Symbol { @@ -1632,7 +1611,7 @@ func findOwnConstructorReferences(classSymbol *ast.Symbol, sourceFile *ast.Sourc body := decl.Body() if body != nil { forEachDescendantOfKind(body, ast.KindThisKeyword, func(thisKeyword *ast.Node) { - if isNewExpressionTarget(thisKeyword) { + if ast.IsNewExpressionTarget(thisKeyword, false, false) { addNode(thisKeyword) } }) @@ -1653,7 +1632,7 @@ func findSuperConstructorAccesses(classDeclaration *ast.ClassLikeDeclaration, ad body := decl.Body() if body != nil { forEachDescendantOfKind(body, ast.KindSuperKeyword, func(node *ast.Node) { - if isCallExpressionTarget(node) { + if ast.IsCallExpressionTarget(node, false, false) { addNode(node) } }) @@ -1853,8 +1832,8 @@ func (state *refState) getReferencesAtLocation(sourceFile *ast.SourceFile, posit } func (state *refState) addConstructorReferences(referenceLocation *ast.Node, symbol *ast.Symbol, search *refSearch, addReferencesHere bool) { - if isNewExpressionTarget(referenceLocation) && addReferencesHere { - state.addReference(referenceLocation, symbol, entryKindNone) + if ast.IsNewExpressionTarget(referenceLocation, false, false) && addReferencesHere { + state.addReference(referenceLocation, symbol, entryKindNode) } pusher := func() func(*ast.Node, entryKind) { @@ -1865,13 +1844,13 @@ func (state *refState) addConstructorReferences(referenceLocation *ast.Node, sym // This is the class declaration containing the constructor. sourceFile := ast.GetSourceFileOfNode(referenceLocation) findOwnConstructorReferences(search.symbol, sourceFile, func(n *ast.Node) { - pusher()(n, entryKindNone) + pusher()(n, entryKindNode) }) } else { // If this class appears in `extends C`, then the extending class' "super" calls are references. if classExtending := tryGetClassByExtendingIdentifier(referenceLocation); classExtending != nil { findSuperConstructorAccesses(classExtending, func(n *ast.Node) { - pusher()(n, entryKindNone) + pusher()(n, entryKindNode) }) state.findInheritedConstructorReferences(classExtending) } @@ -1880,7 +1859,7 @@ func (state *refState) addConstructorReferences(referenceLocation *ast.Node, sym func (state *refState) addClassStaticThisReferences(referenceLocation *ast.Node, symbol *ast.Symbol, search *refSearch, addReferencesHere bool) { if addReferencesHere { - state.addReference(referenceLocation, symbol, entryKindNone) + state.addReference(referenceLocation, symbol, entryKindNode) } classLike := referenceLocation.Parent @@ -1902,7 +1881,7 @@ func (state *refState) addClassStaticThisReferences(referenceLocation *ast.Node, var cb func(*ast.Node) cb = func(node *ast.Node) { if node.Kind == ast.KindThisKeyword { - addRef(node, entryKindNone) + addRef(node, entryKindNode) } else if !ast.IsFunctionLike(node) && !ast.IsClassLike(node) { node.ForEachChild(func(child *ast.Node) bool { cb(child) @@ -2017,7 +1996,7 @@ func (state *refState) getReferenceForShorthandProperty(referenceSymbol *ast.Sym // the position in short-hand property assignment excluding property accessing. However, if we do findAllReference at the // position of property accessing, the referenceEntry of such position will be handled in the first case. if name != nil && search.includes(shorthandValueSymbol) { - state.addReference(name, shorthandValueSymbol, entryKindNone) + state.addReference(name, shorthandValueSymbol, entryKindNode) } } @@ -2163,7 +2142,7 @@ func (state *refState) forEachRelatedSymbol( } if res := fromRoot(symbol); res != nil { - return res, entryKindNone + return res, entryKindNode } if symbol.ValueDeclaration != nil && ast.IsParameterPropertyDeclaration(symbol.ValueDeclaration, symbol.ValueDeclaration.Parent) { @@ -2176,7 +2155,7 @@ func (state *refState) forEachRelatedSymbol( if !(paramProp1.Flags&ast.SymbolFlagsFunctionScopedVariable != 0 && paramProp2.Flags&ast.SymbolFlagsProperty != 0) { panic("Expected a parameter and a property") } - return fromRoot(core.IfElse(symbol.Flags&ast.SymbolFlagsFunctionScopedVariable != 0, paramProp2, paramProp1)), entryKindNone + return fromRoot(core.IfElse(symbol.Flags&ast.SymbolFlagsFunctionScopedVariable != 0, paramProp2, paramProp1)), entryKindNode } if exportSpecifier := ast.GetDeclarationOfKind(symbol, ast.KindExportSpecifier); exportSpecifier != nil && (!isForRenamePopulateSearchSymbolSet || exportSpecifier.PropertyName() == nil) { diff --git a/internal/ls/symbols.go b/internal/ls/symbols.go index b45695e703..5ca7d20d5c 100644 --- a/internal/ls/symbols.go +++ b/internal/ls/symbols.go @@ -350,35 +350,53 @@ func compareDeclarationInfos(d1, d2 DeclarationInfo) int { return d1.declaration.Pos() - d2.declaration.Pos() } +// getSymbolKindFromNode converts an AST node to an LSP SymbolKind. +// Combines getNodeKind with VS Code's fromProtocolScriptElementKind. func getSymbolKindFromNode(node *ast.Node) lsproto.SymbolKind { switch node.Kind { + case ast.KindSourceFile: + if ast.IsExternalModule(node.AsSourceFile()) { + return lsproto.SymbolKindModule + } + return lsproto.SymbolKindFile case ast.KindModuleDeclaration: - return lsproto.SymbolKindNamespace - case ast.KindClassDeclaration, ast.KindClassExpression, ast.KindTypeAliasDeclaration: + return lsproto.SymbolKindModule + case ast.KindClassDeclaration, ast.KindClassExpression: + return lsproto.SymbolKindClass + case ast.KindInterfaceDeclaration: + return lsproto.SymbolKindInterface + case ast.KindTypeAliasDeclaration: return lsproto.SymbolKindClass + case ast.KindEnumDeclaration: + return lsproto.SymbolKindEnum + case ast.KindVariableDeclaration: + return lsproto.SymbolKindVariable + case ast.KindArrowFunction, ast.KindFunctionDeclaration, ast.KindFunctionExpression: + return lsproto.SymbolKindFunction + case ast.KindGetAccessor, ast.KindSetAccessor: + return lsproto.SymbolKindProperty case ast.KindMethodDeclaration, ast.KindMethodSignature: return lsproto.SymbolKindMethod - case ast.KindPropertyDeclaration, ast.KindPropertySignature, ast.KindGetAccessor, ast.KindSetAccessor: + case ast.KindPropertyDeclaration, ast.KindPropertySignature: return lsproto.SymbolKindProperty - case ast.KindConstructor, ast.KindConstructSignature: + case ast.KindIndexSignature, ast.KindCallSignature: + return lsproto.SymbolKindMethod + case ast.KindConstructSignature: + return lsproto.SymbolKindConstructor + case ast.KindConstructor, ast.KindClassStaticBlockDeclaration: return lsproto.SymbolKindConstructor - case ast.KindEnumDeclaration: - return lsproto.SymbolKindEnum - case ast.KindInterfaceDeclaration: - return lsproto.SymbolKindInterface - case ast.KindFunctionDeclaration, ast.KindFunctionExpression: - return lsproto.SymbolKindFunction - case ast.KindEnumMember: - return lsproto.SymbolKindEnumMember case ast.KindTypeParameter: return lsproto.SymbolKindTypeParameter + case ast.KindEnumMember: + return lsproto.SymbolKindEnumMember case ast.KindParameter: if ast.HasSyntacticModifier(node, ast.ModifierFlagsParameterPropertyModifier) { return lsproto.SymbolKindProperty } return lsproto.SymbolKindVariable case ast.KindBinaryExpression: - switch ast.GetAssignmentDeclarationKind(node.AsBinaryExpression()) { + kind := ast.GetAssignmentDeclarationKind(node.AsBinaryExpression()) + switch kind { case ast.JSDeclarationKindThisProperty, ast.JSDeclarationKindProperty: return lsproto.SymbolKindProperty } diff --git a/internal/lsp/server.go b/internal/lsp/server.go index a443458b46..8969e96ad3 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -517,10 +517,14 @@ var handlers = sync.OnceValue(func() handlerMap { registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentSelectionRangeInfo, (*Server).handleSelectionRange) registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentInlayHintInfo, (*Server).handleInlayHint) registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentCodeActionInfo, (*Server).handleCodeAction) + registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentPrepareCallHierarchyInfo, (*Server).handlePrepareCallHierarchy) registerMultiProjectReferenceRequestHandler(handlers, lsproto.TextDocumentReferencesInfo, (*Server).handleReferences, combineReferences) registerMultiProjectReferenceRequestHandler(handlers, lsproto.TextDocumentRenameInfo, (*Server).handleRename, combineRenameResponse) + registerRequestHandler(handlers, lsproto.CallHierarchyIncomingCallsInfo, (*Server).handleCallHierarchyIncomingCalls) + registerRequestHandler(handlers, lsproto.CallHierarchyOutgoingCallsInfo, (*Server).handleCallHierarchyOutgoingCalls) + registerRequestHandler(handlers, lsproto.WorkspaceSymbolInfo, (*Server).handleWorkspaceSymbol) registerRequestHandler(handlers, lsproto.CompletionItemResolveInfo, (*Server).handleCompletionItemResolve) @@ -952,6 +956,9 @@ func (s *Server) handleInitialize(ctx context.Context, params *lsproto.Initializ }, }, }, + CallHierarchyProvider: &lsproto.BooleanOrCallHierarchyOptionsOrCallHierarchyRegistrationOptions{ + Boolean: ptrTo(true), + }, }, } @@ -1285,6 +1292,38 @@ func (s *Server) handleInlayHint( return languageService.ProvideInlayHint(ctx, params) } +func (s *Server) handlePrepareCallHierarchy( + ctx context.Context, + languageService *ls.LanguageService, + params *lsproto.CallHierarchyPrepareParams, +) (lsproto.CallHierarchyPrepareResponse, error) { + return languageService.ProvidePrepareCallHierarchy(ctx, params.TextDocument.Uri, params.Position) +} + +func (s *Server) handleCallHierarchyIncomingCalls( + ctx context.Context, + params *lsproto.CallHierarchyIncomingCallsParams, + _ *lsproto.RequestMessage, +) (lsproto.CallHierarchyIncomingCallsResponse, error) { + languageService, err := s.session.GetLanguageService(ctx, params.Item.Uri) + if err != nil { + return lsproto.CallHierarchyIncomingCallsOrNull{}, err + } + return languageService.ProvideCallHierarchyIncomingCalls(ctx, params.Item) +} + +func (s *Server) handleCallHierarchyOutgoingCalls( + ctx context.Context, + params *lsproto.CallHierarchyOutgoingCallsParams, + _ *lsproto.RequestMessage, +) (lsproto.CallHierarchyOutgoingCallsResponse, error) { + languageService, err := s.session.GetLanguageService(ctx, params.Item.Uri) + if err != nil { + return lsproto.CallHierarchyOutgoingCallsOrNull{}, err + } + return languageService.ProvideCallHierarchyOutgoingCalls(ctx, params.Item) +} + func (s *Server) Log(msg ...any) { fmt.Fprintln(s.stderr, msg...) } diff --git a/internal/testutil/baseline/baseline.go b/internal/testutil/baseline/baseline.go index 1d2afd939b..ff6cf23c4b 100644 --- a/internal/testutil/baseline/baseline.go +++ b/internal/testutil/baseline/baseline.go @@ -126,6 +126,11 @@ func getBaselineDiff(t *testing.T, actual string, expected string, fileName stri } s := DiffText("old."+fileName, "new."+fileName, expected, actual) + // If the diff is empty (just headers, no hunks), return NoContent + if !strings.Contains(s, "@@") { + return NoContent + } + // Remove line numbers from unified diff headers; this avoids adding/deleting // lines in our baselines from causing knock-on header changes later in the diff. diff --git a/testdata/baselines/reference/fourslash/findAllReferences/findAllReferencesOfConstructor.baseline.jsonc b/testdata/baselines/reference/fourslash/findAllReferences/findAllReferencesOfConstructor.baseline.jsonc index 90ec6e075a..4e2671027f 100644 --- a/testdata/baselines/reference/fourslash/findAllReferences/findAllReferencesOfConstructor.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/findAllReferences/findAllReferencesOfConstructor.baseline.jsonc @@ -29,7 +29,7 @@ // === /d.ts === // import * as a from "./a"; -// new a.C(); +// new a.[|C|](); // class d extends a.C { constructor() { [|super|](); } @@ -65,7 +65,7 @@ // === /d.ts === // import * as a from "./a"; -// new a.C(); +// new a.[|C|](); // class d extends a.C { constructor() { [|super|](); } @@ -101,5 +101,5 @@ // === /d.ts === // import * as a from "./a"; -// new a.C(); +// new a.[|C|](); // class d extends a.C { constructor() { [|super|](); } \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyAccessor.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyAccessor.callHierarchy.txt new file mode 100644 index 0000000000..68b3d05e3f --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyAccessor.callHierarchy.txt @@ -0,0 +1,67 @@ +// === Call Hierarchy === +╭ name: bar +├ kind: property +├ containerName: C +├ file: /callHierarchyAccessor.ts +├ span: +│ ╭ /callHierarchyAccessor.ts:6:5-8:6 +│ │ 6: get bar() { +│ │ ^^^^^^^^^^^ +│ │ 7: return baz(); +│ │ ^^^^^^^^^^^^^^^^^^^^^ +│ │ 8: } +│ │ ^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyAccessor.ts:6:9-6:12 +│ │ 6: get bar() { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /callHierarchyAccessor.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyAccessor.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: new C().bar; +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyAccessor.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyAccessor.ts:2:13-2:16 +│ │ │ 2: new C().bar; +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /callHierarchyAccessor.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyAccessor.ts:11:1-12:2 +│ │ │ │ 11: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 12: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyAccessor.ts:11:10-11:13 +│ │ │ │ 11: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyAccessor.ts:7:16-7:19 +│ │ │ 7: return baz(); +│ │ │ ^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyCallExpressionByConstNamedFunctionExpression.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyCallExpressionByConstNamedFunctionExpression.callHierarchy.txt new file mode 100644 index 0000000000..bfa14daf2e --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyCallExpressionByConstNamedFunctionExpression.callHierarchy.txt @@ -0,0 +1,108 @@ +// === Call Hierarchy === +╭ name: bar +├ kind: function +├ file: /callHierarchyCallExpressionByConstNamedFunctionExpression.ts +├ span: +│ ╭ /callHierarchyCallExpressionByConstNamedFunctionExpression.ts:5:13-7:2 +│ │ 5: const bar = function () { +│ │ ^^^^^^^^^^^^^ +│ │ 6: baz(); +│ │ ^^^^^^^^^^ +│ │ 7: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyCallExpressionByConstNamedFunctionExpression.ts:5:7-5:10 +│ │ 5: const bar = function () { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /callHierarchyCallExpressionByConstNamedFunctionExpression.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyCallExpressionByConstNamedFunctionExpression.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: bar(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyCallExpressionByConstNamedFunctionExpression.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyCallExpressionByConstNamedFunctionExpression.ts:2:5-2:8 +│ │ │ 2: bar(); +│ │ │ ^^^ +│ ╰ ╰ +│ ╭ from: +│ │ ╭ name: /callHierarchyCallExpressionByConstNamedFunctionExpression.ts +│ │ ├ kind: file +│ │ ├ file: /callHierarchyCallExpressionByConstNamedFunctionExpression.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyCallExpressionByConstNamedFunctionExpression.ts:1:1-12:6 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: bar(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ │ 4: +│ │ │ │ ^ +│ │ │ │ 5: const bar = function () { +│ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ 6: baz(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 7: } +│ │ │ │ ^ +│ │ │ │ 8: +│ │ │ │ ^ +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 10: } +│ │ │ │ ^ +│ │ │ │ 11: +│ │ │ │ ^ +│ │ │ │ 12: bar() +│ │ │ │ ^^^^^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyCallExpressionByConstNamedFunctionExpression.ts:1:1-1:1 +│ │ │ │ 1: function foo() { +│ │ │ │ < +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyCallExpressionByConstNamedFunctionExpression.ts:12:1-12:4 +│ │ │ 12: bar() +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /callHierarchyCallExpressionByConstNamedFunctionExpression.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyCallExpressionByConstNamedFunctionExpression.ts:9:1-10:2 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 10: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyCallExpressionByConstNamedFunctionExpression.ts:9:10-9:13 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyCallExpressionByConstNamedFunctionExpression.ts:6:5-6:8 +│ │ │ 6: baz(); +│ │ │ ^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyClass.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyClass.callHierarchy.txt new file mode 100644 index 0000000000..801b8d4041 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyClass.callHierarchy.txt @@ -0,0 +1,66 @@ +// === Call Hierarchy === +╭ name: bar +├ kind: function +├ file: /callHierarchyClass.ts +├ span: +│ ╭ /callHierarchyClass.ts:5:1-7:2 +│ │ 5: function bar() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 6: new Baz(); +│ │ ^^^^^^^^^^^^^^ +│ │ 7: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyClass.ts:5:10-5:13 +│ │ 5: function bar() { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /callHierarchyClass.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyClass.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: bar(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyClass.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyClass.ts:2:5-2:8 +│ │ │ 2: bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: Baz +│ │ ├ kind: class +│ │ ├ file: /callHierarchyClass.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyClass.ts:9:1-10:2 +│ │ │ │ 9: class Baz { +│ │ │ │ ^^^^^^^^^^^ +│ │ │ │ 10: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyClass.ts:9:7-9:10 +│ │ │ │ 9: class Baz { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyClass.ts:6:9-6:12 +│ │ │ 6: new Baz(); +│ │ │ ^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyClassPropertyArrowFunction.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyClassPropertyArrowFunction.callHierarchy.txt new file mode 100644 index 0000000000..6a78d564e4 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyClassPropertyArrowFunction.callHierarchy.txt @@ -0,0 +1,44 @@ +// === Call Hierarchy === +╭ name: callee +├ kind: function +├ containerName: C +├ file: /callHierarchyClassPropertyArrowFunction.ts +├ span: +│ ╭ /callHierarchyClassPropertyArrowFunction.ts:6:14-7:6 +│ │ 6: callee = () => { +│ │ ^^^^^^^ +│ │ 7: } +│ │ ^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyClassPropertyArrowFunction.ts:6:5-6:11 +│ │ 6: callee = () => { +│ │ ^^^^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: caller +│ │ ├ kind: function +│ │ ├ containerName: C +│ │ ├ file: /callHierarchyClassPropertyArrowFunction.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyClassPropertyArrowFunction.ts:2:14-4:6 +│ │ │ │ 2: caller = () => { +│ │ │ │ ^^^^^^^ +│ │ │ │ 3: this.callee(); +│ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ 4: } +│ │ │ │ ^^^^^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyClassPropertyArrowFunction.ts:2:5-2:11 +│ │ │ │ 2: caller = () => { +│ │ │ │ ^^^^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyClassPropertyArrowFunction.ts:3:14-3:20 +│ │ │ 3: this.callee(); +│ │ │ ^^^^^^ +│ ╰ ╰ +╰ outgoing: none \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyClassStaticBlock.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyClassStaticBlock.callHierarchy.txt new file mode 100644 index 0000000000..cef1e4637d --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyClassStaticBlock.callHierarchy.txt @@ -0,0 +1,140 @@ +// === Call Hierarchy === +╭ name: bar +├ kind: function +├ file: /callHierarchyClassStaticBlock.ts +├ span: +│ ╭ /callHierarchyClassStaticBlock.ts:7:9-11:10 +│ │ 7: function bar() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 8: baz(); +│ │ ^^^^^^^^^^^^^^^^^^ +│ │ 9: quxx(); +│ │ ^^^^^^^^^^^^^^^^^^^ +│ │ 10: baz(); +│ │ ^^^^^^^^^^^^^^^^^^ +│ │ 11: } +│ │ ^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyClassStaticBlock.ts:7:18-7:21 +│ │ 7: function bar() { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /callHierarchyClassStaticBlock.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyClassStaticBlock.ts:3:9-5:10 +│ │ │ │ 3: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 4: bar(); +│ │ │ │ ^^^^^^^^^^^^^^^^^^ +│ │ │ │ 5: } +│ │ │ │ ^^^^^^^^^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyClassStaticBlock.ts:3:18-3:21 +│ │ │ │ 3: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ├ incoming: +│ │ │ ╭ from: +│ │ │ │ ╭ name: static {} +│ │ │ │ ├ kind: constructor +│ │ │ │ ├ file: /callHierarchyClassStaticBlock.ts +│ │ │ │ ├ span: +│ │ │ │ │ ╭ /callHierarchyClassStaticBlock.ts:2:5-14:6 +│ │ │ │ │ │ 2: static { +│ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ │ │ 3: function foo() { +│ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ 4: bar(); +│ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ 5: } +│ │ │ │ │ │ ^^^^^^^^^ +│ │ │ │ │ │ 6: +│ │ │ │ │ │ ^ +│ │ │ │ │ │ 7: function bar() { +│ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ 8: baz(); +│ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ 9: quxx(); +│ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ 10: baz(); +│ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ 11: } +│ │ │ │ │ │ ^^^^^^^^^ +│ │ │ │ │ │ 12: +│ │ │ │ │ │ ^ +│ │ │ │ │ │ 13: foo(); +│ │ │ │ │ │ ^^^^^^^^^^^^^^ +│ │ │ │ │ │ 14: } +│ │ │ │ │ │ ^^^^^ +│ │ │ │ │ ╰ +│ │ │ │ ├ selectionSpan: +│ │ │ │ │ ╭ /callHierarchyClassStaticBlock.ts:2:5-2:11 +│ │ │ │ │ │ 2: static { +│ │ │ │ │ │ ^^^^^^ +│ │ │ │ │ ╰ +│ │ │ │ ╰ incoming: none +│ │ │ ├ fromSpans: +│ │ │ │ ╭ /callHierarchyClassStaticBlock.ts:13:9-13:12 +│ │ │ │ │ 13: foo(); +│ │ │ │ │ ^^^ +│ │ ╰ ╰ ╰ +│ ├ fromSpans: +│ │ ╭ /callHierarchyClassStaticBlock.ts:4:13-4:16 +│ │ │ 4: bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /callHierarchyClassStaticBlock.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyClassStaticBlock.ts:17:1-18:2 +│ │ │ │ 17: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 18: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyClassStaticBlock.ts:17:10-17:13 +│ │ │ │ 17: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyClassStaticBlock.ts:8:13-8:16 +│ │ │ 8: baz(); +│ │ │ ^^^ +│ │ ╰ +│ │ ╭ /callHierarchyClassStaticBlock.ts:10:13-10:16 +│ │ │ 10: baz(); +│ │ │ ^^^ +│ ╰ ╰ +│ ╭ to: +│ │ ╭ name: quxx +│ │ ├ kind: function +│ │ ├ file: /callHierarchyClassStaticBlock.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyClassStaticBlock.ts:20:1-21:2 +│ │ │ │ 20: function quxx() { +│ │ │ │ ^^^^^^^^^^^^^^^^^ +│ │ │ │ 21: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyClassStaticBlock.ts:20:10-20:14 +│ │ │ │ 20: function quxx() { +│ │ │ │ ^^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyClassStaticBlock.ts:9:13-9:17 +│ │ │ 9: quxx(); +│ │ │ ^^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyClassStaticBlock2.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyClassStaticBlock2.callHierarchy.txt new file mode 100644 index 0000000000..dd4bfa270c --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyClassStaticBlock2.callHierarchy.txt @@ -0,0 +1,140 @@ +// === Call Hierarchy === +╭ name: static {} +├ kind: constructor +├ file: /callHierarchyClassStaticBlock2.ts +├ span: +│ ╭ /callHierarchyClassStaticBlock2.ts:2:5-14:6 +│ │ 2: static { +│ │ ^^^^^^^^ +│ │ 3: function foo() { +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ 4: bar(); +│ │ ^^^^^^^^^^^^^^^^^^ +│ │ 5: } +│ │ ^^^^^^^^^ +│ │ 6: +│ │ ^ +│ │ 7: function bar() { +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ 8: baz(); +│ │ ^^^^^^^^^^^^^^^^^^ +│ │ 9: quxx(); +│ │ ^^^^^^^^^^^^^^^^^^^ +│ │ 10: baz(); +│ │ ^^^^^^^^^^^^^^^^^^ +│ │ 11: } +│ │ ^^^^^^^^^ +│ │ 12: +│ │ ^ +│ │ 13: foo(); +│ │ ^^^^^^^^^^^^^^ +│ │ 14: } +│ │ ^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyClassStaticBlock2.ts:2:5-2:11 +│ │ 2: static { +│ │ ^^^^^^ +│ ╰ +├ incoming: none +├ outgoing: +│ ╭ to: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /callHierarchyClassStaticBlock2.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyClassStaticBlock2.ts:3:9-5:10 +│ │ │ │ 3: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 4: bar(); +│ │ │ │ ^^^^^^^^^^^^^^^^^^ +│ │ │ │ 5: } +│ │ │ │ ^^^^^^^^^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyClassStaticBlock2.ts:3:18-3:21 +│ │ │ │ 3: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ├ outgoing: +│ │ │ ╭ to: +│ │ │ │ ╭ name: bar +│ │ │ │ ├ kind: function +│ │ │ │ ├ file: /callHierarchyClassStaticBlock2.ts +│ │ │ │ ├ span: +│ │ │ │ │ ╭ /callHierarchyClassStaticBlock2.ts:7:9-11:10 +│ │ │ │ │ │ 7: function bar() { +│ │ │ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ 8: baz(); +│ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ 9: quxx(); +│ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ 10: baz(); +│ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ 11: } +│ │ │ │ │ │ ^^^^^^^^^ +│ │ │ │ │ ╰ +│ │ │ │ ├ selectionSpan: +│ │ │ │ │ ╭ /callHierarchyClassStaticBlock2.ts:7:18-7:21 +│ │ │ │ │ │ 7: function bar() { +│ │ │ │ │ │ ^^^ +│ │ │ │ │ ╰ +│ │ │ │ ├ outgoing: +│ │ │ │ │ ╭ to: +│ │ │ │ │ │ ╭ name: baz +│ │ │ │ │ │ ├ kind: function +│ │ │ │ │ │ ├ file: /callHierarchyClassStaticBlock2.ts +│ │ │ │ │ │ ├ span: +│ │ │ │ │ │ │ ╭ /callHierarchyClassStaticBlock2.ts:17:1-18:2 +│ │ │ │ │ │ │ │ 17: function baz() { +│ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ 18: } +│ │ │ │ │ │ │ │ ^ +│ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ ├ selectionSpan: +│ │ │ │ │ │ │ ╭ /callHierarchyClassStaticBlock2.ts:17:10-17:13 +│ │ │ │ │ │ │ │ 17: function baz() { +│ │ │ │ │ │ │ │ ^^^ +│ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ ╰ outgoing: none +│ │ │ │ │ ├ fromSpans: +│ │ │ │ │ │ ╭ /callHierarchyClassStaticBlock2.ts:8:13-8:16 +│ │ │ │ │ │ │ 8: baz(); +│ │ │ │ │ │ │ ^^^ +│ │ │ │ │ │ ╰ +│ │ │ │ │ │ ╭ /callHierarchyClassStaticBlock2.ts:10:13-10:16 +│ │ │ │ │ │ │ 10: baz(); +│ │ │ │ │ │ │ ^^^ +│ │ │ │ │ ╰ ╰ +│ │ │ │ │ ╭ to: +│ │ │ │ │ │ ╭ name: quxx +│ │ │ │ │ │ ├ kind: function +│ │ │ │ │ │ ├ file: /callHierarchyClassStaticBlock2.ts +│ │ │ │ │ │ ├ span: +│ │ │ │ │ │ │ ╭ /callHierarchyClassStaticBlock2.ts:20:1-21:2 +│ │ │ │ │ │ │ │ 20: function quxx() { +│ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ 21: } +│ │ │ │ │ │ │ │ ^ +│ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ ├ selectionSpan: +│ │ │ │ │ │ │ ╭ /callHierarchyClassStaticBlock2.ts:20:10-20:14 +│ │ │ │ │ │ │ │ 20: function quxx() { +│ │ │ │ │ │ │ │ ^^^^ +│ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ ╰ outgoing: none +│ │ │ │ │ ├ fromSpans: +│ │ │ │ │ │ ╭ /callHierarchyClassStaticBlock2.ts:9:13-9:17 +│ │ │ │ │ │ │ 9: quxx(); +│ │ │ │ │ │ │ ^^^^ +│ │ │ │ ╰ ╰ ╰ +│ │ │ ├ fromSpans: +│ │ │ │ ╭ /callHierarchyClassStaticBlock2.ts:4:13-4:16 +│ │ │ │ │ 4: bar(); +│ │ │ │ │ ^^^ +│ │ ╰ ╰ ╰ +│ ├ fromSpans: +│ │ ╭ /callHierarchyClassStaticBlock2.ts:13:9-13:12 +│ │ │ 13: foo(); +│ │ │ ^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyConstNamedArrowFunction.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyConstNamedArrowFunction.callHierarchy.txt new file mode 100644 index 0000000000..9d7eef6e05 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyConstNamedArrowFunction.callHierarchy.txt @@ -0,0 +1,66 @@ +// === Call Hierarchy === +╭ name: bar +├ kind: function +├ file: /callHierarchyConstNamedArrowFunction.ts +├ span: +│ ╭ /callHierarchyConstNamedArrowFunction.ts:5:13-7:2 +│ │ 5: const bar = () => { +│ │ ^^^^^^^ +│ │ 6: baz(); +│ │ ^^^^^^^^^^ +│ │ 7: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyConstNamedArrowFunction.ts:5:7-5:10 +│ │ 5: const bar = () => { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /callHierarchyConstNamedArrowFunction.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyConstNamedArrowFunction.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: bar(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyConstNamedArrowFunction.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyConstNamedArrowFunction.ts:2:5-2:8 +│ │ │ 2: bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /callHierarchyConstNamedArrowFunction.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyConstNamedArrowFunction.ts:9:1-10:2 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 10: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyConstNamedArrowFunction.ts:9:10-9:13 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyConstNamedArrowFunction.ts:6:5-6:8 +│ │ │ 6: baz(); +│ │ │ ^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyConstNamedClassExpression.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyConstNamedClassExpression.callHierarchy.txt new file mode 100644 index 0000000000..61abee5bec --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyConstNamedClassExpression.callHierarchy.txt @@ -0,0 +1,70 @@ +// === Call Hierarchy === +╭ name: Bar +├ kind: class +├ file: /callHierarchyConstNamedClassExpression.ts +├ span: +│ ╭ /callHierarchyConstNamedClassExpression.ts:5:13-9:2 +│ │ 5: const Bar = class { +│ │ ^^^^^^^ +│ │ 6: constructor() { +│ │ ^^^^^^^^^^^^^^^^^^^ +│ │ 7: baz(); +│ │ ^^^^^^^^^^^^^^ +│ │ 8: } +│ │ ^^^^^ +│ │ 9: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyConstNamedClassExpression.ts:5:7-5:10 +│ │ 5: const Bar = class { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /callHierarchyConstNamedClassExpression.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyConstNamedClassExpression.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: new Bar(); +│ │ │ │ ^^^^^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyConstNamedClassExpression.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyConstNamedClassExpression.ts:2:9-2:12 +│ │ │ 2: new Bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /callHierarchyConstNamedClassExpression.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyConstNamedClassExpression.ts:11:1-12:2 +│ │ │ │ 11: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 12: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyConstNamedClassExpression.ts:11:10-11:13 +│ │ │ │ 11: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyConstNamedClassExpression.ts:7:9-7:12 +│ │ │ 7: baz(); +│ │ │ ^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyConstNamedFunctionExpression.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyConstNamedFunctionExpression.callHierarchy.txt new file mode 100644 index 0000000000..d1bb8a767c --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyConstNamedFunctionExpression.callHierarchy.txt @@ -0,0 +1,66 @@ +// === Call Hierarchy === +╭ name: bar +├ kind: function +├ file: /callHierarchyConstNamedFunctionExpression.ts +├ span: +│ ╭ /callHierarchyConstNamedFunctionExpression.ts:5:13-7:2 +│ │ 5: const bar = function () { +│ │ ^^^^^^^^^^^^^ +│ │ 6: baz(); +│ │ ^^^^^^^^^^ +│ │ 7: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyConstNamedFunctionExpression.ts:5:7-5:10 +│ │ 5: const bar = function () { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /callHierarchyConstNamedFunctionExpression.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyConstNamedFunctionExpression.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: bar(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyConstNamedFunctionExpression.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyConstNamedFunctionExpression.ts:2:5-2:8 +│ │ │ 2: bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /callHierarchyConstNamedFunctionExpression.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyConstNamedFunctionExpression.ts:9:1-10:2 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 10: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyConstNamedFunctionExpression.ts:9:10-9:13 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyConstNamedFunctionExpression.ts:6:5-6:8 +│ │ │ 6: baz(); +│ │ │ ^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyContainerName.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyContainerName.callHierarchy.txt new file mode 100644 index 0000000000..237f7ae11a --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyContainerName.callHierarchy.txt @@ -0,0 +1,166 @@ +// === Call Hierarchy === +╭ name: f +├ kind: function +├ file: /callHierarchyContainerName.ts +├ span: +│ ╭ /callHierarchyContainerName.ts:1:1-1:16 +│ │ 1: function f() {} +│ │ ^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyContainerName.ts:1:10-1:11 +│ │ 1: function f() {} +│ │ ^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: sameName +│ │ ├ kind: method +│ │ ├ containerName: A +│ │ ├ file: /callHierarchyContainerName.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyContainerName.ts:4:3-6:4 +│ │ │ │ 4: static sameName() { +│ │ │ │ ^^^^^^^^^^^^^^^^^^^ +│ │ │ │ 5: f(); +│ │ │ │ ^^^^^^^^ +│ │ │ │ 6: } +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyContainerName.ts:4:10-4:18 +│ │ │ │ 4: static sameName() { +│ │ │ │ ^^^^^^^^ +│ │ │ ╰ +│ │ ├ incoming: +│ │ │ ╭ from: +│ │ │ │ ╭ name: sameName +│ │ │ │ ├ kind: method +│ │ │ │ ├ containerName: B +│ │ │ │ ├ file: /callHierarchyContainerName.ts +│ │ │ │ ├ span: +│ │ │ │ │ ╭ /callHierarchyContainerName.ts:10:3-12:4 +│ │ │ │ │ │ 10: sameName() { +│ │ │ │ │ │ ^^^^^^^^^^^^ +│ │ │ │ │ │ 11: A.sameName(); +│ │ │ │ │ │ ^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ 12: } +│ │ │ │ │ │ ^^^ +│ │ │ │ │ ╰ +│ │ │ │ ├ selectionSpan: +│ │ │ │ │ ╭ /callHierarchyContainerName.ts:10:3-10:11 +│ │ │ │ │ │ 10: sameName() { +│ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ │ ╰ +│ │ │ │ ├ incoming: +│ │ │ │ │ ╭ from: +│ │ │ │ │ │ ╭ name: sameName +│ │ │ │ │ │ ├ kind: property +│ │ │ │ │ │ ├ containerName: Obj +│ │ │ │ │ │ ├ file: /callHierarchyContainerName.ts +│ │ │ │ │ │ ├ span: +│ │ │ │ │ │ │ ╭ /callHierarchyContainerName.ts:16:3-18:4 +│ │ │ │ │ │ │ │ 16: get sameName() { +│ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ 17: return new B().sameName; +│ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ 18: } +│ │ │ │ │ │ │ │ ^^^ +│ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ ├ selectionSpan: +│ │ │ │ │ │ │ ╭ /callHierarchyContainerName.ts:16:7-16:15 +│ │ │ │ │ │ │ │ 16: get sameName() { +│ │ │ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ ├ incoming: +│ │ │ │ │ │ │ ╭ from: +│ │ │ │ │ │ │ │ ╭ name: sameName +│ │ │ │ │ │ │ │ ├ kind: function +│ │ │ │ │ │ │ │ ├ containerName: Foo +│ │ │ │ │ │ │ │ ├ file: /callHierarchyContainerName.ts +│ │ │ │ │ │ │ │ ├ span: +│ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerName.ts:22:3-24:4 +│ │ │ │ │ │ │ │ │ │ 22: function sameName() { +│ │ │ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ │ │ 23: return Obj.sameName; +│ │ │ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ │ │ 24: } +│ │ │ │ │ │ │ │ │ │ ^^^ +│ │ │ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ │ │ ├ selectionSpan: +│ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerName.ts:22:12-22:20 +│ │ │ │ │ │ │ │ │ │ 22: function sameName() { +│ │ │ │ │ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ │ │ ├ incoming: +│ │ │ │ │ │ │ │ │ ╭ from: +│ │ │ │ │ │ │ │ │ │ ╭ name: C +│ │ │ │ │ │ │ │ │ │ ├ kind: class +│ │ │ │ │ │ │ │ │ │ ├ containerName: Foo +│ │ │ │ │ │ │ │ │ │ ├ file: /callHierarchyContainerName.ts +│ │ │ │ │ │ │ │ │ │ ├ span: +│ │ │ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerName.ts:26:3-30:4 +│ │ │ │ │ │ │ │ │ │ │ │ 26: export class C { +│ │ │ │ │ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ │ │ │ │ 27: constructor() { +│ │ │ │ │ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ │ │ │ │ 28: sameName(); +│ │ │ │ │ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ │ │ │ │ 29: } +│ │ │ │ │ │ │ │ │ │ │ │ ^^^^^ +│ │ │ │ │ │ │ │ │ │ │ │ 30: } +│ │ │ │ │ │ │ │ │ │ │ │ ^^^ +│ │ │ │ │ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ │ │ │ │ ├ selectionSpan: +│ │ │ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerName.ts:26:16-26:17 +│ │ │ │ │ │ │ │ │ │ │ │ 26: export class C { +│ │ │ │ │ │ │ │ │ │ │ │ ^ +│ │ │ │ │ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ │ │ │ │ ├ incoming: +│ │ │ │ │ │ │ │ │ │ │ ╭ from: +│ │ │ │ │ │ │ │ │ │ │ │ ╭ name: sameName +│ │ │ │ │ │ │ │ │ │ │ │ ├ kind: function +│ │ │ │ │ │ │ │ │ │ │ │ ├ containerName: Bar +│ │ │ │ │ │ │ │ │ │ │ │ ├ file: /callHierarchyContainerName.ts +│ │ │ │ │ │ │ │ │ │ │ │ ├ span: +│ │ │ │ │ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerName.ts:34:20-34:37 +│ │ │ │ │ │ │ │ │ │ │ │ │ │ 34: const sameName = () => new Foo.C(); +│ │ │ │ │ │ │ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ │ │ │ │ │ │ ├ selectionSpan: +│ │ │ │ │ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerName.ts:34:9-34:17 +│ │ │ │ │ │ │ │ │ │ │ │ │ │ 34: const sameName = () => new Foo.C(); +│ │ │ │ │ │ │ │ │ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ │ │ │ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ │ │ │ │ │ │ ╰ incoming: none +│ │ │ │ │ │ │ │ │ │ │ ├ fromSpans: +│ │ │ │ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerName.ts:34:34-34:35 +│ │ │ │ │ │ │ │ │ │ │ │ │ 34: const sameName = () => new Foo.C(); +│ │ │ │ │ │ │ │ │ │ │ │ │ ^ +│ │ │ │ │ │ │ │ │ │ ╰ ╰ ╰ +│ │ │ │ │ │ │ │ │ ├ fromSpans: +│ │ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerName.ts:28:7-28:15 +│ │ │ │ │ │ │ │ │ │ │ 28: sameName(); +│ │ │ │ │ │ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ │ │ │ │ ╰ ╰ ╰ +│ │ │ │ │ │ │ ├ fromSpans: +│ │ │ │ │ │ │ │ ╭ /callHierarchyContainerName.ts:23:16-23:24 +│ │ │ │ │ │ │ │ │ 23: return Obj.sameName; +│ │ │ │ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ │ │ ╰ ╰ ╰ +│ │ │ │ │ ├ fromSpans: +│ │ │ │ │ │ ╭ /callHierarchyContainerName.ts:17:20-17:28 +│ │ │ │ │ │ │ 17: return new B().sameName; +│ │ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ ╰ ╰ ╰ +│ │ │ ├ fromSpans: +│ │ │ │ ╭ /callHierarchyContainerName.ts:11:7-11:15 +│ │ │ │ │ 11: A.sameName(); +│ │ │ │ │ ^^^^^^^^ +│ │ ╰ ╰ ╰ +│ ├ fromSpans: +│ │ ╭ /callHierarchyContainerName.ts:5:5-5:6 +│ │ │ 5: f(); +│ │ │ ^ +│ ╰ ╰ +╰ outgoing: none \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyContainerNameServer.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyContainerNameServer.callHierarchy.txt new file mode 100644 index 0000000000..22c38f323c --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyContainerNameServer.callHierarchy.txt @@ -0,0 +1,166 @@ +// === Call Hierarchy === +╭ name: f +├ kind: function +├ file: /callHierarchyContainerNameServer.ts +├ span: +│ ╭ /callHierarchyContainerNameServer.ts:1:1-1:16 +│ │ 1: function f() {} +│ │ ^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyContainerNameServer.ts:1:10-1:11 +│ │ 1: function f() {} +│ │ ^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: sameName +│ │ ├ kind: method +│ │ ├ containerName: A +│ │ ├ file: /callHierarchyContainerNameServer.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyContainerNameServer.ts:4:3-6:4 +│ │ │ │ 4: static sameName() { +│ │ │ │ ^^^^^^^^^^^^^^^^^^^ +│ │ │ │ 5: f(); +│ │ │ │ ^^^^^^^^ +│ │ │ │ 6: } +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyContainerNameServer.ts:4:10-4:18 +│ │ │ │ 4: static sameName() { +│ │ │ │ ^^^^^^^^ +│ │ │ ╰ +│ │ ├ incoming: +│ │ │ ╭ from: +│ │ │ │ ╭ name: sameName +│ │ │ │ ├ kind: method +│ │ │ │ ├ containerName: B +│ │ │ │ ├ file: /callHierarchyContainerNameServer.ts +│ │ │ │ ├ span: +│ │ │ │ │ ╭ /callHierarchyContainerNameServer.ts:10:3-12:4 +│ │ │ │ │ │ 10: sameName() { +│ │ │ │ │ │ ^^^^^^^^^^^^ +│ │ │ │ │ │ 11: A.sameName(); +│ │ │ │ │ │ ^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ 12: } +│ │ │ │ │ │ ^^^ +│ │ │ │ │ ╰ +│ │ │ │ ├ selectionSpan: +│ │ │ │ │ ╭ /callHierarchyContainerNameServer.ts:10:3-10:11 +│ │ │ │ │ │ 10: sameName() { +│ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ │ ╰ +│ │ │ │ ├ incoming: +│ │ │ │ │ ╭ from: +│ │ │ │ │ │ ╭ name: sameName +│ │ │ │ │ │ ├ kind: property +│ │ │ │ │ │ ├ containerName: Obj +│ │ │ │ │ │ ├ file: /callHierarchyContainerNameServer.ts +│ │ │ │ │ │ ├ span: +│ │ │ │ │ │ │ ╭ /callHierarchyContainerNameServer.ts:16:3-18:4 +│ │ │ │ │ │ │ │ 16: get sameName() { +│ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ 17: return new B().sameName; +│ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ 18: } +│ │ │ │ │ │ │ │ ^^^ +│ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ ├ selectionSpan: +│ │ │ │ │ │ │ ╭ /callHierarchyContainerNameServer.ts:16:7-16:15 +│ │ │ │ │ │ │ │ 16: get sameName() { +│ │ │ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ ├ incoming: +│ │ │ │ │ │ │ ╭ from: +│ │ │ │ │ │ │ │ ╭ name: sameName +│ │ │ │ │ │ │ │ ├ kind: function +│ │ │ │ │ │ │ │ ├ containerName: Foo +│ │ │ │ │ │ │ │ ├ file: /callHierarchyContainerNameServer.ts +│ │ │ │ │ │ │ │ ├ span: +│ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerNameServer.ts:22:3-24:4 +│ │ │ │ │ │ │ │ │ │ 22: function sameName() { +│ │ │ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ │ │ 23: return Obj.sameName; +│ │ │ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ │ │ 24: } +│ │ │ │ │ │ │ │ │ │ ^^^ +│ │ │ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ │ │ ├ selectionSpan: +│ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerNameServer.ts:22:12-22:20 +│ │ │ │ │ │ │ │ │ │ 22: function sameName() { +│ │ │ │ │ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ │ │ ├ incoming: +│ │ │ │ │ │ │ │ │ ╭ from: +│ │ │ │ │ │ │ │ │ │ ╭ name: C +│ │ │ │ │ │ │ │ │ │ ├ kind: class +│ │ │ │ │ │ │ │ │ │ ├ containerName: Foo +│ │ │ │ │ │ │ │ │ │ ├ file: /callHierarchyContainerNameServer.ts +│ │ │ │ │ │ │ │ │ │ ├ span: +│ │ │ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerNameServer.ts:26:3-30:4 +│ │ │ │ │ │ │ │ │ │ │ │ 26: export class C { +│ │ │ │ │ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ │ │ │ │ 27: constructor() { +│ │ │ │ │ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ │ │ │ │ 28: sameName(); +│ │ │ │ │ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ │ │ │ │ 29: } +│ │ │ │ │ │ │ │ │ │ │ │ ^^^^^ +│ │ │ │ │ │ │ │ │ │ │ │ 30: } +│ │ │ │ │ │ │ │ │ │ │ │ ^^^ +│ │ │ │ │ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ │ │ │ │ ├ selectionSpan: +│ │ │ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerNameServer.ts:26:16-26:17 +│ │ │ │ │ │ │ │ │ │ │ │ 26: export class C { +│ │ │ │ │ │ │ │ │ │ │ │ ^ +│ │ │ │ │ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ │ │ │ │ ├ incoming: +│ │ │ │ │ │ │ │ │ │ │ ╭ from: +│ │ │ │ │ │ │ │ │ │ │ │ ╭ name: sameName +│ │ │ │ │ │ │ │ │ │ │ │ ├ kind: function +│ │ │ │ │ │ │ │ │ │ │ │ ├ containerName: Bar +│ │ │ │ │ │ │ │ │ │ │ │ ├ file: /callHierarchyContainerNameServer.ts +│ │ │ │ │ │ │ │ │ │ │ │ ├ span: +│ │ │ │ │ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerNameServer.ts:34:20-34:37 +│ │ │ │ │ │ │ │ │ │ │ │ │ │ 34: const sameName = () => new Foo.C(); +│ │ │ │ │ │ │ │ │ │ │ │ │ │ ^^^^^^^^^^^^^^^^^ +│ │ │ │ │ │ │ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ │ │ │ │ │ │ ├ selectionSpan: +│ │ │ │ │ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerNameServer.ts:34:9-34:17 +│ │ │ │ │ │ │ │ │ │ │ │ │ │ 34: const sameName = () => new Foo.C(); +│ │ │ │ │ │ │ │ │ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ │ │ │ │ │ │ │ │ │ ╰ +│ │ │ │ │ │ │ │ │ │ │ │ ╰ incoming: none +│ │ │ │ │ │ │ │ │ │ │ ├ fromSpans: +│ │ │ │ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerNameServer.ts:34:34-34:35 +│ │ │ │ │ │ │ │ │ │ │ │ │ 34: const sameName = () => new Foo.C(); +│ │ │ │ │ │ │ │ │ │ │ │ │ ^ +│ │ │ │ │ │ │ │ │ │ ╰ ╰ ╰ +│ │ │ │ │ │ │ │ │ ├ fromSpans: +│ │ │ │ │ │ │ │ │ │ ╭ /callHierarchyContainerNameServer.ts:28:7-28:15 +│ │ │ │ │ │ │ │ │ │ │ 28: sameName(); +│ │ │ │ │ │ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ │ │ │ │ ╰ ╰ ╰ +│ │ │ │ │ │ │ ├ fromSpans: +│ │ │ │ │ │ │ │ ╭ /callHierarchyContainerNameServer.ts:23:16-23:24 +│ │ │ │ │ │ │ │ │ 23: return Obj.sameName; +│ │ │ │ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ │ │ ╰ ╰ ╰ +│ │ │ │ │ ├ fromSpans: +│ │ │ │ │ │ ╭ /callHierarchyContainerNameServer.ts:17:20-17:28 +│ │ │ │ │ │ │ 17: return new B().sameName; +│ │ │ │ │ │ │ ^^^^^^^^ +│ │ │ │ ╰ ╰ ╰ +│ │ │ ├ fromSpans: +│ │ │ │ ╭ /callHierarchyContainerNameServer.ts:11:7-11:15 +│ │ │ │ │ 11: A.sameName(); +│ │ │ │ │ ^^^^^^^^ +│ │ ╰ ╰ ╰ +│ ├ fromSpans: +│ │ ╭ /callHierarchyContainerNameServer.ts:5:5-5:6 +│ │ │ 5: f(); +│ │ │ ^ +│ ╰ ╰ +╰ outgoing: none \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyCrossFile.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyCrossFile.callHierarchy.txt new file mode 100644 index 0000000000..e11d62c05a --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyCrossFile.callHierarchy.txt @@ -0,0 +1,64 @@ +// === Call Hierarchy === +╭ name: createModelReference +├ kind: function +├ file: /a.ts +├ span: +│ ╭ /a.ts:1:1-1:42 +│ │ 1: export function createModelReference() {} +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /a.ts:1:17-1:37 +│ │ 1: export function createModelReference() {} +│ │ ^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: openElementsAtEditor +│ │ ├ kind: function +│ │ ├ file: /b.ts +│ │ ├ span: +│ │ │ ╭ /b.ts:2:1-4:2 +│ │ │ │ 2: function openElementsAtEditor() { +│ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ 3: createModelReference(); +│ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ 4: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /b.ts:2:10-2:30 +│ │ │ │ 2: function openElementsAtEditor() { +│ │ │ │ ^^^^^^^^^^^^^^^^^^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /b.ts:3:3-3:23 +│ │ │ 3: createModelReference(); +│ │ │ ^^^^^^^^^^^^^^^^^^^^ +│ ╰ ╰ +│ ╭ from: +│ │ ╭ name: registerDefaultLanguageCommand +│ │ ├ kind: function +│ │ ├ file: /c.ts +│ │ ├ span: +│ │ │ ╭ /c.ts:2:1-4:2 +│ │ │ │ 2: function registerDefaultLanguageCommand() { +│ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ 3: createModelReference(); +│ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ 4: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /c.ts:2:10-2:40 +│ │ │ │ 2: function registerDefaultLanguageCommand() { +│ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /c.ts:3:3-3:23 +│ │ │ 3: createModelReference(); +│ │ │ ^^^^^^^^^^^^^^^^^^^^ +│ ╰ ╰ +╰ outgoing: none \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyDecorator.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyDecorator.callHierarchy.txt new file mode 100644 index 0000000000..879d802f63 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyDecorator.callHierarchy.txt @@ -0,0 +1,66 @@ +// === Call Hierarchy === +╭ name: bar +├ kind: function +├ file: /callHierarchyDecorator.ts +├ span: +│ ╭ /callHierarchyDecorator.ts:5:1-7:2 +│ │ 5: function bar() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 6: baz(); +│ │ ^^^^^^^^^^ +│ │ 7: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyDecorator.ts:5:10-5:13 +│ │ 5: function bar() { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: Foo +│ │ ├ kind: class +│ │ ├ file: /callHierarchyDecorator.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyDecorator.ts:1:1-3:2 +│ │ │ │ 1: @bar +│ │ │ │ ^^^^ +│ │ │ │ 2: class Foo { +│ │ │ │ ^^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyDecorator.ts:2:7-2:10 +│ │ │ │ 2: class Foo { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyDecorator.ts:1:2-1:5 +│ │ │ 1: @bar +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /callHierarchyDecorator.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyDecorator.ts:9:1-10:2 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 10: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyDecorator.ts:9:10-9:13 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyDecorator.ts:6:5-6:8 +│ │ │ 6: baz(); +│ │ │ ^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyExportDefaultClass.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyExportDefaultClass.callHierarchy.txt new file mode 100644 index 0000000000..430a44c476 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyExportDefaultClass.callHierarchy.txt @@ -0,0 +1,70 @@ +// === Call Hierarchy === +╭ name: default +├ kind: class +├ file: /other.ts +├ span: +│ ╭ /other.ts:1:1-5:2 +│ │ 1: export default class { +│ │ ^^^^^^^^^^^^^^^^^^^^^^ +│ │ 2: constructor() { +│ │ ^^^^^^^^^^^^^^^^^^^ +│ │ 3: baz(); +│ │ ^^^^^^^^^^^^^^ +│ │ 4: } +│ │ ^^^^^ +│ │ 5: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /other.ts:1:8-1:15 +│ │ 1: export default class { +│ │ ^^^^^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /main.ts +│ │ ├ span: +│ │ │ ╭ /main.ts:3:1-5:2 +│ │ │ │ 3: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 4: new Bar(); +│ │ │ │ ^^^^^^^^^^^^^^ +│ │ │ │ 5: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /main.ts:3:10-3:13 +│ │ │ │ 3: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /main.ts:4:9-4:12 +│ │ │ 4: new Bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /other.ts +│ │ ├ span: +│ │ │ ╭ /other.ts:7:1-8:2 +│ │ │ │ 7: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 8: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /other.ts:7:10-7:13 +│ │ │ │ 7: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /other.ts:3:9-3:12 +│ │ │ 3: baz(); +│ │ │ ^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyExportDefaultFunction.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyExportDefaultFunction.callHierarchy.txt new file mode 100644 index 0000000000..eba573d573 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyExportDefaultFunction.callHierarchy.txt @@ -0,0 +1,66 @@ +// === Call Hierarchy === +╭ name: default +├ kind: function +├ file: /other.ts +├ span: +│ ╭ /other.ts:1:1-3:2 +│ │ 1: export default function () { +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ 2: baz(); +│ │ ^^^^^^^^^^ +│ │ 3: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /other.ts:1:8-1:15 +│ │ 1: export default function () { +│ │ ^^^^^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /main.ts +│ │ ├ span: +│ │ │ ╭ /main.ts:3:1-5:2 +│ │ │ │ 3: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 4: bar(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 5: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /main.ts:3:10-3:13 +│ │ │ │ 3: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /main.ts:4:5-4:8 +│ │ │ 4: bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /other.ts +│ │ ├ span: +│ │ │ ╭ /other.ts:5:1-6:2 +│ │ │ │ 5: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 6: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /other.ts:5:10-5:13 +│ │ │ │ 5: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /other.ts:2:5-2:8 +│ │ │ 2: baz(); +│ │ │ ^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyExportEqualsFunction.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyExportEqualsFunction.callHierarchy.txt new file mode 100644 index 0000000000..3e85787a89 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyExportEqualsFunction.callHierarchy.txt @@ -0,0 +1,48 @@ +// === Call Hierarchy === +╭ name: /other.ts +├ kind: module +├ file: /other.ts +├ span: +│ ╭ /other.ts:1:1-6:2 +│ │ 1: export = function () { +│ │ ^^^^^^^^^^^^^^^^^^^^^^ +│ │ 2: baz(); +│ │ ^^^^^^^^^^ +│ │ 3: } +│ │ ^ +│ │ 4: +│ │ ^ +│ │ 5: function baz() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 6: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /other.ts:1:1-1:1 +│ │ 1: export = function () { +│ │ < +│ ╰ +├ incoming: none +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /other.ts +│ │ ├ span: +│ │ │ ╭ /other.ts:5:1-6:2 +│ │ │ │ 5: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 6: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /other.ts:5:10-5:13 +│ │ │ │ 5: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /other.ts:2:5-2:8 +│ │ │ 2: baz(); +│ │ │ ^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFile.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFile.callHierarchy.txt new file mode 100644 index 0000000000..be23e82ae3 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFile.callHierarchy.txt @@ -0,0 +1,42 @@ +// === Call Hierarchy === +╭ name: foo +├ kind: function +├ file: /callHierarchyFile.ts +├ span: +│ ╭ /callHierarchyFile.ts:2:1-3:2 +│ │ 2: function foo() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 3: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyFile.ts:2:10-2:13 +│ │ 2: function foo() { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: /callHierarchyFile.ts +│ │ ├ kind: file +│ │ ├ file: /callHierarchyFile.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyFile.ts:1:1-3:2 +│ │ │ │ 1: foo(); +│ │ │ │ ^^^^^^ +│ │ │ │ 2: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyFile.ts:1:1-1:1 +│ │ │ │ 1: foo(); +│ │ │ │ < +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyFile.ts:1:1-1:4 +│ │ │ 1: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunction.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunction.callHierarchy.txt new file mode 100644 index 0000000000..c43da437ea --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunction.callHierarchy.txt @@ -0,0 +1,96 @@ +// === Call Hierarchy === +╭ name: bar +├ kind: function +├ file: /callHierarchyFunction.ts +├ span: +│ ╭ /callHierarchyFunction.ts:5:1-9:2 +│ │ 5: function bar() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 6: baz(); +│ │ ^^^^^^^^^^ +│ │ 7: quxx(); +│ │ ^^^^^^^^^^^ +│ │ 8: baz(); +│ │ ^^^^^^^^^^ +│ │ 9: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyFunction.ts:5:10-5:13 +│ │ 5: function bar() { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /callHierarchyFunction.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyFunction.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: bar(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyFunction.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyFunction.ts:2:5-2:8 +│ │ │ 2: bar(); +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /callHierarchyFunction.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyFunction.ts:11:1-12:2 +│ │ │ │ 11: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 12: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyFunction.ts:11:10-11:13 +│ │ │ │ 11: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyFunction.ts:6:5-6:8 +│ │ │ 6: baz(); +│ │ │ ^^^ +│ │ ╰ +│ │ ╭ /callHierarchyFunction.ts:8:5-8:8 +│ │ │ 8: baz(); +│ │ │ ^^^ +│ ╰ ╰ +│ ╭ to: +│ │ ╭ name: quxx +│ │ ├ kind: function +│ │ ├ file: /callHierarchyFunction.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyFunction.ts:14:1-15:2 +│ │ │ │ 14: function quxx() { +│ │ │ │ ^^^^^^^^^^^^^^^^^ +│ │ │ │ 15: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyFunction.ts:14:10-14:14 +│ │ │ │ 14: function quxx() { +│ │ │ │ ^^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyFunction.ts:7:5-7:9 +│ │ │ 7: quxx(); +│ │ │ ^^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.1.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.1.callHierarchy.txt new file mode 100644 index 0000000000..3b77dc6cfb --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.1.callHierarchy.txt @@ -0,0 +1,79 @@ +// === Call Hierarchy === +╭ name: foo +├ kind: function +├ file: /a.d.ts +├ span: +│ ╭ /a.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /a.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /main.ts +│ │ ├ span: +│ │ │ ╭ /main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none +╭ name: foo +├ kind: function +├ file: /b.d.ts +├ span: +│ ╭ /b.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /b.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /main.ts +│ │ ├ span: +│ │ │ ╭ /main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.2.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.2.callHierarchy.txt new file mode 100644 index 0000000000..3b77dc6cfb --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.2.callHierarchy.txt @@ -0,0 +1,79 @@ +// === Call Hierarchy === +╭ name: foo +├ kind: function +├ file: /a.d.ts +├ span: +│ ╭ /a.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /a.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /main.ts +│ │ ├ span: +│ │ │ ╭ /main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none +╭ name: foo +├ kind: function +├ file: /b.d.ts +├ span: +│ ╭ /b.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /b.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /main.ts +│ │ ├ span: +│ │ │ ╭ /main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.3.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.3.callHierarchy.txt new file mode 100644 index 0000000000..3b77dc6cfb --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.3.callHierarchy.txt @@ -0,0 +1,79 @@ +// === Call Hierarchy === +╭ name: foo +├ kind: function +├ file: /a.d.ts +├ span: +│ ╭ /a.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /a.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /main.ts +│ │ ├ span: +│ │ │ ╭ /main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none +╭ name: foo +├ kind: function +├ file: /b.d.ts +├ span: +│ ╭ /b.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /b.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /main.ts +│ │ ├ span: +│ │ │ ╭ /main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.4.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.4.callHierarchy.txt new file mode 100644 index 0000000000..3b77dc6cfb --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.4.callHierarchy.txt @@ -0,0 +1,79 @@ +// === Call Hierarchy === +╭ name: foo +├ kind: function +├ file: /a.d.ts +├ span: +│ ╭ /a.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /a.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: number): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /main.ts +│ │ ├ span: +│ │ │ ╭ /main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none +╭ name: foo +├ kind: function +├ file: /b.d.ts +├ span: +│ ╭ /b.d.ts:1:1-1:40 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /b.d.ts:1:18-1:21 +│ │ 1: declare function foo(x?: string): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: bar +│ │ ├ kind: function +│ │ ├ file: /main.ts +│ │ ├ span: +│ │ │ ╭ /main.ts:1:1-3:2 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /main.ts:1:10-1:13 +│ │ │ │ 1: function bar() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.5.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.5.callHierarchy.txt new file mode 100644 index 0000000000..b4b46fc4f5 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyFunctionAmbiguity.5.callHierarchy.txt @@ -0,0 +1,60 @@ +// === Call Hierarchy === +╭ name: bar +├ kind: function +├ file: /main.ts +├ span: +│ ╭ /main.ts:1:1-3:2 +│ │ 1: function bar() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 2: foo(); +│ │ ^^^^^^^^^^ +│ │ 3: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /main.ts:1:10-1:13 +│ │ 1: function bar() { +│ │ ^^^ +│ ╰ +├ incoming: none +├ outgoing: +│ ╭ to: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /a.d.ts +│ │ ├ span: +│ │ │ ╭ /a.d.ts:1:1-1:40 +│ │ │ │ 1: declare function foo(x?: number): void; +│ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /a.d.ts:1:18-1:21 +│ │ │ │ 1: declare function foo(x?: number): void; +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +│ ╰ ╰ +│ ╭ to: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /b.d.ts +│ │ ├ span: +│ │ │ ╭ /b.d.ts:1:1-1:40 +│ │ │ │ 1: declare function foo(x?: string): void; +│ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /b.d.ts:1:18-1:21 +│ │ │ │ 1: declare function foo(x?: string): void; +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /main.ts:2:5-2:8 +│ │ │ 2: foo(); +│ │ │ ^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyInterfaceMethod.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyInterfaceMethod.callHierarchy.txt new file mode 100644 index 0000000000..4cdbb8c53b --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyInterfaceMethod.callHierarchy.txt @@ -0,0 +1,48 @@ +// === Call Hierarchy === +╭ name: foo +├ kind: method +├ file: /callHierarchyInterfaceMethod.ts +├ span: +│ ╭ /callHierarchyInterfaceMethod.ts:2:5-2:17 +│ │ 2: foo(): void; +│ │ ^^^^^^^^^^^^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyInterfaceMethod.ts:2:5-2:8 +│ │ 2: foo(): void; +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: /callHierarchyInterfaceMethod.ts +│ │ ├ kind: file +│ │ ├ file: /callHierarchyInterfaceMethod.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyInterfaceMethod.ts:1:1-7:11 +│ │ │ │ 1: interface I { +│ │ │ │ ^^^^^^^^^^^^^ +│ │ │ │ 2: foo(): void; +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ │ 4: +│ │ │ │ ^ +│ │ │ │ 5: const obj: I = { foo() {} }; +│ │ │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ │ │ 6: +│ │ │ │ ^ +│ │ │ │ 7: obj.foo(); +│ │ │ │ ^^^^^^^^^^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyInterfaceMethod.ts:1:1-1:1 +│ │ │ │ 1: interface I { +│ │ │ │ < +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyInterfaceMethod.ts:7:5-7:8 +│ │ │ 7: obj.foo(); +│ │ │ ^^^ +│ ╰ ╰ +╰ outgoing: none \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyJsxElement.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyJsxElement.callHierarchy.txt new file mode 100644 index 0000000000..4609c0ecd6 --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyJsxElement.callHierarchy.txt @@ -0,0 +1,66 @@ +// === Call Hierarchy === +╭ name: Bar +├ kind: function +├ file: /main.tsx +├ span: +│ ╭ /main.tsx:5:1-7:2 +│ │ 5: function Bar() { +│ │ ^^^^^^^^^^^^^^^^ +│ │ 6: baz(); +│ │ ^^^^^^^^^^ +│ │ 7: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /main.tsx:5:10-5:13 +│ │ 5: function Bar() { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /main.tsx +│ │ ├ span: +│ │ │ ╭ /main.tsx:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: return ; +│ │ │ │ ^^^^^^^^^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /main.tsx:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /main.tsx:2:13-2:16 +│ │ │ 2: return ; +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /main.tsx +│ │ ├ span: +│ │ │ ╭ /main.tsx:9:1-10:2 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 10: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /main.tsx:9:10-9:13 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /main.tsx:6:5-6:8 +│ │ │ 6: baz(); +│ │ │ ^^^ +╰ ╰ ╰ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyTaggedTemplate.callHierarchy.txt b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyTaggedTemplate.callHierarchy.txt new file mode 100644 index 0000000000..e7b0093b0c --- /dev/null +++ b/testdata/baselines/reference/submodule/fourslash/callHierarchy/callHierarchyTaggedTemplate.callHierarchy.txt @@ -0,0 +1,66 @@ +// === Call Hierarchy === +╭ name: bar +├ kind: function +├ file: /callHierarchyTaggedTemplate.ts +├ span: +│ ╭ /callHierarchyTaggedTemplate.ts:5:1-7:2 +│ │ 5: function bar(array: TemplateStringsArray, ...args: any[]) { +│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +│ │ 6: baz(); +│ │ ^^^^^^^^^^ +│ │ 7: } +│ │ ^ +│ ╰ +├ selectionSpan: +│ ╭ /callHierarchyTaggedTemplate.ts:5:10-5:13 +│ │ 5: function bar(array: TemplateStringsArray, ...args: any[]) { +│ │ ^^^ +│ ╰ +├ incoming: +│ ╭ from: +│ │ ╭ name: foo +│ │ ├ kind: function +│ │ ├ file: /callHierarchyTaggedTemplate.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyTaggedTemplate.ts:1:1-3:2 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 2: bar`a${1}b`; +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 3: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyTaggedTemplate.ts:1:10-1:13 +│ │ │ │ 1: function foo() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ incoming: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyTaggedTemplate.ts:2:5-2:8 +│ │ │ 2: bar`a${1}b`; +│ │ │ ^^^ +│ ╰ ╰ +├ outgoing: +│ ╭ to: +│ │ ╭ name: baz +│ │ ├ kind: function +│ │ ├ file: /callHierarchyTaggedTemplate.ts +│ │ ├ span: +│ │ │ ╭ /callHierarchyTaggedTemplate.ts:9:1-10:2 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^^^^^^^^^^^^^^ +│ │ │ │ 10: } +│ │ │ │ ^ +│ │ │ ╰ +│ │ ├ selectionSpan: +│ │ │ ╭ /callHierarchyTaggedTemplate.ts:9:10-9:13 +│ │ │ │ 9: function baz() { +│ │ │ │ ^^^ +│ │ │ ╰ +│ │ ╰ outgoing: none +│ ├ fromSpans: +│ │ ╭ /callHierarchyTaggedTemplate.ts:6:5-6:8 +│ │ │ 6: baz(); +│ │ │ ^^^ +╰ ╰ ╰ \ No newline at end of file