Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 37 additions & 11 deletions internal/fourslash/_scripts/convertFourslash.mts
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,14 @@ function parseFourslashStatement(statement: ts.Statement): Cmd[] | undefined {
return [parseBaselineSignatureHelp(callExpression.arguments)];
case "baselineGoToDefinition":
case "baselineGetDefinitionAtPosition":
// Both of these take the same arguments, but differ in that...
case "baselineGoToType":
// Both `baselineGoToDefinition` and `baselineGetDefinitionAtPosition` take the same
// arguments, but differ in that...
// - `verify.baselineGoToDefinition(...)` called getDefinitionAndBoundSpan
// - `verify.baselineGetDefinitionAtPosition(...)` called getDefinitionAtPosition
// LSP doesn't have two separate commands though. It's unclear how we would model bound spans though.
return parseBaselineGoToDefinitionArgs(callExpression.arguments);
// LSP doesn't have two separate commands though.
// It's unclear how we would model bound spans though.
return parseBaselineGoToDefinitionArgs(func.text, callExpression.arguments);
case "baselineRename":
case "baselineRenameAtRangesWithText":
// `verify.baselineRename...(...)`
Expand Down Expand Up @@ -817,7 +820,20 @@ function parseBaselineDocumentHighlightsArgs(args: readonly ts.Expression[]): [V
}];
}

function parseBaselineGoToDefinitionArgs(args: readonly ts.Expression[]): [VerifyBaselineGoToDefinitionCmd] | undefined {
function parseBaselineGoToDefinitionArgs(
funcName: "baselineGoToDefinition" | "baselineGoToType" | "baselineGetDefinitionAtPosition",
args: readonly ts.Expression[],
): [VerifyBaselineGoToDefinitionCmd] | undefined {
let kind: "verifyBaselineGoToDefinition" | "verifyBaselineGoToType";
switch (funcName) {
case "baselineGoToDefinition":
case "baselineGetDefinitionAtPosition":
kind = "verifyBaselineGoToDefinition";
break;
case "baselineGoToType":
kind = "verifyBaselineGoToType";
break;
}
const newArgs = [];
for (const arg of args) {
let strArg;
Expand All @@ -829,19 +845,19 @@ function parseBaselineGoToDefinitionArgs(args: readonly ts.Expression[]): [Verif
}
else if (arg.getText() === "...test.ranges()") {
return [{
kind: "verifyBaselineGoToDefinition",
kind,
markers: [],
ranges: true,
}];
}
else {
console.error(`Unrecognized argument in verify.baselineGoToDefinition: ${arg.getText()}`);
console.error(`Unrecognized argument in verify.${funcName}: ${arg.getText()}`);
return undefined;
}
}

return [{
kind: "verifyBaselineGoToDefinition",
kind,
markers: newArgs,
}];
}
Expand Down Expand Up @@ -1293,7 +1309,7 @@ interface VerifyBaselineFindAllReferencesCmd {
}

interface VerifyBaselineGoToDefinitionCmd {
kind: "verifyBaselineGoToDefinition";
kind: "verifyBaselineGoToDefinition" | "verifyBaselineGoToType";
markers: string[];
ranges?: boolean;
}
Expand Down Expand Up @@ -1393,11 +1409,20 @@ function generateBaselineDocumentHighlights({ args, preferences }: VerifyBaselin
return `f.VerifyBaselineDocumentHighlights(t, ${preferences}, ${args.join(", ")})`;
}

function generateBaselineGoToDefinition({ markers, ranges }: VerifyBaselineGoToDefinitionCmd): string {
function generateBaselineGoToDefinition({ markers, ranges, kind }: VerifyBaselineGoToDefinitionCmd): string {
let goFunc;
switch (kind) {
case "verifyBaselineGoToDefinition":
goFunc = "VerifyBaselineGoToDefinition";
break;
case "verifyBaselineGoToType":
goFunc = "VerifyBaselineGoToTypeDefinition";
break;
}
if (ranges || markers.length === 0) {
return `f.VerifyBaselineGoToDefinition(t)`;
return `f.${goFunc}(t)`;
}
return `f.VerifyBaselineGoToDefinition(t, ${markers.join(", ")})`;
return `f.${goFunc}(t, ${markers.join(", ")})`;
}

function generateGoToCommand({ funcName, args }: GoToCmd): string {
Expand Down Expand Up @@ -1436,6 +1461,7 @@ function generateCmd(cmd: Cmd): string {
case "verifyBaselineDocumentHighlights":
return generateBaselineDocumentHighlights(cmd);
case "verifyBaselineGoToDefinition":
case "verifyBaselineGoToType":
return generateBaselineGoToDefinition(cmd);
case "verifyBaselineQuickInfo":
// Quick Info -> Hover
Expand Down
1 change: 1 addition & 0 deletions internal/fourslash/_scripts/failingTests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ TestJsDocPropertyDescription6
TestJsDocPropertyDescription7
TestJsDocPropertyDescription8
TestJsDocPropertyDescription9
TestJsDocServices
TestJsDocTagsWithHyphen
TestJsQuickInfoGenerallyAcceptableSize
TestJsRequireQuickInfo
Expand Down
49 changes: 49 additions & 0 deletions internal/fourslash/fourslash.go
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,55 @@ func (f *FourslashTest) VerifyBaselineGoToDefinition(
}
}

func (f *FourslashTest) VerifyBaselineGoToTypeDefinition(
t *testing.T,
markers ...string,
) {
referenceLocations := f.lookupMarkersOrGetRanges(t, markers)

for _, markerOrRange := range referenceLocations {
// worker in `baselineEachMarkerOrRange`
f.GoToMarkerOrRange(t, markerOrRange)

params := &lsproto.TypeDefinitionParams{
TextDocument: lsproto.TextDocumentIdentifier{
Uri: ls.FileNameToDocumentURI(f.activeFilename),
},
Position: f.currentCaretPosition,
}

resMsg, result, resultOk := sendRequest(t, f, lsproto.TextDocumentTypeDefinitionInfo, params)
if resMsg == nil {
if f.lastKnownMarkerName == nil {
t.Fatalf("Nil response received for type definition request at pos %v", f.currentCaretPosition)
} else {
t.Fatalf("Nil response received for type definition request at marker '%s'", *f.lastKnownMarkerName)
}
}
if !resultOk {
if f.lastKnownMarkerName == nil {
t.Fatalf("Unexpected type definition response type at pos %v: %T", f.currentCaretPosition, resMsg.AsResponse().Result)
} else {
t.Fatalf("Unexpected type definition response type at marker '%s': %T", *f.lastKnownMarkerName, resMsg.AsResponse().Result)
}
}

var resultAsLocations []lsproto.Location
if result.Locations != nil {
resultAsLocations = *result.Locations
} else if result.Location != nil {
resultAsLocations = []lsproto.Location{*result.Location}
} else if result.DefinitionLinks != nil {
t.Fatalf("Unexpected type definition response type at marker '%s': %T", *f.lastKnownMarkerName, result.DefinitionLinks)
}

f.addResultToBaseline(t, "goToType", f.getBaselineForLocationsWithFileContents(resultAsLocations, baselineFourslashLocationsOptions{
marker: markerOrRange,
markerName: "/*GOTO TYPE*/",
}))
}
}

func (f *FourslashTest) VerifyBaselineHover(t *testing.T) {
markersAndItems := core.MapFiltered(f.Markers(), func(marker *Marker) (markerAndItem[*lsproto.Hover], bool) {
if marker.Name == nil {
Expand Down
27 changes: 27 additions & 0 deletions internal/fourslash/tests/gen/goToTypeDefinition2_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package fourslash_test

import (
"testing"

"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)

func TestGoToTypeDefinition2(t *testing.T) {
t.Parallel()

defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: goToTypeDefinition2_Definition.ts
interface /*definition*/I1 {
p;
}
type propertyType = I1;
interface I2 {
property: propertyType;
}
// @Filename: goToTypeDefinition2_Consumption.ts
var i2: I2;
i2.prop/*reference*/erty;`
f := fourslash.NewFourslash(t, nil /*capabilities*/, content)
f.VerifyBaselineGoToTypeDefinition(t, "reference")
}
18 changes: 18 additions & 0 deletions internal/fourslash/tests/gen/goToTypeDefinition3_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package fourslash_test

import (
"testing"

"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)

func TestGoToTypeDefinition3(t *testing.T) {
t.Parallel()

defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `type /*definition*/T = string;
const x: /*reference*/T;`
f := fourslash.NewFourslash(t, nil /*capabilities*/, content)
f.VerifyBaselineGoToTypeDefinition(t, "reference")
}
23 changes: 23 additions & 0 deletions internal/fourslash/tests/gen/goToTypeDefinition4_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package fourslash_test

import (
"testing"

"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)

func TestGoToTypeDefinition4(t *testing.T) {
t.Parallel()

defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: foo.ts
export type /*def0*/T = string;
export const /*def1*/T = "";
// @Filename: bar.ts
import { T } from "./foo";
let x: [|/*reference*/T|];`
f := fourslash.NewFourslash(t, nil /*capabilities*/, content)
f.VerifyBaselineGoToTypeDefinition(t, "reference")
f.VerifyBaselineGoToDefinition(t, "reference")
}
20 changes: 20 additions & 0 deletions internal/fourslash/tests/gen/goToTypeDefinition5_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package fourslash_test

import (
"testing"

"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)

func TestGoToTypeDefinition5(t *testing.T) {
t.Parallel()

defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: foo.ts
let Foo: /*definition*/unresolved;
type Foo = { x: string };
/*reference*/Foo;`
f := fourslash.NewFourslash(t, nil /*capabilities*/, content)
f.VerifyBaselineGoToTypeDefinition(t, "reference")
}
28 changes: 28 additions & 0 deletions internal/fourslash/tests/gen/goToTypeDefinitionAliases_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package fourslash_test

import (
"testing"

"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)

func TestGoToTypeDefinitionAliases(t *testing.T) {
t.Parallel()

defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: goToTypeDefinitioAliases_module1.ts
interface /*definition*/I {
p;
}
export {I as I2};
// @Filename: goToTypeDefinitioAliases_module2.ts
import {I2 as I3} from "./goToTypeDefinitioAliases_module1";
var v1: I3;
export {v1 as v2};
// @Filename: goToTypeDefinitioAliases_module3.ts
import {/*reference1*/v2 as v3} from "./goToTypeDefinitioAliases_module2";
/*reference2*/v3;`
f := fourslash.NewFourslash(t, nil /*capabilities*/, content)
f.VerifyBaselineGoToTypeDefinition(t, "reference1", "reference2")
}
23 changes: 23 additions & 0 deletions internal/fourslash/tests/gen/goToTypeDefinitionEnumMembers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package fourslash_test

import (
"testing"

"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)

func TestGoToTypeDefinitionEnumMembers(t *testing.T) {
t.Parallel()

defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `enum E {
value1,
/*definition*/value2
}
var x = E.value2;

/*reference*/x;`
f := fourslash.NewFourslash(t, nil /*capabilities*/, content)
f.VerifyBaselineGoToTypeDefinition(t, "reference")
}
24 changes: 24 additions & 0 deletions internal/fourslash/tests/gen/goToTypeDefinitionImportMeta_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package fourslash_test

import (
"testing"

"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)

func TestGoToTypeDefinitionImportMeta(t *testing.T) {
t.Parallel()

defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @module: esnext
// @Filename: foo.ts
/// <reference no-default-lib="true"/>
/// <reference path='./bar.d.ts' />
import.me/*reference*/ta;
//@Filename: bar.d.ts
interface /*definition*/ImportMeta {
}`
f := fourslash.NewFourslash(t, nil /*capabilities*/, content)
f.VerifyBaselineGoToTypeDefinition(t, "reference")
}
33 changes: 33 additions & 0 deletions internal/fourslash/tests/gen/goToTypeDefinitionModifiers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package fourslash_test

import (
"testing"

"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)

func TestGoToTypeDefinitionModifiers(t *testing.T) {
t.Parallel()

defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /a.ts
/*export*/export class A/*A*/ {

/*private*/private z/*z*/: string;

/*private2*/private y/*y*/: A;

/*readonly*/readonly x/*x*/: string;

/*async*/async a/*a*/() { }

/*override*/override b/*b*/() {}

/*public1*/public/*public2*/ as/*multipleModifiers*/ync c/*c*/() { }
}

exp/*exportFunction*/ort function foo/*foo*/() { }`
f := fourslash.NewFourslash(t, nil /*capabilities*/, content)
f.VerifyBaselineGoToTypeDefinition(t, "export", "A", "private", "z", "private2", "y", "readonly", "x", "async", "a", "override", "b", "public1", "public2", "multipleModifiers", "c", "exportFunction", "foo")
}
24 changes: 24 additions & 0 deletions internal/fourslash/tests/gen/goToTypeDefinitionModule_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package fourslash_test

import (
"testing"

"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)

func TestGoToTypeDefinitionModule(t *testing.T) {
t.Parallel()

defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: module1.ts
module /*definition*/M {
export var p;
}
var m: typeof M;
// @Filename: module3.ts
/*reference1*/M;
/*reference2*/m;`
f := fourslash.NewFourslash(t, nil /*capabilities*/, content)
f.VerifyBaselineGoToTypeDefinition(t, "reference1", "reference2")
}
Loading