Skip to content
Open
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
11 changes: 1 addition & 10 deletions internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -19683,22 +19683,13 @@ func (c *Checker) getAnnotatedAccessorTypeNode(accessor *ast.Node) *ast.Node {
}

func getEffectiveSetAccessorTypeAnnotationNode(node *ast.Node) *ast.Node {
param := getSetAccessorValueParameter(node)
param := GetSetAccessorValueParameter(node)
if param != nil {
return param.Type()
}
return nil
}

func getSetAccessorValueParameter(accessor *ast.Node) *ast.Node {
parameters := accessor.Parameters()
if len(parameters) > 0 {
hasThis := len(parameters) == 2 && ast.IsThisParameter(parameters[0])
return parameters[core.IfElse(hasThis, 1, 0)]
}
return nil
}

func (c *Checker) getReturnTypeFromBody(fn *ast.Node, checkMode CheckMode) *Type {
body := fn.Body()
if body == nil {
Expand Down
19 changes: 19 additions & 0 deletions internal/checker/exports.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,21 @@ func (c *Checker) GetUnionType(types []*Type) *Type {
return c.getUnionType(types)
}

func (c *Checker) GetNameTypeOfSymbol(symbol *ast.Symbol) *Type {
if !c.valueSymbolLinks.Has(symbol) {
return nil
}
return c.valueSymbolLinks.TryGet(symbol).nameType
}

func IsTypeUsableAsPropertyName(t *Type) bool {
return isTypeUsableAsPropertyName(t)
}

func GetPropertyNameFromType(t *Type) string {
return getPropertyNameFromType(t)
}

func (c *Checker) GetGlobalSymbol(name string, meaning ast.SymbolFlags, diagnostic *diagnostics.Message) *ast.Symbol {
return c.getGlobalSymbol(name, meaning, diagnostic)
}
Expand Down Expand Up @@ -263,6 +278,10 @@ func (c *Checker) GetTypeArguments(t *Type) []*Type {
return c.getTypeArguments(t)
}

func (c *Checker) GetIndexInfoOfType(t *Type, keyType *Type) *IndexInfo {
return c.getIndexInfoOfType(t, keyType)
}

func (c *Checker) GetIndexInfosOfType(t *Type) []*IndexInfo {
return c.getIndexInfosOfType(t)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/checker/grammarchecks.go
Original file line number Diff line number Diff line change
Expand Up @@ -1337,7 +1337,7 @@ func (c *Checker) checkGrammarAccessor(accessor *ast.AccessorDeclaration) bool {
return c.grammarErrorOnNode(accessor.Name(), diagnostics.A_set_accessor_cannot_have_a_return_type_annotation)
}

parameterNode := getSetAccessorValueParameter(accessor)
parameterNode := GetSetAccessorValueParameter(accessor)
if parameterNode == nil {
panic("Return value does not match parameter count assertion.")
}
Expand Down
4 changes: 2 additions & 2 deletions internal/checker/nodebuilderimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -2544,7 +2544,7 @@ func (b *NodeBuilderImpl) createTypeNodesFromResolvedType(resolvedType *Structur
if b.checkTruncationLength() {
if b.ctx.flags&nodebuilder.FlagsNoTruncation != 0 {
elem := b.f.NewNotEmittedTypeElement()
return b.f.NewNodeList([]*ast.TypeElement{b.e.AddSyntheticLeadingComment(elem, ast.KindMultiLineCommentTrivia, "elided", false /*hasTrailingNewLine*/)})
return b.f.NewNodeList([]*ast.TypeElement{b.e.AddSyntheticTrailingComment(elem, ast.KindMultiLineCommentTrivia, "elided", false /*hasTrailingNewLine*/)})
}
return b.f.NewNodeList([]*ast.Node{b.f.NewPropertySignatureDeclaration(nil, b.f.NewIdentifier("..."), nil, nil, nil)})
}
Expand Down Expand Up @@ -2586,7 +2586,7 @@ func (b *NodeBuilderImpl) createTypeNodesFromResolvedType(resolvedType *Structur
}
if b.checkTruncationLength() && (i+2 < len(properties)-1) {
if b.ctx.flags&nodebuilder.FlagsNoTruncation != 0 {
typeElements[len(typeElements)-1] = b.e.AddSyntheticLeadingComment(typeElements[len(typeElements)-1], ast.KindMultiLineCommentTrivia, fmt.Sprintf("... %d more elided ...", len(properties)-i), false /*hasTrailingNewLine*/)
typeElements[len(typeElements)-1] = b.e.AddSyntheticTrailingComment(typeElements[len(typeElements)-1], ast.KindMultiLineCommentTrivia, fmt.Sprintf("... %d more elided ...", len(properties)-i), false /*hasTrailingNewLine*/)
} else {
text := fmt.Sprintf("... %d more ...", len(properties)-i)
typeElements = append(typeElements, b.f.NewPropertySignatureDeclaration(nil, b.f.NewIdentifier(text), nil, nil, nil))
Expand Down
4 changes: 4 additions & 0 deletions internal/checker/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,10 @@ func (s *Signature) HasRestParameter() bool {
return s.flags&SignatureFlagsHasRestParameter != 0
}

func (s *Signature) MinArgumentCount() int {
return int(s.minArgumentCount)
}

type CompositeSignature struct {
isUnion bool // True for union, false for intersection
signatures []*Signature // Individual signatures
Expand Down
9 changes: 9 additions & 0 deletions internal/checker/utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -1810,3 +1810,12 @@ func CreateModeMismatchDetails(program Program, file *ast.SourceFile) Diagnostic
Args: nil,
}
}

func GetSetAccessorValueParameter(accessor *ast.Node) *ast.Node {
parameters := accessor.Parameters()
if len(parameters) > 0 {
hasThis := len(parameters) == 2 && ast.IsThisParameter(parameters[0])
return parameters[core.IfElse(hasThis, 1, 0)]
}
return nil
}
52 changes: 49 additions & 3 deletions internal/fourslash/_scripts/convertFourslash.mts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const IMPORT_UTIL = `. "github.com/microsoft/typescript-go/internal/fourslash/te
const allowedCodeFixIds = new Set([
"fixMissingImport",
"fixMissingTypeAnnotationOnExports",
"fixClassIncorrectlyImplementsInterface",
]);

// File name prefixes for code fix tests that are allowed even without a fixId.
Expand All @@ -42,6 +43,7 @@ const allowedCodeFixDescriptionPrefixes = [
"Import ",
"Add import from ",
"Update import from ",
"Implement interface '",
"Change 'import' to 'import type'",
"Add annotation of type",
"Add return type",
Expand Down Expand Up @@ -1826,9 +1828,11 @@ function parseCodeFixArgs(args: readonly ts.Expression[]): [VerifyCodeFixCmd] {

const sourceFile = args[0].getSourceFile();
let description = "";
let newFileContent = "";
let newFileContent: string | undefined;
let newRangeContent: string | undefined;
let index = 0;
let applyChanges = false;
let preferences = "nil /*preferences*/";

for (const prop of obj.properties) {
const name = getPropertyName(prop);
Expand All @@ -1852,6 +1856,11 @@ function parseCodeFixArgs(args: readonly ts.Expression[]): [VerifyCodeFixCmd] {
if (str) newFileContent = str.text;
break;
}
case "newRangeContent": {
const str = getStringLiteralLike(prop.initializer);
if (str) newRangeContent = str.text;
break;
}
case "index": {
const num = getNumericLiteral(prop.initializer);
if (num) index = parseInt(num.text);
Expand All @@ -1863,15 +1872,25 @@ function parseCodeFixArgs(args: readonly ts.Expression[]): [VerifyCodeFixCmd] {
}
break;
}
case "preferences": {
const prefs = getObjectLiteralExpression(prop.initializer);
if (!prefs) {
throw new Error(`Expected object literal for preferences in verify.codeFix, got ${prop.initializer.getText()}`);
}
preferences = parseUserPreferences(prefs);
break;
}
}
}

return [{
kind: "verifyCodeFix",
description,
newFileContent,
newRangeContent,
index,
applyChanges,
preferences,
}];
}

Expand Down Expand Up @@ -3647,9 +3666,11 @@ interface VerifyErrorExistsBeforeMarkerCmd {
interface VerifyCodeFixCmd {
kind: "verifyCodeFix";
description: string;
newFileContent: string;
newFileContent?: string;
newRangeContent?: string;
index: number;
applyChanges: boolean;
preferences: string;
}

interface VerifyCodeFixAvailableCmd {
Expand Down Expand Up @@ -4091,10 +4112,17 @@ function generateCmd(cmd: Cmd, imports: Set<string>): string {
case "verifyCodeFix":
return `f.VerifyCodeFix(t, fourslash.VerifyCodeFixOptions{
Description: ${getGoStringLiteral(cmd.description)},
NewFileContent: ${getGoMultiLineStringLiteral(cmd.newFileContent)},
${
cmd.newRangeContent !== undefined
? `\tNewRangeContent: ${getGoMultiLineStringLiteral(cmd.newRangeContent)},`
: `\tNewFileContent: ${getGoMultiLineStringLiteral(cmd.newFileContent ?? "")},`
}
Index: ${cmd.index},${
cmd.applyChanges ? `
ApplyChanges: true,` : ``
}${
cmd.preferences !== "nil /*preferences*/" ? `
UserPreferences: ${cmd.preferences},` : ``
}
})`;
case "verifyCodeFixAvailable":
Expand Down Expand Up @@ -4236,6 +4264,24 @@ function resolveDescriptionExpression(expr: ts.Expression, sourceFile: ts.Source
const str = getStringLiteralLike(expr);
if (str) return str.text;

// [ts.Diagnostics.Foo.message, "arg0", "arg1", ...]
if (ts.isArrayLiteralExpression(expr) && expr.elements.length > 0) {
const [diagnostic] = expr.elements;
const template = resolveDescriptionExpression(diagnostic, sourceFile);
if (template) {
let message = template;
for (let i = 1; i < expr.elements.length; i++) {
const arg = resolveDescriptionExpression(expr.elements[i], sourceFile);
if (arg === undefined) {
return undefined;
}
message = message.replaceAll(`{${i - 1}}`, arg);
}
return message;
}
return undefined;
}

// ts.Diagnostics.Foo_bar.message
if (ts.isPropertyAccessExpression(expr) && expr.name.text === "message") {
const inner = expr.expression;
Expand Down
2 changes: 1 addition & 1 deletion internal/fourslash/_scripts/crashingTests.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@

TestAutoImportFileExcludePatterns12
13 changes: 13 additions & 0 deletions internal/fourslash/_scripts/failingTests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ TestAutoImportCompletionExportListAugmentation3
TestAutoImportCompletionExportListAugmentation4
TestAutoImportCrossProject_symlinks_stripSrc
TestAutoImportCrossProject_symlinks_toDist
TestAutoImportFileExcludePatterns10
TestAutoImportFileExcludePatterns11
TestAutoImportFileExcludePatterns12
TestAutoImportFileExcludePatterns3
TestAutoImportFileExcludePatterns5
TestAutoImportFileExcludePatterns6
TestAutoImportFileExcludePatterns9
TestAutoImportJsDocImport1
TestAutoImportModuleNone2
TestAutoImportNodeModuleSymlinkRenamed
Expand All @@ -31,6 +37,10 @@ TestAutoImportVerbatimTypeOnly1
TestCalledUnionsOfDissimilarTyeshaveGoodDisplay
TestCloduleTypeOf1
TestCodeCompletionEscaping
TestCodeFixClassImplementInterfaceAutoImports
TestCodeFixClassImplementInterfaceAutoImports_typeOnly
TestCodeFixClassImplementInterfaceAutoImportsReExports
TestCodeFixClassImplementInterfaceNoTruncation
TestCodeFixMissingTypeAnnotationOnExports11
TestCodeFixMissingTypeAnnotationOnExports16
TestCodeFixMissingTypeAnnotationOnExports23_heritage_formatting
Expand Down Expand Up @@ -215,6 +225,8 @@ TestImportCompletionsPackageJsonImportsPatternRootWildcard
TestImportFixesGlobalTypingsCache
TestImportMetaCompletionDetails
TestImportNameCodeFix_externalNonRelative1
TestImportNameCodeFix_jsx4
TestImportNameCodeFix_jsx6
TestImportNameCodeFix_noDestructureNonObjectLiteral
TestImportNameCodeFix_order2
TestImportNameCodeFix_preferBaseUrl
Expand Down Expand Up @@ -295,6 +307,7 @@ TestNoQuickInfoInWhitespace
TestOverloadQuickInfo
TestProtoVarVisibleWithOuterScopeUnderscoreProto
TestQualifyModuleTypeNames
TestQuickfixImplementInterfaceUnreachableTypeUsesRelativeImport
TestQuickInfo_notInsideComment
TestQuickinfo01
TestQuickInfoBindingPatternInJsdocNoCrash1
Expand Down
Loading
Loading