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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion microsoft/typescript-go
Submodule typescript-go updated 698 files
2 changes: 1 addition & 1 deletion pkg/bundled/embed.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func (vfs *wrappedFS) walkDir(rest string, walkFn vfs.WalkDirFunc) error {
return err
}
if entry.IsDir() {
if err := vfs.walkDir(name, walkFn); err != nil {
if err := vfs.walkDir(strings.TrimPrefix(name, "/"), walkFn); err != nil {
return err
}
}
Expand Down
23 changes: 12 additions & 11 deletions pkg/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -4271,7 +4271,7 @@ func (c *Checker) checkClassLikeDeclaration(node *ast.Node) {
}
c.checkIndexConstraints(classType, symbol, false /*isStaticIndex*/)
c.checkIndexConstraints(staticType, symbol, true /*isStaticIndex*/)
c.checkTypeForDuplicateIndexSignatures(node)
c.checkClassOrInterfaceForDuplicateIndexSignatures(node)
c.checkPropertyInitialization(node)
}

Expand Down Expand Up @@ -4758,14 +4758,15 @@ func (c *Checker) checkIndexConstraintForIndexSignature(t *Type, checkInfo *Inde
}
}

func (c *Checker) checkTypeForDuplicateIndexSignatures(node *ast.Node) {
if ast.IsInterfaceDeclaration(node) {
// in case of merging interface declaration it is possible that we'll enter this check procedure several times for every declaration
// to prevent this run check only for the first declaration of a given kind
if symbol := c.getSymbolOfDeclaration(node); len(symbol.Declarations) != 0 && symbol.Declarations[0] != node {
return
}
func (c *Checker) checkClassOrInterfaceForDuplicateIndexSignatures(node *ast.Node) {
// Only check the type once
if links := c.declaredTypeLinks.Get(c.getSymbolOfDeclaration(node)); !links.indexSignaturesChecked {
links.indexSignaturesChecked = true
c.checkTypeForDuplicateIndexSignatures(node)
}
}

func (c *Checker) checkTypeForDuplicateIndexSignatures(node *ast.Node) {
// TypeScript 1.0 spec (April 2014)
// 3.7.4: An object type can contain at most one string index signature and one numeric index signature.
// 8.5: A class declaration can have at most one string index member declaration and one numeric index member declaration
Expand Down Expand Up @@ -4865,8 +4866,8 @@ func (c *Checker) checkInterfaceDeclaration(node *ast.Node) {
symbol := c.getSymbolOfDeclaration(node)
c.checkTypeParameterListsIdentical(symbol)
// Only check this symbol once
firstInterfaceDecl := ast.GetDeclarationOfKind(symbol, ast.KindInterfaceDeclaration)
if node == firstInterfaceDecl {
if links := c.declaredTypeLinks.Get(symbol); !links.interfaceChecked {
links.interfaceChecked = true
t := c.getDeclaredTypeOfSymbol(symbol)
typeWithThis := c.getTypeWithThisArgument(t, nil, false)
// run subsequent checks only if first set succeeded
Expand All @@ -4886,7 +4887,7 @@ func (c *Checker) checkInterfaceDeclaration(node *ast.Node) {
c.checkTypeReferenceNode(heritageElement)
}
c.checkSourceElements(node.Members())
c.checkTypeForDuplicateIndexSignatures(node)
c.checkClassOrInterfaceForDuplicateIndexSignatures(node)
c.registerForUnusedIdentifiersCheck(node)
}

Expand Down
6 changes: 4 additions & 2 deletions pkg/checker/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,10 @@ type TypeAliasLinks struct {
// Links for declared types (type parameters, class types, interface types, enums)

type DeclaredTypeLinks struct {
declaredType *Type
typeParametersChecked bool
declaredType *Type
interfaceChecked bool
indexSignaturesChecked bool
typeParametersChecked bool
}

// Links for switch clauses
Expand Down
23 changes: 17 additions & 6 deletions pkg/fourslash/_scripts/convertFourslash.mts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ function parseTypeScriptFiles(failingTests: Set<string>, manualTests: Set<string
else if (file.endsWith(".ts") && !manualTests.has(file.slice(0, -3))) {
const content = fs.readFileSync(filePath, "utf-8");
const test = parseFileContent(file, content);
const isServer = filePath.split(path.sep).includes("server");
if (test) {
const testContent = generateGoTest(failingTests, test);
const testContent = generateGoTest(failingTests, test, isServer);
const testPath = path.join(outputDir, `${test.name}_test.go`);
fs.writeFileSync(testPath, testContent, "utf-8");
}
Expand Down Expand Up @@ -198,6 +199,7 @@ function parseFourslashStatement(statement: ts.Statement): Cmd[] | undefined {
case "baselineGoToDefinition":
case "baselineGetDefinitionAtPosition":
case "baselineGoToType":
case "baselineGoToImplementation":
// Both `baselineGoToDefinition` and `baselineGetDefinitionAtPosition` take the same
// arguments, but differ in that...
// - `verify.baselineGoToDefinition(...)` called getDefinitionAndBoundSpan
Expand Down Expand Up @@ -1130,14 +1132,14 @@ function parseBaselineDocumentHighlightsArgs(args: readonly ts.Expression[]): [V
}

function parseBaselineGoToDefinitionArgs(
funcName: "baselineGoToDefinition" | "baselineGoToType" | "baselineGetDefinitionAtPosition",
funcName: "baselineGoToDefinition" | "baselineGoToType" | "baselineGetDefinitionAtPosition" | "baselineGoToImplementation",
args: readonly ts.Expression[],
): [VerifyBaselineGoToDefinitionCmd] | undefined {
let boundSpan: true | undefined;
if (funcName === "baselineGoToDefinition") {
boundSpan = true;
}
let kind: "verifyBaselineGoToDefinition" | "verifyBaselineGoToType";
let kind: "verifyBaselineGoToDefinition" | "verifyBaselineGoToType" | "verifyBaselineGoToImplementation";
switch (funcName) {
case "baselineGoToDefinition":
case "baselineGetDefinitionAtPosition":
Expand All @@ -1146,6 +1148,9 @@ function parseBaselineGoToDefinitionArgs(
case "baselineGoToType":
kind = "verifyBaselineGoToType";
break;
case "baselineGoToImplementation":
kind = "verifyBaselineGoToImplementation";
break;
}
const newArgs = [];
for (const arg of args) {
Expand Down Expand Up @@ -1824,7 +1829,7 @@ interface VerifyBaselineFindAllReferencesCmd {
}

interface VerifyBaselineGoToDefinitionCmd {
kind: "verifyBaselineGoToDefinition" | "verifyBaselineGoToType";
kind: "verifyBaselineGoToDefinition" | "verifyBaselineGoToType" | "verifyBaselineGoToImplementation";
markers: string[];
boundSpan?: true;
ranges?: boolean;
Expand Down Expand Up @@ -1984,6 +1989,11 @@ function generateBaselineGoToDefinition({ markers, ranges, kind, boundSpan }: Ve
return `f.VerifyBaselineGoToTypeDefinition(t)`;
}
return `f.VerifyBaselineGoToTypeDefinition(t, ${markers.join(", ")})`;
case "verifyBaselineGoToImplementation":
if (ranges || markers.length === 0) {
return `f.VerifyBaselineGoToImplementation(t)`;
}
return `f.VerifyBaselineGoToImplementation(t, ${markers.join(", ")})`;
}
}

Expand Down Expand Up @@ -2038,6 +2048,7 @@ function generateCmd(cmd: Cmd): string {
return generateBaselineDocumentHighlights(cmd);
case "verifyBaselineGoToDefinition":
case "verifyBaselineGoToType":
case "verifyBaselineGoToImplementation":
return generateBaselineGoToDefinition(cmd);
case "verifyBaselineQuickInfo":
// Quick Info -> Hover
Expand Down Expand Up @@ -2083,7 +2094,7 @@ interface GoTest {
commands: Cmd[];
}

function generateGoTest(failingTests: Set<string>, test: GoTest): string {
function generateGoTest(failingTests: Set<string>, test: GoTest, isServer: boolean): string {
const testName = (test.name[0].toUpperCase() + test.name.substring(1)).replaceAll("-", "_").replaceAll(/[^a-zA-Z0-9_]/g, "");
const content = test.content;
const commands = test.commands.map(cmd => generateCmd(cmd)).join("\n");
Expand Down Expand Up @@ -2119,7 +2130,7 @@ func Test${testName}(t *testing.T) {
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = ${content}
f := fourslash.NewFourslash(t, nil /*capabilities*/, content)
${commands}
${isServer ? `f.MarkTestAsStradaServer()\n` : ""}${commands}
}`;
return template;
}
Expand Down
Loading