diff --git a/internal/fourslash/_scripts/crashingTests.txt b/internal/fourslash/_scripts/crashingTests.txt index c8f66569cc2..6e2e3f5b173 100644 --- a/internal/fourslash/_scripts/crashingTests.txt +++ b/internal/fourslash/_scripts/crashingTests.txt @@ -5,8 +5,4 @@ TestFormatDocumentWithTrivia TestFormattingJsxTexts4 TestGetOccurrencesIfElseBroken TestImportNameCodeFix_importType8 -TestJsdocLink2 -TestJsdocLink3 -TestJsdocLink6 -TestQuickInfoAlias TestQuickInfoBindingPatternInJsdocNoCrash1 diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt index 04ba4ebb282..eaef397bf86 100644 --- a/internal/fourslash/_scripts/failingTests.txt +++ b/internal/fourslash/_scripts/failingTests.txt @@ -375,9 +375,6 @@ TestJsDocFunctionSignatures7 TestJsDocFunctionSignatures8 TestJsDocGenerics2 TestJsDocInheritDoc -TestJsdocLink2 -TestJsdocLink3 -TestJsdocLink6 TestJsDocPropertyDescription1 TestJsDocPropertyDescription10 TestJsDocPropertyDescription11 @@ -430,7 +427,6 @@ TestProtoVarVisibleWithOuterScopeUnderscoreProto TestQualifyModuleTypeNames TestQuickInfo_notInsideComment TestQuickinfo01 -TestQuickInfoAlias TestQuickInfoAssertionNodeNotReusedWhenTypeNotEquivalent1 TestQuickInfoBindingPatternInJsdocNoCrash1 TestQuickInfoCanBeTruncated diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index a78e8f95402..61fcf090dcf 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -2101,7 +2101,7 @@ func (f *FourslashTest) VerifyBaselineHover(t *testing.T) { params := &lsproto.HoverParams{ TextDocument: lsproto.TextDocumentIdentifier{ - Uri: lsconv.FileNameToDocumentURI(f.activeFilename), + Uri: lsconv.FileNameToDocumentURI(marker.fileName), }, Position: marker.LSPosition, } diff --git a/internal/fourslash/tests/quickInfoMergedAlias_test.go b/internal/fourslash/tests/quickInfoMergedAlias_test.go new file mode 100644 index 00000000000..afb165a39ac --- /dev/null +++ b/internal/fourslash/tests/quickInfoMergedAlias_test.go @@ -0,0 +1,46 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestQuickInfoMergedAlias(t *testing.T) { + fourslash.SkipIfFailing(t) + t.Parallel() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @filename: /a.ts +/** + * A function + */ +export function foo/*1*/() {} +// @filename: /b.ts +import { foo/*2*/ } from './a'; +export { foo/*3*/ }; + +/** + * A type + */ +type foo/*4*/ = number; + +foo/*5*/() +let x1: foo/*6*/; +// @filename: /c.ts +import { foo/*7*/ } from './b'; + +/** + * A namespace + */ +namespace foo/*8*/ { + export type bar = string[]; +} + +foo/*9*/() +let x1: foo/*10*/; +let x2: foo/*11*/.bar;` + f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) + defer done() + f.VerifyBaselineHover(t) +} diff --git a/internal/ls/hover.go b/internal/ls/hover.go index 103a70a2227..291d6fa1506 100644 --- a/internal/ls/hover.go +++ b/internal/ls/hover.go @@ -182,6 +182,12 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol var b strings.Builder var visitedAliases collections.Set[*ast.Symbol] var aliasLevel int + var firstDeclaration *ast.Node + setDeclaration := func(declaration *ast.Node) { + if firstDeclaration == nil { + firstDeclaration = declaration + } + } writeNewLine := func() { if b.Len() != 0 { b.WriteString("\n") @@ -219,14 +225,13 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol b.WriteString(">") } } - var writeSymbol func(*ast.Symbol) *ast.Node - writeSymbol = func(symbol *ast.Symbol) *ast.Node { - var declaration *ast.Node + var writeSymbol func(*ast.Symbol) + writeSymbol = func(symbol *ast.Symbol) { // Recursively write all meanings of alias if symbol.Flags&ast.SymbolFlagsAlias != 0 && visitedAliases.AddIfAbsent(symbol) { if aliasedSymbol := c.GetAliasedSymbol(symbol); aliasedSymbol != c.GetUnknownSymbol() { aliasLevel++ - declaration = writeSymbol(aliasedSymbol) + writeSymbol(aliasedSymbol) aliasLevel-- } } @@ -238,19 +243,21 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol flags = symbol.Flags & ast.SymbolFlagsType case ast.SemanticMeaningNamespace: flags = symbol.Flags & ast.SymbolFlagsNamespace + default: + flags = symbol.Flags & (ast.SymbolFlagsValue | ast.SymbolFlagsSignature | ast.SymbolFlagsType | ast.SymbolFlagsNamespace) } if flags == 0 { + if aliasLevel != 0 || b.Len() != 0 { + return + } flags = symbol.Flags & (ast.SymbolFlagsValue | ast.SymbolFlagsSignature | ast.SymbolFlagsType | ast.SymbolFlagsNamespace) if flags == 0 { - return nil + return } } if flags&ast.SymbolFlagsProperty != 0 && symbol.ValueDeclaration != nil && ast.IsMethodDeclaration(symbol.ValueDeclaration) { flags = ast.SymbolFlagsMethod } - if flags&ast.SymbolFlagsValue != 0 { - declaration = symbol.ValueDeclaration - } if flags&(ast.SymbolFlagsVariable|ast.SymbolFlagsProperty|ast.SymbolFlagsAccessor) != 0 { writeNewLine() switch { @@ -288,6 +295,7 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol } else { b.WriteString(c.TypeToStringEx(c.GetTypeOfSymbolAtLocation(symbol, node), container, typeFormatFlags)) } + setDeclaration(symbol.ValueDeclaration) } if flags&ast.SymbolFlagsEnumMember != 0 { writeNewLine() @@ -298,33 +306,32 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol b.WriteString(" = ") b.WriteString(t.AsLiteralType().String()) } + setDeclaration(symbol.ValueDeclaration) } if flags&(ast.SymbolFlagsFunction|ast.SymbolFlagsMethod) != 0 { prefix := core.IfElse(flags&ast.SymbolFlagsMethod != 0, "(method) ", "function ") if ast.IsIdentifier(node) && ast.IsFunctionLikeDeclaration(node.Parent) && node.Parent.Name() == node { - declaration = node.Parent - signatures := []*checker.Signature{c.GetSignatureFromDeclaration(declaration)} + setDeclaration(node.Parent) + signatures := []*checker.Signature{c.GetSignatureFromDeclaration(node.Parent)} writeSignatures(signatures, prefix, symbol) } else { signatures := getSignaturesAtLocation(c, symbol, checker.SignatureKindCall, node) if len(signatures) == 1 { if d := signatures[0].Declaration(); d != nil && d.Flags&ast.NodeFlagsJSDoc == 0 { - declaration = d + setDeclaration(d) } } writeSignatures(signatures, prefix, symbol) } + setDeclaration(symbol.ValueDeclaration) } if flags&(ast.SymbolFlagsClass|ast.SymbolFlagsInterface) != 0 { - if flags&ast.SymbolFlagsInterface != 0 && (declaration == nil || ast.IsIdentifier(node) && ast.IsInterfaceDeclaration(node.Parent)) { - declaration = core.Find(symbol.Declarations, ast.IsInterfaceDeclaration) - } if node.Kind == ast.KindThisKeyword || ast.IsThisInTypeQuery(node) { writeNewLine() b.WriteString("this") } else if node.Kind == ast.KindConstructorKeyword && (ast.IsConstructorDeclaration(node.Parent) || ast.IsConstructSignatureDeclaration(node.Parent)) { - declaration = node.Parent - signatures := []*checker.Signature{c.GetSignatureFromDeclaration(declaration)} + setDeclaration(node.Parent) + signatures := []*checker.Signature{c.GetSignatureFromDeclaration(node.Parent)} writeSignatures(signatures, "constructor ", symbol) } else { var signatures []*checker.Signature @@ -333,7 +340,7 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol } if len(signatures) == 1 { if d := signatures[0].Declaration(); d != nil && d.Flags&ast.NodeFlagsJSDoc == 0 { - declaration = d + setDeclaration(d) } writeSignatures(signatures, "constructor ", symbol) } else { @@ -344,22 +351,23 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol writeTypeParams(params) } } + if flags&ast.SymbolFlagsClass != 0 { + setDeclaration(symbol.ValueDeclaration) + } else { + setDeclaration(core.Find(symbol.Declarations, ast.IsInterfaceDeclaration)) + } } if flags&ast.SymbolFlagsEnum != 0 { writeNewLine() b.WriteString("enum ") b.WriteString(c.SymbolToStringEx(symbol, container, ast.SymbolFlagsNone, symbolFormatFlags)) - if declaration == nil || ast.IsIdentifier(node) && ast.IsEnumDeclaration(node.Parent) { - declaration = core.Find(symbol.Declarations, ast.IsEnumDeclaration) - } + setDeclaration(core.Find(symbol.Declarations, ast.IsEnumDeclaration)) } if flags&ast.SymbolFlagsModule != 0 { writeNewLine() b.WriteString(core.IfElse(symbol.ValueDeclaration != nil && ast.IsSourceFile(symbol.ValueDeclaration), "module ", "namespace ")) b.WriteString(c.SymbolToStringEx(symbol, container, ast.SymbolFlagsNone, symbolFormatFlags)) - if declaration == nil || ast.IsIdentifier(node) && ast.IsModuleDeclaration(node.Parent) { - declaration = core.Find(symbol.Declarations, ast.IsModuleDeclaration) - } + setDeclaration(core.Find(symbol.Declarations, ast.IsModuleDeclaration)) } if flags&ast.SymbolFlagsTypeParameter != 0 { writeNewLine() @@ -371,9 +379,7 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol b.WriteString(" extends ") b.WriteString(c.TypeToStringEx(cons, container, typeFormatFlags)) } - if declaration == nil || ast.IsIdentifier(node) && ast.IsTypeParameterDeclaration(node.Parent) { - declaration = core.Find(symbol.Declarations, ast.IsTypeParameterDeclaration) - } + setDeclaration(core.Find(symbol.Declarations, ast.IsTypeParameterDeclaration)) } if flags&ast.SymbolFlagsTypeAlias != 0 { writeNewLine() @@ -384,17 +390,14 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol b.WriteString(" = ") b.WriteString(c.TypeToStringEx(c.GetDeclaredTypeOfSymbol(symbol), container, typeFormatFlags|checker.TypeFormatFlagsInTypeAlias)) } - if declaration == nil || ast.IsIdentifier(node) && ast.IsTypeOrJSTypeAliasDeclaration(node.Parent) { - declaration = core.Find(symbol.Declarations, ast.IsTypeOrJSTypeAliasDeclaration) - } + setDeclaration(core.Find(symbol.Declarations, ast.IsTypeOrJSTypeAliasDeclaration)) } if flags&ast.SymbolFlagsSignature != 0 { writeNewLine() b.WriteString(c.TypeToStringEx(c.GetTypeOfSymbol(symbol), container, typeFormatFlags)) } - return declaration } - firstDeclaration := writeSymbol(symbol) + writeSymbol(symbol) return b.String(), firstDeclaration } diff --git a/testdata/baselines/reference/fourslash/quickInfo/jsDocAliasQuickInfo.baseline b/testdata/baselines/reference/fourslash/quickInfo/jsDocAliasQuickInfo.baseline index 52ea31202e1..02d3fd04a35 100644 --- a/testdata/baselines/reference/fourslash/quickInfo/jsDocAliasQuickInfo.baseline +++ b/testdata/baselines/reference/fourslash/quickInfo/jsDocAliasQuickInfo.baseline @@ -14,13 +14,19 @@ // | ---------------------------------------------------------------------- === /test.ts === // export { default as test } from "./jsDocAliasQuickInfo"; -// ^ +// ^^^^^^^ // | ---------------------------------------------------------------------- -// | No quickinfo at /*2*/. +// | ```tsx +// | (property) default: 10 +// | ``` +// | Comment // | ---------------------------------------------------------------------- -// ^ +// ^^^^ // | ---------------------------------------------------------------------- -// | No quickinfo at /*3*/. +// | ```tsx +// | (alias) (property) default: 10 +// | ``` +// | Comment // | ---------------------------------------------------------------------- @@ -62,7 +68,22 @@ "Name": "2", "Data": {} }, - "item": null + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(property) default: 10\n```\nComment" + }, + "range": { + "start": { + "line": 0, + "character": 9 + }, + "end": { + "line": 0, + "character": 16 + } + } + } }, { "marker": { @@ -74,6 +95,21 @@ "Name": "3", "Data": {} }, - "item": null + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(alias) (property) default: 10\n```\nComment" + }, + "range": { + "start": { + "line": 0, + "character": 20 + }, + "end": { + "line": 0, + "character": 24 + } + } + } } ] \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/quickInfo/jsdocLink2.baseline b/testdata/baselines/reference/fourslash/quickInfo/jsdocLink2.baseline new file mode 100644 index 00000000000..60410ae9b6f --- /dev/null +++ b/testdata/baselines/reference/fourslash/quickInfo/jsdocLink2.baseline @@ -0,0 +1,56 @@ +// === QuickInfo === +=== /script.ts === +// /** +// * {@link C} +// * @wat Makes a {@link C}. A default one. +// * {@link C()} +// * {@link C|postfix text} +// * {@link unformatted postfix text} +// * @see {@link C} its great +// */ +// function CC() { +// ^^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | function CC(): void +// | ``` +// | [C](file:///jsdocLink2.ts#1,7-1,8) +// | +// | *@wat* — Makes a [C](file:///jsdocLink2.ts#1,7-1,8). A default one. +// | [C()](file:///jsdocLink2.ts#1,7-1,8) +// | [postfix text](file:///jsdocLink2.ts#1,7-1,8) +// | unformatted postfix text +// | +// | *@see* — [C](file:///jsdocLink2.ts#1,7-1,8) its great +// | +// | ---------------------------------------------------------------------- +// } +[ + { + "marker": { + "Position": 177, + "LSPosition": { + "line": 8, + "character": 9 + }, + "Name": "", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\nfunction CC(): void\n```\n[C](file:///jsdocLink2.ts#1,7-1,8)\n\n*@wat* — Makes a [C](file:///jsdocLink2.ts#1,7-1,8). A default one.\n[C()](file:///jsdocLink2.ts#1,7-1,8)\n[postfix text](file:///jsdocLink2.ts#1,7-1,8)\nunformatted postfix text\n\n*@see* — [C](file:///jsdocLink2.ts#1,7-1,8) its great\n" + }, + "range": { + "start": { + "line": 8, + "character": 9 + }, + "end": { + "line": 8, + "character": 11 + } + } + } + } +] \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/quickInfo/jsdocLink3.baseline b/testdata/baselines/reference/fourslash/quickInfo/jsdocLink3.baseline new file mode 100644 index 00000000000..a5762ae2451 --- /dev/null +++ b/testdata/baselines/reference/fourslash/quickInfo/jsdocLink3.baseline @@ -0,0 +1,57 @@ +// === QuickInfo === +=== /module1.ts === +// import { C } from './jsdocLink3' +// /** +// * {@link C} +// * @wat Makes a {@link C}. A default one. +// * {@link C()} +// * {@link C|postfix text} +// * {@link unformatted postfix text} +// * @see {@link C} its great +// */ +// function CC() { +// ^^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | function CC(): void +// | ``` +// | [C](file:///jsdocLink3.ts#1,14-1,15) +// | +// | *@wat* — Makes a [C](file:///jsdocLink3.ts#1,14-1,15). A default one. +// | [C()](file:///jsdocLink3.ts#1,14-1,15) +// | [postfix text](file:///jsdocLink3.ts#1,14-1,15) +// | unformatted postfix text +// | +// | *@see* — [C](file:///jsdocLink3.ts#1,14-1,15) its great +// | +// | ---------------------------------------------------------------------- +// } +[ + { + "marker": { + "Position": 210, + "LSPosition": { + "line": 9, + "character": 9 + }, + "Name": "", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\nfunction CC(): void\n```\n[C](file:///jsdocLink3.ts#1,14-1,15)\n\n*@wat* — Makes a [C](file:///jsdocLink3.ts#1,14-1,15). A default one.\n[C()](file:///jsdocLink3.ts#1,14-1,15)\n[postfix text](file:///jsdocLink3.ts#1,14-1,15)\nunformatted postfix text\n\n*@see* — [C](file:///jsdocLink3.ts#1,14-1,15) its great\n" + }, + "range": { + "start": { + "line": 9, + "character": 9 + }, + "end": { + "line": 9, + "character": 11 + } + } + } + } +] \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/quickInfo/jsdocLink6.baseline b/testdata/baselines/reference/fourslash/quickInfo/jsdocLink6.baseline new file mode 100644 index 00000000000..d36ab34cadd --- /dev/null +++ b/testdata/baselines/reference/fourslash/quickInfo/jsdocLink6.baseline @@ -0,0 +1,45 @@ +// === QuickInfo === +=== /b.ts === +// import A, { B } from "./a"; +// /** +// * {@link A} +// * {@link B} +// */ +// export default function f() { } +// ^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | function f(): void +// | ``` +// | [A](file:///a.ts#1,25-1,26) +// | [B](file:///a.ts#2,17-2,18) +// | ---------------------------------------------------------------------- +[ + { + "marker": { + "Position": 86, + "LSPosition": { + "line": 5, + "character": 24 + }, + "Name": "", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\nfunction f(): void\n```\n[A](file:///a.ts#1,25-1,26)\n[B](file:///a.ts#2,17-2,18)" + }, + "range": { + "start": { + "line": 5, + "character": 24 + }, + "end": { + "line": 5, + "character": 25 + } + } + } + } +] \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/quickInfo/quickInfoAlias.baseline b/testdata/baselines/reference/fourslash/quickInfo/quickInfoAlias.baseline new file mode 100644 index 00000000000..9e9d88350c0 --- /dev/null +++ b/testdata/baselines/reference/fourslash/quickInfo/quickInfoAlias.baseline @@ -0,0 +1,95 @@ +// === QuickInfo === +=== /b.ts === +// import { x } from "./a"; +// x; +// ^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | (alias) const x: 0 +// | ``` +// | Doc +// | +// | *@tag* — Tag text +// | +// | ---------------------------------------------------------------------- +=== /c.ts === +// /** +// * Doc 2 +// * @tag Tag text 2 +// */ +// import { +// /** +// * Doc 3 +// * @tag Tag text 3 +// */ +// x +// } from "./a"; +// x; +// ^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | (alias) const x: 0 +// | ``` +// | Doc +// | +// | *@tag* — Tag text +// | +// | ---------------------------------------------------------------------- + + +[ + { + "marker": { + "Position": 26, + "LSPosition": { + "line": 1, + "character": 1 + }, + "Name": "b", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(alias) const x: 0\n```\nDoc\n\n*@tag* — Tag text\n" + }, + "range": { + "start": { + "line": 1, + "character": 0 + }, + "end": { + "line": 1, + "character": 1 + } + } + } + }, + { + "marker": { + "Position": 118, + "LSPosition": { + "line": 11, + "character": 1 + }, + "Name": "c", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(alias) const x: 0\n```\nDoc\n\n*@tag* — Tag text\n" + }, + "range": { + "start": { + "line": 11, + "character": 0 + }, + "end": { + "line": 11, + "character": 1 + } + } + } + } +] \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/quickInfo/quickInfoDisplayPartsExternalModuleAlias.baseline b/testdata/baselines/reference/fourslash/quickInfo/quickInfoDisplayPartsExternalModuleAlias.baseline index 6876a51533d..ad64ddf103a 100644 --- a/testdata/baselines/reference/fourslash/quickInfo/quickInfoDisplayPartsExternalModuleAlias.baseline +++ b/testdata/baselines/reference/fourslash/quickInfo/quickInfoDisplayPartsExternalModuleAlias.baseline @@ -1,32 +1,50 @@ // === QuickInfo === === /quickInfoDisplayPartsExternalModuleAlias_file1.ts === // import a1 = require("./quickInfoDisplayPartsExternalModuleAlias_file0"); -// ^ +// ^^ // | ---------------------------------------------------------------------- -// | No quickinfo at /*1*/. +// | ```tsx +// | (alias) module a1 +// | ``` +// | // | ---------------------------------------------------------------------- -// ^ +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // | ---------------------------------------------------------------------- -// | No quickinfo at /*mod1*/. +// | ```tsx +// | module a1 +// | ``` +// | // | ---------------------------------------------------------------------- // new a1.m1.c(); -// ^ +// ^^ // | ---------------------------------------------------------------------- -// | No quickinfo at /*2*/. +// | ```tsx +// | (alias) module a1 +// | ``` +// | // | ---------------------------------------------------------------------- // export import a2 = require("./quickInfoDisplayPartsExternalModuleAlias_file0"); -// ^ +// ^^ // | ---------------------------------------------------------------------- -// | No quickinfo at /*3*/. +// | ```tsx +// | (alias) module a1 +// | ``` +// | // | ---------------------------------------------------------------------- -// ^ +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // | ---------------------------------------------------------------------- -// | No quickinfo at /*mod2*/. +// | ```tsx +// | module a1 +// | ``` +// | // | ---------------------------------------------------------------------- // new a2.m1.c(); -// ^ +// ^^ // | ---------------------------------------------------------------------- -// | No quickinfo at /*4*/. +// | ```tsx +// | (alias) module a1 +// | ``` +// | // | ---------------------------------------------------------------------- [ { @@ -39,7 +57,22 @@ "Name": "1", "Data": {} }, - "item": null + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(alias) module a1\n```\n" + }, + "range": { + "start": { + "line": 0, + "character": 7 + }, + "end": { + "line": 0, + "character": 9 + } + } + } }, { "marker": { @@ -51,7 +84,22 @@ "Name": "mod1", "Data": {} }, - "item": null + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\nmodule a1\n```\n" + }, + "range": { + "start": { + "line": 0, + "character": 21 + }, + "end": { + "line": 0, + "character": 69 + } + } + } }, { "marker": { @@ -63,7 +111,22 @@ "Name": "2", "Data": {} }, - "item": null + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(alias) module a1\n```\n" + }, + "range": { + "start": { + "line": 1, + "character": 4 + }, + "end": { + "line": 1, + "character": 6 + } + } + } }, { "marker": { @@ -75,7 +138,22 @@ "Name": "3", "Data": {} }, - "item": null + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(alias) module a1\n```\n" + }, + "range": { + "start": { + "line": 2, + "character": 14 + }, + "end": { + "line": 2, + "character": 16 + } + } + } }, { "marker": { @@ -87,7 +165,22 @@ "Name": "mod2", "Data": {} }, - "item": null + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\nmodule a1\n```\n" + }, + "range": { + "start": { + "line": 2, + "character": 28 + }, + "end": { + "line": 2, + "character": 76 + } + } + } }, { "marker": { @@ -99,6 +192,21 @@ "Name": "4", "Data": {} }, - "item": null + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(alias) module a1\n```\n" + }, + "range": { + "start": { + "line": 3, + "character": 4 + }, + "end": { + "line": 3, + "character": 6 + } + } + } } ] \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/quickInfo/quickInfoJsDocAlias.baseline b/testdata/baselines/reference/fourslash/quickInfo/quickInfoJsDocAlias.baseline index 19796c5e878..565b7c8d354 100644 --- a/testdata/baselines/reference/fourslash/quickInfo/quickInfoJsDocAlias.baseline +++ b/testdata/baselines/reference/fourslash/quickInfo/quickInfoJsDocAlias.baseline @@ -2,9 +2,12 @@ === /b.ts === // import { A } from "./a"; // A() -// ^ +// ^ // | ---------------------------------------------------------------------- -// | No quickinfo at /**/. +// | ```tsx +// | (alias) const A: () => void +// | ``` +// | docs - const A: T // | ---------------------------------------------------------------------- [ { @@ -17,6 +20,21 @@ "Name": "", "Data": {} }, - "item": null + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(alias) const A: () => void\n```\ndocs - const A: T" + }, + "range": { + "start": { + "line": 1, + "character": 0 + }, + "end": { + "line": 1, + "character": 1 + } + } + } } ] \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/quickInfo/quickInfoMergedAlias.baseline b/testdata/baselines/reference/fourslash/quickInfo/quickInfoMergedAlias.baseline new file mode 100644 index 00000000000..e8acbc15931 --- /dev/null +++ b/testdata/baselines/reference/fourslash/quickInfo/quickInfoMergedAlias.baseline @@ -0,0 +1,414 @@ +// === QuickInfo === +=== /a.ts === +// /** +// * A function +// */ +// export function foo() {} +// ^^^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | function foo(): void +// | ``` +// | A function +// | ---------------------------------------------------------------------- +=== /b.ts === +// import { foo } from './a'; +// ^^^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | (alias) function foo(): void +// | type foo = number +// | ``` +// | A function +// | ---------------------------------------------------------------------- +// export { foo }; +// ^^^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | (alias) function foo(): void +// | (alias) type foo = number +// | ``` +// | A function +// | ---------------------------------------------------------------------- +// +// /** +// * A type +// */ +// type foo = number; +// ^^^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | type foo = number +// | ``` +// | A type +// | ---------------------------------------------------------------------- +// +// foo() +// ^^^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | (alias) function foo(): void +// | ``` +// | A function +// | ---------------------------------------------------------------------- +// let x1: foo; +// ^^^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | type foo = number +// | ``` +// | A type +// | ---------------------------------------------------------------------- + + +=== /c.ts === +// import { foo } from './b'; +// ^^^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | (alias) function foo(): void +// | (alias) type foo = number +// | namespace foo +// | ``` +// | A function +// | ---------------------------------------------------------------------- +// +// /** +// * A namespace +// */ +// namespace foo { +// ^^^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | namespace foo +// | ``` +// | A namespace +// | ---------------------------------------------------------------------- +// export type bar = string[]; +// } +// +// foo() +// ^^^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | (alias) function foo(): void +// | ``` +// | A function +// | ---------------------------------------------------------------------- +// let x1: foo; +// ^^^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | (alias) type foo = number +// | ``` +// | A type +// | ---------------------------------------------------------------------- +// let x2: foo.bar; +// ^^^ +// | ---------------------------------------------------------------------- +// | ```tsx +// | namespace foo +// | ``` +// | A namespace +// | ---------------------------------------------------------------------- + + +[ + { + "marker": { + "Position": 41, + "LSPosition": { + "line": 3, + "character": 19 + }, + "Name": "1", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\nfunction foo(): void\n```\nA function" + }, + "range": { + "start": { + "line": 3, + "character": 16 + }, + "end": { + "line": 3, + "character": 19 + } + } + } + }, + { + "marker": { + "Position": 12, + "LSPosition": { + "line": 0, + "character": 12 + }, + "Name": "2", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(alias) function foo(): void\ntype foo = number\n```\nA function" + }, + "range": { + "start": { + "line": 0, + "character": 9 + }, + "end": { + "line": 0, + "character": 12 + } + } + } + }, + { + "marker": { + "Position": 39, + "LSPosition": { + "line": 1, + "character": 12 + }, + "Name": "3", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(alias) function foo(): void\n(alias) type foo = number\n```\nA function" + }, + "range": { + "start": { + "line": 1, + "character": 9 + }, + "end": { + "line": 1, + "character": 12 + } + } + } + }, + { + "marker": { + "Position": 70, + "LSPosition": { + "line": 6, + "character": 8 + }, + "Name": "4", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\ntype foo = number\n```\nA type" + }, + "range": { + "start": { + "line": 6, + "character": 5 + }, + "end": { + "line": 6, + "character": 8 + } + } + } + }, + { + "marker": { + "Position": 85, + "LSPosition": { + "line": 8, + "character": 3 + }, + "Name": "5", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(alias) function foo(): void\n```\nA function" + }, + "range": { + "start": { + "line": 8, + "character": 0 + }, + "end": { + "line": 8, + "character": 3 + } + } + } + }, + { + "marker": { + "Position": 99, + "LSPosition": { + "line": 9, + "character": 11 + }, + "Name": "6", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\ntype foo = number\n```\nA type" + }, + "range": { + "start": { + "line": 9, + "character": 8 + }, + "end": { + "line": 9, + "character": 11 + } + } + } + }, + { + "marker": { + "Position": 12, + "LSPosition": { + "line": 0, + "character": 12 + }, + "Name": "7", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(alias) function foo(): void\n(alias) type foo = number\nnamespace foo\n```\nA function" + }, + "range": { + "start": { + "line": 0, + "character": 9 + }, + "end": { + "line": 0, + "character": 12 + } + } + } + }, + { + "marker": { + "Position": 64, + "LSPosition": { + "line": 5, + "character": 13 + }, + "Name": "8", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\nnamespace foo\n```\nA namespace" + }, + "range": { + "start": { + "line": 5, + "character": 10 + }, + "end": { + "line": 5, + "character": 13 + } + } + } + }, + { + "marker": { + "Position": 105, + "LSPosition": { + "line": 9, + "character": 3 + }, + "Name": "9", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(alias) function foo(): void\n```\nA function" + }, + "range": { + "start": { + "line": 9, + "character": 0 + }, + "end": { + "line": 9, + "character": 3 + } + } + } + }, + { + "marker": { + "Position": 119, + "LSPosition": { + "line": 10, + "character": 11 + }, + "Name": "10", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\n(alias) type foo = number\n```\nA type" + }, + "range": { + "start": { + "line": 10, + "character": 8 + }, + "end": { + "line": 10, + "character": 11 + } + } + } + }, + { + "marker": { + "Position": 132, + "LSPosition": { + "line": 11, + "character": 11 + }, + "Name": "11", + "Data": {} + }, + "item": { + "contents": { + "kind": "markdown", + "value": "```tsx\nnamespace foo\n```\nA namespace" + }, + "range": { + "start": { + "line": 11, + "character": 8 + }, + "end": { + "line": 11, + "character": 11 + } + } + } + } +] \ No newline at end of file