From 4e1531c83176a6ea86615b5dfe8edb11e6e9fdcb Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 3 Nov 2025 16:27:30 -0800 Subject: [PATCH 01/48] Wip --- internal/ls/codeactions.go | 196 +++++++++++++++++++++++++++++++++++++ internal/ls/utilities.go | 16 +++ internal/lsp/server.go | 12 +++ 3 files changed, 224 insertions(+) create mode 100644 internal/ls/codeactions.go diff --git a/internal/ls/codeactions.go b/internal/ls/codeactions.go new file mode 100644 index 0000000000..329d60a7ab --- /dev/null +++ b/internal/ls/codeactions.go @@ -0,0 +1,196 @@ +package ls + +import ( + "context" + "fmt" + + "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/diagnostics" + "github.com/microsoft/typescript-go/internal/lsp/lsproto" +) + +// Import-related diagnostic codes that can be fixed with auto-import +var importFixDiagnosticCodes = map[int32]struct{}{ + diagnostics.Cannot_find_name_0.Code(): {}, + diagnostics.Cannot_find_name_0_Did_you_mean_1.Code(): {}, + diagnostics.Cannot_find_namespace_0.Code(): {}, + diagnostics.Module_0_has_no_exported_member_1.Code(): {}, + diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations.Code(): {}, +} + +// ProvideCodeActions returns code actions for the given range and context +func (l *LanguageService) ProvideCodeActions(ctx context.Context, params *lsproto.CodeActionParams) (lsproto.CodeActionResponse, error) { + program, file := l.getProgramAndFile(params.TextDocument.Uri) + + var actions []lsproto.CommandOrCodeAction + + // Process diagnostics in the context to generate quick fixes + if params.Context != nil && params.Context.Diagnostics != nil { + for _, diag := range params.Context.Diagnostics { + // Check if this is an import-related diagnostic + if diag.Code.Integer != nil { + if _, isImportDiag := importFixDiagnosticCodes[*diag.Code.Integer]; isImportDiag { + importActions := l.getImportCodeActionsForDiagnostic(ctx, program, file, diag, params) + actions = append(actions, importActions...) + } + } + } + } + + if len(actions) == 0 { + return lsproto.CommandOrCodeActionArrayOrNull{}, nil + } + + return lsproto.CommandOrCodeActionArrayOrNull{CommandOrCodeActionArray: &actions}, nil +} + +// getImportCodeActionsForDiagnostic generates auto-import code actions for a diagnostic +func (l *LanguageService) getImportCodeActionsForDiagnostic( + ctx context.Context, + program *compiler.Program, + file *ast.SourceFile, + diag *lsproto.Diagnostic, + params *lsproto.CodeActionParams, +) []lsproto.CommandOrCodeAction { + // Get the type checker + ch, done := program.GetTypeCheckerForFile(ctx, file) + if done != nil { + defer done() + } + + // Get the position from the diagnostic + position := l.converters.LineAndCharacterToPosition(file, diag.Range.Start) + + // Get the token at the diagnostic position + token := astnav.GetTokenAtPosition(file, int(position)) + if token == nil { + return nil + } + + // Token should be an identifier + if !ast.IsIdentifier(token) { + return nil + } + + // Extract the symbol name from the identifier + symbolName := token.Text() + if symbolName == "" { + return nil + } + + // Get the meaning from the token location to filter exports properly + meaning := getMeaningFromLocation(token) + + // Search for all exports matching this symbol name + exportInfos := l.searchExportInfosForCodeAction(ctx, ch, file, symbolName, meaning) + if len(exportInfos) == 0 { + return nil + } + + // Get all import fixes for the symbol, which will be sorted by preference + isValidTypeOnlyUseSite := ast.IsValidTypeOnlyAliasUseSite(token) + useRequire := getShouldUseRequire(file, program) + _, fixes := l.getImportFixes(ch, exportInfos, &diag.Range.Start, &isValidTypeOnlyUseSite, &useRequire, file, false) + + var actions []lsproto.CommandOrCodeAction + + // Limit to top 3 import suggestions to avoid overwhelming the user + maxActions := 3 + for i, fix := range fixes { + if i >= maxActions { + break + } + + // Create the code action using the fix + internalAction := l.codeActionForFix(ctx, file, symbolName, fix, false) + + // Convert internal code action to LSP CodeAction + if len(internalAction.changes) > 0 { + kind := lsproto.CodeActionKindQuickFix + title := fmt.Sprintf("Import %s from \"%s\"", symbolName, fix.moduleSpecifier) + + changes := map[lsproto.DocumentUri][]*lsproto.TextEdit{ + params.TextDocument.Uri: internalAction.changes, + } + diagnostics := []*lsproto.Diagnostic{diag} + codeAction := &lsproto.CodeAction{ + Title: title, + Kind: &kind, + Edit: &lsproto.WorkspaceEdit{ + Changes: &changes, + }, + Diagnostics: &diagnostics, + } + actions = append(actions, lsproto.CommandOrCodeAction{CodeAction: codeAction}) + } + } + + return actions +} + +// searchExportInfosForCodeAction searches for exports that match the given symbol name +// This follows the same pattern as TypeScript's getExportInfos in importFixes.ts +func (l *LanguageService) searchExportInfosForCodeAction( + ctx context.Context, + ch *checker.Checker, + importingFile *ast.SourceFile, + symbolName string, + meaning ast.SemanticMeaning, +) []*SymbolExportInfo { + var results []*SymbolExportInfo + moduleCount := 0 + + // Iterate through all available modules to find exports matching the symbol name + forEachExternalModuleToImportFrom( + ch, + l.GetProgram(), + func(moduleSymbol *ast.Symbol, moduleFile *ast.SourceFile, ch *checker.Checker, isFromPackageJson bool) { + if moduleCount = moduleCount + 1; moduleCount%100 == 0 && ctx.Err() != nil { + return + } + + moduleFileName := "" + if moduleFile != nil { + moduleFileName = moduleFile.FileName() + } + + // Check if the module has an export with the exact symbol name + exportedSymbol := ch.TryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol) + if exportedSymbol != nil && isImportableSymbol(exportedSymbol, ch) { + // Filter by semantic meaning to match what the token location expects + if symbolFlagsHaveMeaning(exportedSymbol.Flags, meaning) { + results = append(results, &SymbolExportInfo{ + symbol: exportedSymbol, + moduleSymbol: moduleSymbol, + moduleFileName: moduleFileName, + exportKind: ExportKindNamed, + targetFlags: ch.SkipAlias(exportedSymbol).Flags, + isFromPackageJson: isFromPackageJson, + }) + } + } + + // Also check default exports + defaultInfo := getDefaultLikeExportInfo(moduleSymbol, ch) + if defaultInfo != nil && isImportableSymbol(defaultInfo.exportingModuleSymbol, ch) { + // Check if the default export's name matches and has the right meaning + if defaultInfo.exportingModuleSymbol.Name == symbolName && + symbolFlagsHaveMeaning(defaultInfo.exportingModuleSymbol.Flags, meaning) { + results = append(results, &SymbolExportInfo{ + symbol: defaultInfo.exportingModuleSymbol, + moduleSymbol: moduleSymbol, + moduleFileName: moduleFileName, + exportKind: defaultInfo.exportKind, + targetFlags: ch.SkipAlias(defaultInfo.exportingModuleSymbol).Flags, + isFromPackageJson: isFromPackageJson, + }) + } + } + }, + ) + + return results +} diff --git a/internal/ls/utilities.go b/internal/ls/utilities.go index c46faf93f8..6cefe1ca17 100644 --- a/internal/ls/utilities.go +++ b/internal/ls/utilities.go @@ -1181,6 +1181,22 @@ func getAdjustedLocationForExportDeclaration(node *ast.ExportDeclaration, forRen return nil } +func symbolFlagsHaveMeaning(flags ast.SymbolFlags, meaning ast.SemanticMeaning) bool { + if meaning == ast.SemanticMeaningAll { + return true + } + if meaning&ast.SemanticMeaningValue != 0 { + return flags&ast.SymbolFlagsValue != 0 + } + if meaning&ast.SemanticMeaningType != 0 { + return flags&ast.SymbolFlagsType != 0 + } + if meaning&ast.SemanticMeaningNamespace != 0 { + return flags&ast.SymbolFlagsNamespace != 0 + } + return false +} + func getMeaningFromLocation(node *ast.Node) ast.SemanticMeaning { // todo: check if this function needs to be changed for jsdoc updates node = getAdjustedLocation(node, false /*forRename*/, nil) diff --git a/internal/lsp/server.go b/internal/lsp/server.go index 0c98f83ecd..29037f6c74 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -491,6 +491,7 @@ var handlers = sync.OnceValue(func() handlerMap { registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentDocumentHighlightInfo, (*Server).handleDocumentHighlight) registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentSelectionRangeInfo, (*Server).handleSelectionRange) registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentInlayHintInfo, (*Server).handleInlayHint) + registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentCodeActionInfo, (*Server).handleCodeAction) registerRequestHandler(handlers, lsproto.WorkspaceSymbolInfo, (*Server).handleWorkspaceSymbol) registerRequestHandler(handlers, lsproto.CompletionItemResolveInfo, (*Server).handleCompletionItemResolve) @@ -676,6 +677,13 @@ func (s *Server) handleInitialize(ctx context.Context, params *lsproto.Initializ InlayHintProvider: &lsproto.BooleanOrInlayHintOptionsOrInlayHintRegistrationOptions{ Boolean: ptrTo(true), }, + CodeActionProvider: &lsproto.BooleanOrCodeActionOptions{ + CodeActionOptions: &lsproto.CodeActionOptions{ + CodeActionKinds: &[]lsproto.CodeActionKind{ + lsproto.CodeActionKindQuickFix, + }, + }, + }, }, } @@ -919,6 +927,10 @@ func (s *Server) handleSelectionRange(ctx context.Context, ls *ls.LanguageServic return ls.ProvideSelectionRanges(ctx, params) } +func (s *Server) handleCodeAction(ctx context.Context, ls *ls.LanguageService, params *lsproto.CodeActionParams) (lsproto.CodeActionResponse, error) { + return ls.ProvideCodeActions(ctx, params) +} + func (s *Server) Log(msg ...any) { fmt.Fprintln(s.stderr, msg...) } From 84cef635dc507bb6e528edef9cee3d39c7ca29fe Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 17:09:03 -0800 Subject: [PATCH 02/48] Fix test parser for fourslash difference --- internal/fourslash/_scripts/failingTests.txt | 2 - internal/fourslash/test_parser.go | 5 +- .../tests/gen/tsxCompletion14_test.go | 2 +- .../tests/gen/tsxCompletion15_test.go | 2 +- internal/testrunner/test_case_parser.go | 55 ++++++++++++++++--- 5 files changed, 53 insertions(+), 13 deletions(-) diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt index 29254c11a0..4152b6c5f7 100644 --- a/internal/fourslash/_scripts/failingTests.txt +++ b/internal/fourslash/_scripts/failingTests.txt @@ -516,8 +516,6 @@ TestTripleSlashRefPathCompletionExtensionsAllowJSFalse TestTripleSlashRefPathCompletionExtensionsAllowJSTrue TestTripleSlashRefPathCompletionHiddenFile TestTripleSlashRefPathCompletionRootdirs -TestTsxCompletion14 -TestTsxCompletion15 TestTsxCompletionNonTagLessThan TestTsxQuickInfo1 TestTsxQuickInfo4 diff --git a/internal/fourslash/test_parser.go b/internal/fourslash/test_parser.go index 3215f5619f..147824081b 100644 --- a/internal/fourslash/test_parser.go +++ b/internal/fourslash/test_parser.go @@ -93,10 +93,13 @@ func ParseTestData(t *testing.T, contents string, fileName string) TestData { var markers []*Marker var ranges []*RangeMarker - filesWithMarker, symlinks, _, globalOptions, e := testrunner.ParseTestFilesAndSymlinks( + filesWithMarker, symlinks, _, globalOptions, e := testrunner.ParseTestFilesAndSymlinksWithOptions( contents, fileName, parseFileContent, + testrunner.ParseTestFilesOptions{ + AllowImplicitFirstFile: true, + }, ) if e != nil { t.Fatalf("Error parsing fourslash data: %s", e.Error()) diff --git a/internal/fourslash/tests/gen/tsxCompletion14_test.go b/internal/fourslash/tests/gen/tsxCompletion14_test.go index 364cf42fc3..bf1f8cb687 100644 --- a/internal/fourslash/tests/gen/tsxCompletion14_test.go +++ b/internal/fourslash/tests/gen/tsxCompletion14_test.go @@ -10,7 +10,7 @@ import ( func TestTsxCompletion14(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `//@module: commonjs //@jsx: preserve diff --git a/internal/fourslash/tests/gen/tsxCompletion15_test.go b/internal/fourslash/tests/gen/tsxCompletion15_test.go index 90478f63fd..63de791a39 100644 --- a/internal/fourslash/tests/gen/tsxCompletion15_test.go +++ b/internal/fourslash/tests/gen/tsxCompletion15_test.go @@ -10,7 +10,7 @@ import ( func TestTsxCompletion15(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `//@module: commonjs //@jsx: preserve diff --git a/internal/testrunner/test_case_parser.go b/internal/testrunner/test_case_parser.go index 62fa71de79..42e825809b 100644 --- a/internal/testrunner/test_case_parser.go +++ b/internal/testrunner/test_case_parser.go @@ -107,6 +107,13 @@ func makeUnitsFromTest(code string, fileName string) testCaseContent { } } +type ParseTestFilesOptions struct { + // If true, allows test content to appear before the first @Filename directive. + // In this case, an implicit first file is created using the fileName parameter. + // This matches the behavior of the TypeScript fourslash test harness. + AllowImplicitFirstFile bool +} + // Given a test file containing // @FileName and // @symlink directives, // return an array of named units of code to be added to an existing compiler instance, // along with a map of symlinks and the current directory. @@ -114,6 +121,15 @@ func ParseTestFilesAndSymlinks[T any]( code string, fileName string, parseFile func(filename string, content string, fileOptions map[string]string) (T, error), +) (units []T, symlinks map[string]string, currentDir string, globalOptions map[string]string, e error) { + return ParseTestFilesAndSymlinksWithOptions(code, fileName, parseFile, ParseTestFilesOptions{}) +} + +func ParseTestFilesAndSymlinksWithOptions[T any]( + code string, + fileName string, + parseFile func(filename string, content string, fileOptions map[string]string) (T, error), + options ParseTestFilesOptions, ) (units []T, symlinks map[string]string, currentDir string, globalOptions map[string]string, e error) { // List of all the subfiles we've parsed out var testUnits []T @@ -123,6 +139,11 @@ func ParseTestFilesAndSymlinks[T any]( // Stuff related to the subfile we're parsing var currentFileContent strings.Builder var currentFileName string + if options.AllowImplicitFirstFile { + // For fourslash tests, initialize currentFileName to the fileName parameter + // so content before the first @Filename directive goes into an implicit first file + currentFileName = fileName + } var currentDirectory string var parseError error currentFileOptions := make(map[string]string) @@ -158,13 +179,15 @@ func ParseTestFilesAndSymlinks[T any]( // New metadata statement after having collected some code to go with the previous metadata if currentFileName != "" { - // Store result file - newTestFile, e := parseFile(currentFileName, currentFileContent.String(), currentFileOptions) - if e != nil { - parseError = e - break + if currentFileContent.Len() != 0 { + // Store result file + newTestFile, e := parseFile(currentFileName, currentFileContent.String(), currentFileOptions) + if e != nil { + parseError = e + break + } + testUnits = append(testUnits, newTestFile) } - testUnits = append(testUnits, newTestFile) // Reset local data currentFileContent.Reset() @@ -172,11 +195,27 @@ func ParseTestFilesAndSymlinks[T any]( currentFileOptions = make(map[string]string) } else { // First metadata marker in the file - currentFileName = strings.TrimSpace(testMetaData[2]) - if currentFileContent.Len() != 0 && scanner.SkipTrivia(currentFileContent.String(), 0) != currentFileContent.Len() { + hasContentBeforeFirstFilename := currentFileContent.Len() != 0 && scanner.SkipTrivia(currentFileContent.String(), 0) != currentFileContent.Len() + if hasContentBeforeFirstFilename && !options.AllowImplicitFirstFile { panic("Non-comment test content appears before the first '// @Filename' directive") } + + // If we have content before the first @Filename and AllowImplicitFirstFile is true, + // we need to save it as an implicit first file before starting the new file + if hasContentBeforeFirstFilename && options.AllowImplicitFirstFile && currentFileName != "" { + // Store the implicit first file + newTestFile, e := parseFile(currentFileName, currentFileContent.String(), currentFileOptions) + if e != nil { + parseError = e + break + } + testUnits = append(testUnits, newTestFile) + } + + // Reset for the new file currentFileContent.Reset() + currentFileName = strings.TrimSpace(testMetaData[2]) + currentFileOptions = make(map[string]string) } } else { // Subfile content line From 8cf4fd6a10011bbf68448f5edf27d5b9cf3423d7 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 17:10:08 -0800 Subject: [PATCH 03/48] Add tests --- .../fourslash/_scripts/convertFourslash.mts | 77 +++++++++- internal/fourslash/fourslash.go | 135 ++++++++++++++++++ ...ortCrossProject_paths_sharedOutDir_test.go | 50 +++++++ ...oImportCrossProject_paths_stripSrc_test.go | 60 ++++++++ ...utoImportCrossProject_paths_toDist_test.go | 60 ++++++++ ...autoImportCrossProject_paths_toSrc_test.go | 60 ++++++++ ...portCrossProject_symlinks_stripSrc_test.go | 49 +++++++ ...ImportCrossProject_symlinks_toDist_test.go | 49 +++++++ ...oImportCrossProject_symlinks_toSrc_test.go | 46 ++++++ .../tests/gen/autoImportJsDocImport1_test.go | 50 +++++++ .../gen/autoImportNodeNextJSRequire_test.go | 35 +++++ ...rtPackageJsonFilterExistingImport2_test.go | 32 +++++ ...rtPackageJsonFilterExistingImport3_test.go | 34 +++++ .../tests/gen/autoImportPnpm_test.go | 33 +++++ .../tests/gen/autoImportProvider4_test.go | 34 +++++ .../tests/gen/autoImportProvider5_test.go | 34 +++++ .../tests/gen/autoImportProvider_pnpm_test.go | 32 +++++ .../autoImportSortCaseSensitivity1_test.go | 54 +++++++ .../autoImportSymlinkCaseSensitive_test.go | 31 ++++ .../tests/gen/autoImportTypeImport1_test.go | 42 ++++++ .../tests/gen/autoImportTypeImport2_test.go | 42 ++++++ .../tests/gen/autoImportTypeImport3_test.go | 42 ++++++ .../tests/gen/autoImportTypeImport4_test.go | 123 ++++++++++++++++ .../tests/gen/autoImportTypeImport5_test.go | 108 ++++++++++++++ .../gen/autoImportTypeOnlyPreferred2_test.go | 50 +++++++ .../tests/gen/autoImportsNodeNext1_test.go | 47 ++++++ ...WithMultipleModuleExportAssignment_test.go | 32 +++++ .../gen/importFixesGlobalTypingsCache_test.go | 33 +++++ ...uotePreferenceDouble_importHelpers_test.go | 28 ++++ ...uotePreferenceSingle_importHelpers_test.go | 28 ++++ .../importNameCodeFixConvertTypeOnly1_test.go | 26 ++++ .../importNameCodeFixDefaultExport1_test.go | 25 ++++ .../importNameCodeFixDefaultExport2_test.go | 26 ++++ .../importNameCodeFixDefaultExport3_test.go | 25 ++++ .../importNameCodeFixDefaultExport4_test.go | 26 ++++ .../importNameCodeFixDefaultExport5_test.go | 27 ++++ .../importNameCodeFixDefaultExport7_test.go | 26 ++++ .../importNameCodeFixDefaultExport_test.go | 25 ++++ .../importNameCodeFixExistingImport0_test.go | 23 +++ .../importNameCodeFixExistingImport10_test.go | 32 +++++ .../importNameCodeFixExistingImport11_test.go | 32 +++++ .../importNameCodeFixExistingImport12_test.go | 25 ++++ .../importNameCodeFixExistingImport1_test.go | 24 ++++ .../importNameCodeFixExistingImport2_test.go | 30 ++++ .../importNameCodeFixExistingImport3_test.go | 28 ++++ .../importNameCodeFixExistingImport4_test.go | 25 ++++ .../importNameCodeFixExistingImport5_test.go | 25 ++++ .../importNameCodeFixExistingImport6_test.go | 25 ++++ .../importNameCodeFixExistingImport7_test.go | 23 +++ .../importNameCodeFixExistingImport8_test.go | 25 ++++ .../importNameCodeFixExistingImport9_test.go | 28 ++++ ...rtNameCodeFixExistingImportEquals0_test.go | 29 ++++ ...deFixExportAsDefaultExistingImport_test.go | 26 ++++ ...mportNameCodeFixIndentedIdentifier_test.go | 33 +++++ ...mportAllowSyntheticDefaultImports0_test.go | 29 ++++ ...mportAllowSyntheticDefaultImports1_test.go | 29 ++++ ...mportAllowSyntheticDefaultImports2_test.go | 30 ++++ ...mportAllowSyntheticDefaultImports3_test.go | 30 ++++ ...mportAllowSyntheticDefaultImports4_test.go | 30 ++++ ...mportAllowSyntheticDefaultImports5_test.go | 30 ++++ ...importNameCodeFixNewImportAmbient0_test.go | 26 ++++ ...importNameCodeFixNewImportAmbient1_test.go | 38 +++++ ...importNameCodeFixNewImportAmbient2_test.go | 33 +++++ ...importNameCodeFixNewImportAmbient3_test.go | 40 ++++++ ...importNameCodeFixNewImportBaseUrl0_test.go | 29 ++++ ...importNameCodeFixNewImportBaseUrl1_test.go | 36 +++++ ...importNameCodeFixNewImportBaseUrl2_test.go | 36 +++++ ...importNameCodeFixNewImportDefault0_test.go | 23 +++ ...mportExportEqualsCommonJSInteropOn_test.go | 62 ++++++++ ...ImportExportEqualsESNextInteropOff_test.go | 29 ++++ ...wImportExportEqualsESNextInteropOn_test.go | 30 ++++ .../importNameCodeFixNewImportFile0_test.go | 24 ++++ .../importNameCodeFixNewImportFile1_test.go | 29 ++++ .../importNameCodeFixNewImportFile2_test.go | 24 ++++ .../importNameCodeFixNewImportFile3_test.go | 26 ++++ .../importNameCodeFixNewImportFile4_test.go | 27 ++++ ...ameCodeFixNewImportFileAllComments_test.go | 47 ++++++ ...deFixNewImportFileDetachedComments_test.go | 34 +++++ ...ameCodeFixNewImportFileQuoteStyle0_test.go | 28 ++++ ...ameCodeFixNewImportFileQuoteStyle1_test.go | 28 ++++ ...ameCodeFixNewImportFileQuoteStyle2_test.go | 28 ++++ ...ameCodeFixNewImportFileQuoteStyle3_test.go | 29 ++++ ...deFixNewImportFileQuoteStyleMixed0_test.go | 32 +++++ ...deFixNewImportFileQuoteStyleMixed1_test.go | 32 +++++ ...xNewImportFromAtTypesScopedPackage_test.go | 24 ++++ ...ortNameCodeFixNewImportFromAtTypes_test.go | 24 ++++ ...mportIndex_notForClassicResolution_test.go | 37 +++++ .../importNameCodeFixNewImportIndex_test.go | 26 ++++ ...rtNameCodeFixNewImportNodeModules0_test.go | 28 ++++ ...rtNameCodeFixNewImportNodeModules1_test.go | 26 ++++ ...rtNameCodeFixNewImportNodeModules2_test.go | 33 +++++ ...rtNameCodeFixNewImportNodeModules3_test.go | 25 ++++ ...rtNameCodeFixNewImportNodeModules4_test.go | 33 +++++ ...rtNameCodeFixNewImportNodeModules6_test.go | 33 +++++ ...rtNameCodeFixNewImportNodeModules7_test.go | 30 ++++ ...rtNameCodeFixNewImportNodeModules8_test.go | 33 +++++ .../importNameCodeFixNewImportPaths0_test.go | 32 +++++ .../importNameCodeFixNewImportPaths1_test.go | 32 +++++ .../importNameCodeFixNewImportPaths2_test.go | 37 +++++ ...odeFixNewImportPaths_withExtension_test.go | 33 +++++ ...NewImportPaths_withLeadingDotSlash_test.go | 33 +++++ ...ImportPaths_withParentRelativePath_test.go | 33 +++++ ...mportNameCodeFixNewImportRootDirs0_test.go | 33 +++++ ...mportNameCodeFixNewImportRootDirs1_test.go | 32 +++++ ...portNameCodeFixNewImportTypeRoots0_test.go | 32 +++++ ...portNameCodeFixNewImportTypeRoots1_test.go | 33 +++++ .../importNameCodeFixOptionalImport0_test.go | 29 ++++ .../importNameCodeFixOptionalImport1_test.go | 29 ++++ .../gen/importNameCodeFixShebang_test.go | 29 ++++ .../gen/importNameCodeFixUMDGlobal0_test.go | 29 ++++ .../gen/importNameCodeFixUMDGlobal1_test.go | 32 +++++ ...portNameCodeFixUMDGlobalJavaScript_test.go | 31 ++++ .../importNameCodeFixUMDGlobalReact0_test.go | 50 +++++++ .../importNameCodeFixUMDGlobalReact1_test.go | 41 ++++++ .../importNameCodeFixUMDGlobalReact2_test.go | 32 +++++ .../importNameCodeFix_HeaderComment1_test.go | 36 +++++ .../importNameCodeFix_HeaderComment2_test.go | 42 ++++++ ...meCodeFix_avoidRelativeNodeModules_test.go | 34 +++++ ...ameCodeFix_commonjs_allowSynthetic_test.go | 35 +++++ .../importNameCodeFix_defaultExport_test.go | 29 ++++ .../gen/importNameCodeFix_dollar_test.go | 27 ++++ ...eCodeFix_fileWithNoTrailingNewline_test.go | 28 ++++ .../importNameCodeFix_fromPathMapping_test.go | 34 +++++ ...rtNameCodeFix_getCanonicalFileName_test.go | 25 ++++ .../gen/importNameCodeFix_importType1_test.go | 37 +++++ .../gen/importNameCodeFix_importType2_test.go | 57 ++++++++ .../gen/importNameCodeFix_importType3_test.go | 28 ++++ .../gen/importNameCodeFix_importType4_test.go | 29 ++++ .../gen/importNameCodeFix_importType5_test.go | 27 ++++ .../gen/importNameCodeFix_importType6_test.go | 30 ++++ .../gen/importNameCodeFix_importType7_test.go | 54 +++++++ .../gen/importNameCodeFix_importType8_test.go | 28 ++++ .../gen/importNameCodeFix_importType_test.go | 28 ++++ .../gen/importNameCodeFix_jsCJSvsESM1_test.go | 29 ++++ .../gen/importNameCodeFix_jsCJSvsESM2_test.go | 31 ++++ .../gen/importNameCodeFix_jsCJSvsESM3_test.go | 34 +++++ .../tests/gen/importNameCodeFix_jsx1_test.go | 42 ++++++ ...CodeFix_jsxOpeningTagImportDefault_test.go | 31 ++++ .../gen/importNameCodeFix_jsxReact17_test.go | 41 ++++++ .../gen/importNameCodeFix_order2_test.go | 54 +++++++ .../tests/gen/importNameCodeFix_order_test.go | 31 ++++ ...rtNameCodeFix_pathsWithoutBaseUrl1_test.go | 34 +++++ ...rtNameCodeFix_pathsWithoutBaseUrl2_test.go | 34 +++++ .../tests/gen/importNameCodeFix_pnpm1_test.go | 28 ++++ .../importNameCodeFix_preferBaseUrl_test.go | 27 ++++ .../gen/importNameCodeFix_quoteStyle_test.go | 26 ++++ .../importNameCodeFix_reExportDefault_test.go | 54 +++++++ .../gen/importNameCodeFix_reExport_test.go | 30 ++++ ...deFix_shorthandPropertyAssignment1_test.go | 25 ++++ ...deFix_shorthandPropertyAssignment2_test.go | 26 ++++ .../importNameCodeFix_sortByDistance_test.go | 41 ++++++ ...tNameCodeFix_symlink_own_package_2_test.go | 28 ++++ ...ortNameCodeFix_symlink_own_package_test.go | 31 ++++ .../gen/importNameCodeFix_symlink_test.go | 33 +++++ .../importNameCodeFix_trailingComma_test.go | 35 +++++ ...ortNameCodeFix_tripleSlashOrdering_test.go | 119 +++++++++++++++ .../gen/importNameCodeFix_typeOnly_test.go | 27 ++++ .../importNameCodeFix_typeUsedAsValue_test.go | 25 ++++ .../gen/importNameCodeFix_withJson_test.go | 28 ++++ .../gen/moduleNodeNextAutoImport1_test.go | 31 ++++ .../gen/moduleNodeNextAutoImport2_test.go | 31 ++++ .../gen/moduleNodeNextAutoImport3_test.go | 31 ++++ internal/ls/codeactions.go | 2 +- 163 files changed, 5746 insertions(+), 2 deletions(-) create mode 100644 internal/fourslash/tests/gen/autoImportCrossProject_paths_sharedOutDir_test.go create mode 100644 internal/fourslash/tests/gen/autoImportCrossProject_paths_stripSrc_test.go create mode 100644 internal/fourslash/tests/gen/autoImportCrossProject_paths_toDist_test.go create mode 100644 internal/fourslash/tests/gen/autoImportCrossProject_paths_toSrc_test.go create mode 100644 internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go create mode 100644 internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go create mode 100644 internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go create mode 100644 internal/fourslash/tests/gen/autoImportJsDocImport1_test.go create mode 100644 internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go create mode 100644 internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport2_test.go create mode 100644 internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport3_test.go create mode 100644 internal/fourslash/tests/gen/autoImportPnpm_test.go create mode 100644 internal/fourslash/tests/gen/autoImportProvider4_test.go create mode 100644 internal/fourslash/tests/gen/autoImportProvider5_test.go create mode 100644 internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go create mode 100644 internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go create mode 100644 internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go create mode 100644 internal/fourslash/tests/gen/autoImportTypeImport1_test.go create mode 100644 internal/fourslash/tests/gen/autoImportTypeImport2_test.go create mode 100644 internal/fourslash/tests/gen/autoImportTypeImport3_test.go create mode 100644 internal/fourslash/tests/gen/autoImportTypeImport4_test.go create mode 100644 internal/fourslash/tests/gen/autoImportTypeImport5_test.go create mode 100644 internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go create mode 100644 internal/fourslash/tests/gen/autoImportsNodeNext1_test.go create mode 100644 internal/fourslash/tests/gen/importFixWithMultipleModuleExportAssignment_test.go create mode 100644 internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go create mode 100644 internal/fourslash/tests/gen/importFixes_quotePreferenceDouble_importHelpers_test.go create mode 100644 internal/fourslash/tests/gen/importFixes_quotePreferenceSingle_importHelpers_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixDefaultExport1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixDefaultExport2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixDefaultExport3_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixDefaultExport4_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixDefaultExport5_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixDefaultExport7_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixDefaultExport_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExistingImport0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExistingImport12_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExistingImport1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExistingImport2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExistingImport3_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExistingImport4_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExistingImport6_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExistingImport7_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixExportAsDefaultExistingImport_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixIndentedIdentifier_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports3_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports4_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports5_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportDefault0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsCommonJSInteropOn_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsESNextInteropOff_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsESNextInteropOn_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFile0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFile1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFile3_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFile4_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFileAllComments_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFileDetachedComments_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle3_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFromAtTypesScopedPackage_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportFromAtTypes_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_notForClassicResolution_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules3_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules4_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules6_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules7_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules8_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportPaths0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportPaths1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportPaths2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportPaths_withExtension_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportPaths_withLeadingDotSlash_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportPaths_withParentRelativePath_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixOptionalImport1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixShebang_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixUMDGlobal0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixUMDGlobal1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixUMDGlobalJavaScript_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact0_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_commonjs_allowSynthetic_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_defaultExport_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_dollar_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_fromPathMapping_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_getCanonicalFileName_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_importType3_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_importType5_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_importType6_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_importType_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM3_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_jsxOpeningTagImportDefault_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_jsxReact17_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_order2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_order_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_pathsWithoutBaseUrl1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_pathsWithoutBaseUrl2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_quoteStyle_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_reExport_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment1_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_sortByDistance_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_symlink_own_package_2_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_symlink_own_package_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_tripleSlashOrdering_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_typeOnly_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_typeUsedAsValue_test.go create mode 100644 internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go create mode 100644 internal/fourslash/tests/gen/moduleNodeNextAutoImport1_test.go create mode 100644 internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go create mode 100644 internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go diff --git a/internal/fourslash/_scripts/convertFourslash.mts b/internal/fourslash/_scripts/convertFourslash.mts index dedcc358b7..53c52829f3 100644 --- a/internal/fourslash/_scripts/convertFourslash.mts +++ b/internal/fourslash/_scripts/convertFourslash.mts @@ -175,6 +175,9 @@ function parseFourslashStatement(statement: ts.Statement): Cmd[] | undefined { case "applyCodeActionFromCompletion": // `verify.applyCodeActionFromCompletion(...)` return parseVerifyApplyCodeActionFromCompletionArgs(callExpression.arguments); + case "importFixAtPosition": + // `verify.importFixAtPosition(...)` + return parseImportFixAtPositionArgs(callExpression.arguments); case "quickInfoAt": case "quickInfoExists": case "quickInfoIs": @@ -542,6 +545,46 @@ function parseVerifyApplyCodeActionArgs(arg: ts.Expression): string | undefined return `&fourslash.ApplyCodeActionFromCompletionOptions{\n${props.join("\n")}\n}`; } +function parseImportFixAtPositionArgs(args: readonly ts.Expression[]): VerifyImportFixAtPositionCmd[] | undefined { + if (args.length < 1 || args.length > 3) { + console.error(`Expected 1-3 arguments in verify.importFixAtPosition, got ${args.map(arg => arg.getText()).join(", ")}`); + return undefined; + } + const arrayArg = getArrayLiteralExpression(args[0]); + if (!arrayArg) { + console.error(`Expected array literal for first argument in verify.importFixAtPosition, got ${args[0].getText()}`); + return undefined; + } + const expectedTexts: string[] = []; + for (const elem of arrayArg.elements) { + const strElem = getStringLiteralLike(elem); + if (!strElem) { + console.error(`Expected string literal in verify.importFixAtPosition array, got ${elem.getText()}`); + return undefined; + } + expectedTexts.push(getGoMultiLineStringLiteral(strElem.text)); + } + + // If the array is empty, we should still generate valid Go code + if (expectedTexts.length === 0) { + expectedTexts.push(""); // This will be handled specially in code generation + } + + let preferences: string | undefined; + if (args.length > 2 && ts.isObjectLiteralExpression(args[2])) { + preferences = parseUserPreferences(args[2]); + if (!preferences) { + console.error(`Unrecognized user preferences in verify.importFixAtPosition: ${args[2].getText()}`); + return undefined; + } + } + return [{ + kind: "verifyImportFixAtPosition", + expectedTexts, + preferences: preferences || "nil /*preferences*/", + }]; +} + const completionConstants = new Map([ ["completion.globals", "CompletionGlobals"], ["completion.globalTypes", "CompletionGlobalTypes"], @@ -1240,6 +1283,21 @@ function parseUserPreferences(arg: ts.ObjectLiteralExpression): string | undefin case "quotePreference": preferences.push(`QuotePreference: lsutil.QuotePreference(${prop.initializer.getText()})`); break; + case "autoImportFileExcludePatterns": + const arrayArg = getArrayLiteralExpression(prop.initializer); + if (!arrayArg) { + return undefined; + } + const patterns: string[] = []; + for (const elem of arrayArg.elements) { + const strElem = getStringLiteralLike(elem); + if (!strElem) { + return undefined; + } + patterns.push(getGoStringLiteral(strElem.text)); + } + preferences.push(`AutoImportFileExcludePatterns: []string{${patterns.join(", ")}}`); + break; case "includeInlayParameterNameHints": let paramHint; if (!ts.isStringLiteralLike(prop.initializer)) { @@ -1701,6 +1759,12 @@ interface VerifyBaselineInlayHintsCmd { preferences: string; } +interface VerifyImportFixAtPositionCmd { + kind: "verifyImportFixAtPosition"; + expectedTexts: string[]; + preferences: string; +} + interface GoToCmd { kind: "goTo"; // !!! `selectRange` and `rangeStart` require parsing variables and `test.ranges()[n]` @@ -1739,7 +1803,8 @@ type Cmd = | VerifyQuickInfoCmd | VerifyBaselineRenameCmd | VerifyRenameInfoCmd - | VerifyBaselineInlayHintsCmd; + | VerifyBaselineInlayHintsCmd + | VerifyImportFixAtPositionCmd; function generateVerifyCompletions({ marker, args, isNewIdentifierLocation, andApplyCodeActionArgs }: VerifyCompletionsCmd): string { let expectedList: string; @@ -1840,6 +1905,14 @@ function generateBaselineInlayHints({ span, preferences }: VerifyBaselineInlayHi return `f.VerifyBaselineInlayHints(t, ${span}, ${preferences})`; } +function generateImportFixAtPosition({ expectedTexts, preferences }: VerifyImportFixAtPositionCmd): string { + // Handle empty array case + if (expectedTexts.length === 1 && expectedTexts[0] === "") { + return `f.VerifyImportFixAtPosition(t, []string{}, ${preferences})`; + } + return `f.VerifyImportFixAtPosition(t, []string{\n${expectedTexts.join(",\n")},\n}, ${preferences})`; +} + function generateCmd(cmd: Cmd): string { switch (cmd.kind) { case "verifyCompletions": @@ -1878,6 +1951,8 @@ function generateCmd(cmd: Cmd): string { return `f.VerifyRenameFailed(t, ${cmd.preferences})`; case "verifyBaselineInlayHints": return generateBaselineInlayHints(cmd); + case "verifyImportFixAtPosition": + return generateImportFixAtPosition(cmd); default: let neverCommand: never = cmd; throw new Error(`Unknown command kind: ${neverCommand as Cmd["kind"]}`); diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index 6edbbf1be6..07dcb21a7a 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -1030,6 +1030,141 @@ func (f *FourslashTest) VerifyApplyCodeActionFromCompletion(t *testing.T, marker } } +func (f *FourslashTest) VerifyImportFixAtPosition(t *testing.T, expectedTexts []string, preferences *lsutil.UserPreferences) { + fileName := f.activeFilename + ranges := f.Ranges() + var filteredRanges []*RangeMarker + for _, r := range ranges { + if r.FileName() == fileName { + filteredRanges = append(filteredRanges, r) + } + } + if len(filteredRanges) > 1 { + t.Fatalf("Exactly one range should be specified in the testfile.") + } + var rangeMarker *RangeMarker + if len(filteredRanges) == 1 { + rangeMarker = filteredRanges[0] + } + + if preferences != nil { + reset := f.ConfigureWithReset(t, preferences) + defer reset() + } + + // Get diagnostics at the current position to find errors that need import fixes + diagParams := &lsproto.DocumentDiagnosticParams{ + TextDocument: lsproto.TextDocumentIdentifier{ + Uri: lsconv.FileNameToDocumentURI(f.activeFilename), + }, + } + _, diagResult, diagOk := sendRequest(t, f, lsproto.TextDocumentDiagnosticInfo, diagParams) + if !diagOk { + t.Fatalf("Failed to get diagnostics") + } + + var diagnostics []*lsproto.Diagnostic + if diagResult.FullDocumentDiagnosticReport != nil && diagResult.FullDocumentDiagnosticReport.Items != nil { + diagnostics = diagResult.FullDocumentDiagnosticReport.Items + } + + params := &lsproto.CodeActionParams{ + TextDocument: lsproto.TextDocumentIdentifier{ + Uri: lsconv.FileNameToDocumentURI(f.activeFilename), + }, + Range: lsproto.Range{ + Start: f.currentCaretPosition, + End: f.currentCaretPosition, + }, + Context: &lsproto.CodeActionContext{ + Diagnostics: diagnostics, + }, + } + resMsg, result, resultOk := sendRequest(t, f, lsproto.TextDocumentCodeActionInfo, params) + if resMsg == nil { + t.Fatalf("Nil response received for code action request at pos %v", f.currentCaretPosition) + } + if !resultOk { + t.Fatalf("Unexpected code action response type at pos %v: %T", f.currentCaretPosition, resMsg.AsResponse().Result) + } + + // Find all auto-import code actions (fixes with fixId/fixName related to imports) + var importActions []*lsproto.CodeAction + if result.CommandOrCodeActionArray != nil { + for _, item := range *result.CommandOrCodeActionArray { + if item.CodeAction != nil && item.CodeAction.Kind != nil && *item.CodeAction.Kind == lsproto.CodeActionKindQuickFix { + importActions = append(importActions, item.CodeAction) + } + } + } + + if len(importActions) == 0 { + if len(expectedTexts) != 0 { + t.Fatalf("No codefixes returned.") + } + return + } + + // Save the original content before any edits + script := f.getScriptInfo(f.activeFilename) + originalContent := script.content + + // For each import action, apply it and check the result + actualTextArray := make([]string, 0, len(importActions)) + for _, action := range importActions { + // Apply the code action + var edits []*lsproto.TextEdit + if action.Edit != nil && action.Edit.Changes != nil { + if len(*action.Edit.Changes) != 1 { + t.Fatalf("Expected exactly 1 change, got %d", len(*action.Edit.Changes)) + } + for uri, changeEdits := range *action.Edit.Changes { + if uri != lsconv.FileNameToDocumentURI(f.activeFilename) { + t.Fatalf("Expected change to file %s, got %s", f.activeFilename, uri) + } + edits = changeEdits + f.applyTextEdits(t, changeEdits) + } + } + + // Get the result text + var text string + if rangeMarker != nil { + text = f.getRangeText(rangeMarker) + } else { + text = f.getScriptInfo(f.activeFilename).content + } + actualTextArray = append(actualTextArray, text) + + // Undo changes to perform next fix + for _, textChange := range edits { + start := int(f.converters.LineAndCharacterToPosition(script, textChange.Range.Start)) + end := int(f.converters.LineAndCharacterToPosition(script, textChange.Range.End)) + deletedText := originalContent[start:end] + insertedText := textChange.NewText + f.editScriptAndUpdateMarkers(t, f.activeFilename, start, start+len(insertedText), deletedText) + } + } + + // Compare results + if len(expectedTexts) != len(actualTextArray) { + var actualJoined strings.Builder + for i, actual := range actualTextArray { + if i > 0 { + actualJoined.WriteString("\n\n" + strings.Repeat("-", 20) + "\n\n") + } + actualJoined.WriteString(actual) + } + t.Fatalf("Expected %d import fixes, got %d:\n\n%s", len(expectedTexts), len(actualTextArray), actualJoined.String()) + } + for i, expected := range expectedTexts { + actual := actualTextArray[i] + if expected != actual { + t.Fatalf("Import fix at index %d doesn't match.\nExpected:\n%s\n\nActual:\n%s", i, expected, actual) + } + } +} + func (f *FourslashTest) VerifyBaselineFindAllReferences( t *testing.T, markers ...string, diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_paths_sharedOutDir_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_paths_sharedOutDir_test.go new file mode 100644 index 0000000000..1c6c889718 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportCrossProject_paths_sharedOutDir_test.go @@ -0,0 +1,50 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportCrossProject_paths_sharedOutDir(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /home/src/workspaces/project/tsconfig.base.json +{ + "compilerOptions": { + "module": "commonjs", + "baseUrl": ".", + "paths": { + "packages/*": ["./packages/*"] + } + } +} +// @Filename: /home/src/workspaces/project/packages/app/tsconfig.json +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { "outDir": "../../dist/packages/app" }, + "references": [{ "path": "../dep" }] +} +// @Filename: /home/src/workspaces/project/packages/app/index.ts +dep/**/ +// @Filename: /home/src/workspaces/project/packages/app/utils.ts +import "packages/dep"; +// @Filename: /home/src/workspaces/project/packages/dep/tsconfig.json +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { "outDir": "../../dist/packages/dep" } +} +// @Filename: /home/src/workspaces/project/packages/dep/index.ts +import "./sub/folder"; +// @Filename: /home/src/workspaces/project/packages/dep/sub/folder/index.ts +export const dep = 0;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { dep } from "packages/dep/sub/folder"; + +dep`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_paths_stripSrc_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_paths_stripSrc_test.go new file mode 100644 index 0000000000..d55afda187 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportCrossProject_paths_stripSrc_test.go @@ -0,0 +1,60 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportCrossProject_paths_stripSrc(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json +{ "name": "app", "dependencies": { "dep": "*" } } +// @Filename: /home/src/workspaces/project/packages/app/tsconfig.json +{ + "compilerOptions": { + "module": "commonjs", + "outDir": "dist", + "rootDir": "src", + "baseUrl": ".", + "paths": { + "dep": ["../dep/src/main"], + "dep/*": ["../dep/src/*"] + } + } + "references": [{ "path": "../dep" }] +} +// @Filename: /home/src/workspaces/project/packages/app/src/index.ts +dep1/*1*/; +// @Filename: /home/src/workspaces/project/packages/app/src/utils.ts +dep2/*2*/; +// @Filename: /home/src/workspaces/project/packages/app/src/a.ts +import "dep"; +// @Filename: /home/src/workspaces/project/packages/dep/package.json +{ "name": "dep", "main": "dist/main.js", "types": "dist/main.d.ts" } +// @Filename: /home/src/workspaces/project/packages/dep/tsconfig.json +{ + "compilerOptions": { "outDir": "dist", "rootDir": "src", "module": "commonjs" } +} +// @Filename: /home/src/workspaces/project/packages/dep/src/main.ts +import "./sub/folder"; +export const dep1 = 0; +// @Filename: /home/src/workspaces/project/packages/dep/src/sub/folder/index.ts +export const dep2 = 0;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "1") + f.VerifyImportFixAtPosition(t, []string{ + `import { dep1 } from "dep"; + +dep1;`, + }, nil /*preferences*/) + f.GoToMarker(t, "2") + f.VerifyImportFixAtPosition(t, []string{ + `import { dep2 } from "dep/sub/folder"; + +dep2;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_paths_toDist_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_paths_toDist_test.go new file mode 100644 index 0000000000..41428f10d4 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportCrossProject_paths_toDist_test.go @@ -0,0 +1,60 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportCrossProject_paths_toDist(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json +{ "name": "app", "dependencies": { "dep": "*" } } +// @Filename: /home/src/workspaces/project/packages/app/tsconfig.json +{ + "compilerOptions": { + "module": "commonjs", + "outDir": "dist", + "rootDir": "src", + "baseUrl": ".", + "paths": { + "dep": ["../dep/src/main"], + "dep/dist/*": ["../dep/src/*"] + } + } + "references": [{ "path": "../dep" }] +} +// @Filename: /home/src/workspaces/project/packages/app/src/index.ts +dep1/*1*/; +// @Filename: /home/src/workspaces/project/packages/app/src/utils.ts +dep2/*2*/; +// @Filename: /home/src/workspaces/project/packages/app/src/a.ts +import "dep"; +// @Filename: /home/src/workspaces/project/packages/dep/package.json +{ "name": "dep", "main": "dist/main.js", "types": "dist/main.d.ts" } +// @Filename: /home/src/workspaces/project/packages/dep/tsconfig.json +{ + "compilerOptions": { "outDir": "dist", "rootDir": "src", "module": "commonjs" } +} +// @Filename: /home/src/workspaces/project/packages/dep/src/main.ts +import "./sub/folder"; +export const dep1 = 0; +// @Filename: /home/src/workspaces/project/packages/dep/src/sub/folder/index.ts +export const dep2 = 0;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "1") + f.VerifyImportFixAtPosition(t, []string{ + `import { dep1 } from "dep"; + +dep1;`, + }, nil /*preferences*/) + f.GoToMarker(t, "2") + f.VerifyImportFixAtPosition(t, []string{ + `import { dep2 } from "dep/dist/sub/folder"; + +dep2;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_paths_toSrc_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_paths_toSrc_test.go new file mode 100644 index 0000000000..a3d25d2a86 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportCrossProject_paths_toSrc_test.go @@ -0,0 +1,60 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportCrossProject_paths_toSrc(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json +{ "name": "app", "dependencies": { "dep": "*" } } +// @Filename: /home/src/workspaces/project/packages/app/tsconfig.json +{ + "compilerOptions": { + "module": "commonjs", + "outDir": "dist", + "rootDir": "src", + "baseUrl": ".", + "paths": { + "dep": ["../dep/src/main"], + "dep/*": ["../dep/*"] + } + } + "references": [{ "path": "../dep" }] +} +// @Filename: /home/src/workspaces/project/packages/app/src/index.ts +dep1/*1*/; +// @Filename: /home/src/workspaces/project/packages/app/src/utils.ts +dep2/*2*/; +// @Filename: /home/src/workspaces/project/packages/app/src/a.ts +import "dep"; +// @Filename: /home/src/workspaces/project/packages/dep/package.json +{ "name": "dep", "main": "dist/main.js", "types": "dist/main.d.ts" } +// @Filename: /home/src/workspaces/project/packages/dep/tsconfig.json +{ + "compilerOptions": { "outDir": "dist", "rootDir": "src", "module": "commonjs" } +} +// @Filename: /home/src/workspaces/project/packages/dep/src/main.ts +import "./sub/folder"; +export const dep1 = 0; +// @Filename: /home/src/workspaces/project/packages/dep/src/sub/folder/index.ts +export const dep2 = 0;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "1") + f.VerifyImportFixAtPosition(t, []string{ + `import { dep1 } from "dep"; + +dep1;`, + }, nil /*preferences*/) + f.GoToMarker(t, "2") + f.VerifyImportFixAtPosition(t, []string{ + `import { dep2 } from "dep/src/sub/folder"; + +dep2;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go new file mode 100644 index 0000000000..b7358d23e9 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go @@ -0,0 +1,49 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportCrossProject_symlinks_stripSrc(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json +{ "name": "app", "dependencies": { "dep": "*" } } +// @Filename: /home/src/workspaces/project/packages/app/tsconfig.json +{ + "compilerOptions": { + "module": "commonjs", + "outDir": "dist", + "rootDir": "src", + "baseUrl": ".", + "paths": { + "dep/*": ["../dep/src/*"] + } + } + "references": [{ "path": "../dep" }] +} +// @Filename: /home/src/workspaces/project/packages/app/src/index.ts +dep/**/ +// @Filename: /home/src/workspaces/project/packages/dep/package.json +{ "name": "dep", "main": "dist/index.js", "types": "dist/index.d.ts" } +// @Filename: /home/src/workspaces/project/packages/dep/tsconfig.json +{ + "compilerOptions": { "outDir": "dist", "rootDir": "src", "module": "commonjs" } +} +// @Filename: /home/src/workspaces/project/packages/dep/src/index.ts +import "./sub/folder"; +// @Filename: /home/src/workspaces/project/packages/dep/src/sub/folder/index.ts +export const dep = 0; +// @link: /home/src/workspaces/project/packages/dep -> /home/src/workspaces/project/packages/app/node_modules/dep` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { dep } from "dep/sub/folder"; + +dep`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go new file mode 100644 index 0000000000..d7be784d54 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go @@ -0,0 +1,49 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportCrossProject_symlinks_toDist(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json +{ "name": "app", "dependencies": { "dep": "*" } } +// @Filename: /home/src/workspaces/project/packages/app/tsconfig.json +{ + "compilerOptions": { + "module": "commonjs", + "outDir": "dist", + "rootDir": "src", + "baseUrl": ".", + "paths": { + "dep/dist/*": ["../dep/src/*"] + } + } + "references": [{ "path": "../dep" }] +} +// @Filename: /home/src/workspaces/project/packages/app/src/index.ts +dep/**/ +// @Filename: /home/src/workspaces/project/packages/dep/package.json +{ "name": "dep", "main": "dist/index.js", "types": "dist/index.d.ts" } +// @Filename: /home/src/workspaces/project/packages/dep/tsconfig.json +{ + "compilerOptions": { "outDir": "dist", "rootDir": "src", "module": "commonjs" } +} +// @Filename: /home/src/workspaces/project/packages/dep/src/index.ts +import "./sub/folder"; +// @Filename: /home/src/workspaces/project/packages/dep/src/sub/folder/index.ts +export const dep = 0; +// @link: /home/src/workspaces/project/packages/dep -> /home/src/workspaces/project/packages/app/node_modules/dep` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { dep } from "dep/dist/sub/folder"; + +dep`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go new file mode 100644 index 0000000000..2da97bbd63 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_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 TestAutoImportCrossProject_symlinks_toSrc(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json +{ "name": "app", "dependencies": { "dep": "*" } } +// @Filename: /home/src/workspaces/project/packages/app/tsconfig.json +{ + "compilerOptions": { + "module": "commonjs", + "outDir": "dist", + "rootDir": "src", + "baseUrl": "." + } + "references": [{ "path": "../dep" }] +} +// @Filename: /home/src/workspaces/project/packages/app/src/index.ts +dep/**/ +// @Filename: /home/src/workspaces/project/packages/dep/package.json +{ "name": "dep", "main": "dist/index.js", "types": "dist/index.d.ts" } +// @Filename: /home/src/workspaces/project/packages/dep/tsconfig.json +{ + "compilerOptions": { "outDir": "dist", "rootDir": "src", "module": "commonjs" } +} +// @Filename: /home/src/workspaces/project/packages/dep/src/index.ts +import "./sub/folder"; +// @Filename: /home/src/workspaces/project/packages/dep/src/sub/folder/index.ts +export const dep = 0; +// @link: /home/src/workspaces/project/packages/dep -> /home/src/workspaces/project/packages/app/node_modules/dep` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { dep } from "dep/src/sub/folder"; + +dep`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go b/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go new file mode 100644 index 0000000000..800437b6a5 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go @@ -0,0 +1,50 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportJsDocImport1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @verbatimModuleSyntax: true +// @target: esnext +// @allowJs: true +// @checkJs: true +// @Filename: /foo.ts + export const A = 1; + export type B = { x: number }; + export type C = 1; + export class D { y: string } +// @Filename: /test.js +/** + * @import { A, D, C } from "./foo" + */ + +/** + * @param { typeof A } a + * @param { B/**/ | C } b + * @param { C } c + * @param { D } d + */ +export function f(a, b, c, d) { }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `/** + * @import { A, D, C, B } from "./foo" + */ + +/** + * @param { typeof A } a + * @param { B | C } b + * @param { C } c + * @param { D } d + */ +export function f(a, b, c, d) { }`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go b/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go new file mode 100644 index 0000000000..823a6add81 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go @@ -0,0 +1,35 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportNodeNextJSRequire(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: node18 +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @Filename: /matrix.js +exports.variants = []; +// @Filename: /main.js +exports.dedupeLines = data => { + variants/**/ +} +// @Filename: /totally-irrelevant-no-way-this-changes-things-right.js +export default 0;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/main.js") + f.VerifyImportFixAtPosition(t, []string{ + `const { variants } = require("./matrix") + +exports.dedupeLines = data => { + variants +}`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport2_test.go b/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport2_test.go new file mode 100644 index 0000000000..7d881d0e9f --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport2_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 TestAutoImportPackageJsonFilterExistingImport2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: preserve +// @Filename: /home/src/workspaces/project/node_modules/@types/react/index.d.ts +export declare function useMemo(): void; +export declare function useState(): void; +// @Filename: /home/src/workspaces/project/package.json +{} +// @Filename: /home/src/workspaces/project/index.ts +useMemo/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{}, nil /*preferences*/) + f.GoToBOF(t) + f.InsertLine(t, "import { useState } from \"react\";") + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { useMemo, useState } from "react"; +useMemo`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport3_test.go b/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport3_test.go new file mode 100644 index 0000000000..8e8144e077 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport3_test.go @@ -0,0 +1,34 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportPackageJsonFilterExistingImport3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: preserve +// @Filename: /home/src/workspaces/project/node_modules/@types/node/index.d.ts +declare module "node:fs" { + export function readFile(): void; + export function writeFile(): void; +} +// @Filename: /home/src/workspaces/project/package.json +{} +// @Filename: /home/src/workspaces/project/index.ts +readFile/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{}, nil /*preferences*/) + f.GoToBOF(t) + f.InsertLine(t, "import { writeFile } from \"node:fs\";") + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { readFile, writeFile } from "node:fs"; +readFile`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportPnpm_test.go b/internal/fourslash/tests/gen/autoImportPnpm_test.go new file mode 100644 index 0000000000..dac4cd2cc0 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportPnpm_test.go @@ -0,0 +1,33 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportPnpm(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /tsconfig.json +{ "compilerOptions": { "module": "commonjs" } } +// @Filename: /node_modules/.pnpm/mobx@6.0.4/node_modules/mobx/package.json +{ "types": "dist/mobx.d.ts" } +// @Filename: /node_modules/.pnpm/mobx@6.0.4/node_modules/mobx/dist/mobx.d.ts +export declare function autorun(): void; +// @Filename: /index.ts +autorun/**/ +// @Filename: /utils.ts +import "mobx"; +// @link: /node_modules/.pnpm/mobx@6.0.4/node_modules/mobx -> /node_modules/mobx +// @link: /node_modules/.pnpm/mobx@6.0.4/node_modules/mobx -> /node_modules/.pnpm/cool-mobx-dependent@1.2.3/node_modules/mobx` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { autorun } from "mobx"; + +autorun`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportProvider4_test.go b/internal/fourslash/tests/gen/autoImportProvider4_test.go new file mode 100644 index 0000000000..ebb026c217 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportProvider4_test.go @@ -0,0 +1,34 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportProvider4(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /home/src/workspaces/project/a/package.json +{ "dependencies": { "b": "*" } } +// @Filename: /home/src/workspaces/project/a/tsconfig.json +{ "compilerOptions": { "module": "commonjs", "target": "esnext" }, "references": [{ "path": "../b" }] } +// @Filename: /home/src/workspaces/project/a/index.ts +new Shape/**/ +// @Filename: /home/src/workspaces/project/b/package.json +{ "types": "out/index.d.ts" } +// @Filename: /home/src/workspaces/project/b/tsconfig.json +{ "compilerOptions": { "outDir": "out", "composite": true } } +// @Filename: /home/src/workspaces/project/b/index.ts +export class Shape {} +// @link: /home/src/workspaces/project/b -> /home/src/workspaces/project/a/node_modules/b` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { Shape } from "b"; + +new Shape`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportProvider5_test.go b/internal/fourslash/tests/gen/autoImportProvider5_test.go new file mode 100644 index 0000000000..147ea11146 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportProvider5_test.go @@ -0,0 +1,34 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportProvider5(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /home/src/workspaces/project/package.json +{ "dependencies": { "react-hook-form": "*" } } +// @Filename: /home/src/workspaces/project/node_modules/react-hook-form/package.json +{ "types": "dist/index.d.ts" } +// @Filename: /home/src/workspaces/project/node_modules/react-hook-form/dist/index.d.ts +export * from "./useForm"; +// @Filename: /home/src/workspaces/project/node_modules/react-hook-form/dist/useForm.d.ts +export declare function useForm(): void; +// @Filename: /home/src/workspaces/project/index.ts +useForm/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { useForm } from "react-hook-form"; + +useForm`, + `import { useForm } from "react-hook-form/dist/useForm"; + +useForm`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go b/internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go new file mode 100644 index 0000000000..9f7d4698f6 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportProvider_pnpm_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 TestAutoImportProvider_pnpm(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /home/src/workspaces/project/tsconfig.json +{ "compilerOptions": { "module": "commonjs" } } +// @Filename: /home/src/workspaces/project/package.json +{ "dependencies": { "mobx": "*" } } +// @Filename: /home/src/workspaces/project/node_modules/.pnpm/mobx@6.0.4/node_modules/mobx/package.json +{ "types": "dist/mobx.d.ts" } +// @Filename: /home/src/workspaces/project/node_modules/.pnpm/mobx@6.0.4/node_modules/mobx/dist/mobx.d.ts +export declare function autorun(): void; +// @Filename: /home/src/workspaces/project/index.ts +autorun/**/ +// @link: /home/src/workspaces/project/node_modules/.pnpm/mobx@6.0.4/node_modules/mobx -> /home/src/workspaces/project/node_modules/mobx` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { autorun } from "mobx"; + +autorun`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go b/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go new file mode 100644 index 0000000000..3c2e74a682 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go @@ -0,0 +1,54 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportSortCaseSensitivity1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /exports1.ts +export const a = 0; +export const A = 1; +export const b = 2; +export const B = 3; +export const c = 4; +export const C = 5; +// @Filename: /exports2.ts +export const d = 0; +export const D = 1; +export const e = 2; +export const E = 3; +// @Filename: /index0.ts +import { A, B, C } from "./exports1"; +a/*0*/ +// @Filename: /index1.ts +import { A, a, B, b } from "./exports1"; +import { E } from "./exports2"; +d/*1*/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "0") + f.VerifyImportFixAtPosition(t, []string{ + `import { a, A, B, C } from "./exports1"; +a`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { a, A, B, C } from "./exports1"; +a`, + }, nil /*preferences*/) + f.GoToMarker(t, "1") + f.VerifyImportFixAtPosition(t, []string{ + `import { A, a, B, b } from "./exports1"; +import { d, E } from "./exports2"; +d`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { A, a, B, b } from "./exports1"; +import { E, d } from "./exports2"; +d`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go b/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go new file mode 100644 index 0000000000..3ff780778d --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go @@ -0,0 +1,31 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportSymlinkCaseSensitive(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /tsconfig.json +{ "compilerOptions": { "module": "commonjs" } } +// @Filename: /node_modules/.pnpm/mobx@6.0.4/node_modules/MobX/Foo.d.ts +export declare function autorun(): void; +// @Filename: /index.ts +autorun/**/ +// @Filename: /utils.ts +import "MobX/Foo"; +// @link: /node_modules/.pnpm/mobx@6.0.4/node_modules/MobX -> /node_modules/MobX +// @link: /node_modules/.pnpm/mobx@6.0.4/node_modules/MobX -> /node_modules/.pnpm/cool-mobx-dependent@1.2.3/node_modules/MobX` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { autorun } from "MobX/Foo"; + +autorun`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportTypeImport1_test.go b/internal/fourslash/tests/gen/autoImportTypeImport1_test.go new file mode 100644 index 0000000000..e9da922dd9 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportTypeImport1_test.go @@ -0,0 +1,42 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportTypeImport1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @verbatimModuleSyntax: true +// @target: esnext +// @Filename: /foo.ts +export const A = 1; +export type B = { x: number }; +export type C = 1; +export class D = { y: string }; +// @Filename: /test.ts +import { A, D, type C } from './foo'; +const b: B/**/ | C; +console.log(A, D);` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { A, D, type C, type B } from './foo'; +const b: B | C; +console.log(A, D);`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { A, D, type B, type C } from './foo'; +const b: B | C; +console.log(A, D);`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { A, D, type C, type B } from './foo'; +const b: B | C; +console.log(A, D);`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportTypeImport2_test.go b/internal/fourslash/tests/gen/autoImportTypeImport2_test.go new file mode 100644 index 0000000000..571315406c --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportTypeImport2_test.go @@ -0,0 +1,42 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportTypeImport2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @verbatimModuleSyntax: true +// @target: esnext +// @Filename: /foo.ts +export const A = 1; +export type B = { x: number }; +export type C = 1; +export class D = { y: string }; +// @Filename: /test.ts +import { A, type C, D } from './foo'; +const b: B/**/ | C; +console.log(A, D);` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { A, type B, type C, D } from './foo'; +const b: B | C; +console.log(A, D);`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { A, type C, D, type B } from './foo'; +const b: B | C; +console.log(A, D);`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { A, type C, D, type B } from './foo'; +const b: B | C; +console.log(A, D);`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportTypeImport3_test.go b/internal/fourslash/tests/gen/autoImportTypeImport3_test.go new file mode 100644 index 0000000000..67432c61fd --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportTypeImport3_test.go @@ -0,0 +1,42 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportTypeImport3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @verbatimModuleSyntax: true +// @target: esnext +// @Filename: /foo.ts +export const A = 1; +export type B = { x: number }; +export type C = 1; +export class D = { y: string }; +// @Filename: /test.ts +import { A, type B, type C } from './foo'; +const b: B | C; +console.log(A, D/**/);` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { A, D, type B, type C } from './foo'; +const b: B | C; +console.log(A, D);`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { A, type B, type C, D } from './foo'; +const b: B | C; +console.log(A, D);`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { A, type B, type C, D } from './foo'; +const b: B | C; +console.log(A, D);`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportTypeImport4_test.go b/internal/fourslash/tests/gen/autoImportTypeImport4_test.go new file mode 100644 index 0000000000..33ccd2d46d --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportTypeImport4_test.go @@ -0,0 +1,123 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportTypeImport4(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @verbatimModuleSyntax: true +// @target: esnext +// @Filename: /exports1.ts +export const a = 0; +export const A = 1; +export const b = 2; +export const B = 3; +export const c = 4; +export const C = 5; +export type x = 6; +export const X = 7; +export const Y = 8; +export const Z = 9; +// @Filename: /exports2.ts +export const d = 0; +export const D = 1; +export const e = 2; +export const E = 3; +// @Filename: /index0.ts +import { A, B, C } from "./exports1"; +a/*0*//*0a*/; +b; +// @Filename: /index1.ts +import { A, B, C, type Y, type Z } from "./exports1"; +a/*1*//*1a*//*1b*//*1c*/; +b; +// @Filename: /index2.ts +import { A, a, B, b, type Y, type Z } from "./exports1"; +import { E } from "./exports2"; +d/*2*//*2a*//*2b*//*2c*/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "0") + f.VerifyImportFixAtPosition(t, []string{ + `import { a, A, B, C } from "./exports1"; +a; +b;`, + `import { A, b, B, C } from "./exports1"; +a; +b;`, + }, nil /*preferences*/) + f.GoToMarker(t, "0a") + f.VerifyImportFixAtPosition(t, []string{ + `import { a, A, B, C } from "./exports1"; +a; +b;`, + `import { A, b, B, C } from "./exports1"; +a; +b;`, + }, nil /*preferences*/) + f.GoToMarker(t, "1") + f.VerifyImportFixAtPosition(t, []string{ + `import { a, A, B, C, type Y, type Z } from "./exports1"; +a; +b;`, + `import { A, b, B, C, type Y, type Z } from "./exports1"; +a; +b;`, + }, nil /*preferences*/) + f.GoToMarker(t, "1a") + f.VerifyImportFixAtPosition(t, []string{ + `import { a, A, B, C, type Y, type Z } from "./exports1"; +a; +b;`, + `import { A, b, B, C, type Y, type Z } from "./exports1"; +a; +b;`, + }, nil /*preferences*/) + f.GoToMarker(t, "1b") + f.VerifyImportFixAtPosition(t, []string{ + `import { a, A, B, C, type Y, type Z } from "./exports1"; +a; +b;`, + `import { A, b, B, C, type Y, type Z } from "./exports1"; +a; +b;`, + }, nil /*preferences*/) + f.GoToMarker(t, "1c") + f.VerifyImportFixAtPosition(t, []string{ + `import { a, A, B, C, type Y, type Z } from "./exports1"; +a; +b;`, + `import { A, b, B, C, type Y, type Z } from "./exports1"; +a; +b;`, + }, nil /*preferences*/) + f.GoToMarker(t, "2") + f.VerifyImportFixAtPosition(t, []string{ + `import { A, a, B, b, type Y, type Z } from "./exports1"; +import { d, E } from "./exports2"; +d`, + }, nil /*preferences*/) + f.GoToMarker(t, "2a") + f.VerifyImportFixAtPosition(t, []string{ + `import { A, a, B, b, type Y, type Z } from "./exports1"; +import { E, d } from "./exports2"; +d`, + }, nil /*preferences*/) + f.GoToMarker(t, "2b") + f.VerifyImportFixAtPosition(t, []string{ + `import { A, a, B, b, type Y, type Z } from "./exports1"; +import { d, E } from "./exports2"; +d`, + }, nil /*preferences*/) + f.GoToMarker(t, "2c") + f.VerifyImportFixAtPosition(t, []string{ + `import { A, a, B, b, type Y, type Z } from "./exports1"; +import { E, d } from "./exports2"; +d`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportTypeImport5_test.go b/internal/fourslash/tests/gen/autoImportTypeImport5_test.go new file mode 100644 index 0000000000..85077ac85c --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportTypeImport5_test.go @@ -0,0 +1,108 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportTypeImport5(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @verbatimModuleSyntax: true +// @target: esnext +// @Filename: /exports1.ts +export const a = 0; +export const A = 1; +export const b = 2; +export const B = 3; +export const c = 4; +export const C = 5; +export type x = 6; +export const X = 7; +export type y = 8 +export const Y = 9; +export const Z = 10; +// @Filename: /exports2.ts +export const d = 0; +export const D = 1; +export const e = 2; +export const E = 3; +// @Filename: /index0.ts +import { type X, type Y, type Z } from "./exports1"; +const foo: x/*0*/; +const bar: y; +// @Filename: /index1.ts +import { A, B, type X, type Y, type Z } from "./exports1"; +const foo: x/*1*/; +const bar: y;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "0") + f.VerifyImportFixAtPosition(t, []string{ + `import { type x, type X, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + `import { type X, type y, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { type x, type X, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + `import { type X, type y, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { type x, type X, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + `import { type X, type y, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { type x, type X, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + `import { type X, type y, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { type x, type X, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + `import { type X, type y, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { type x, type X, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + `import { type X, type y, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + }, nil /*preferences*/) + f.GoToMarker(t, "1") + f.VerifyImportFixAtPosition(t, []string{ + `import { A, B, type x, type X, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + `import { A, B, type X, type y, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { A, B, type x, type X, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + `import { A, B, type X, type y, type Y, type Z } from "./exports1"; +const foo: x; +const bar: y;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go b/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go new file mode 100644 index 0000000000..857cd76d56 --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go @@ -0,0 +1,50 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportTypeOnlyPreferred2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /node_modules/react/index.d.ts +export interface ComponentType {} +export interface ComponentProps {} +export declare function useState(initialState: T): [T, (newState: T) => void]; +export declare function useEffect(callback: () => void, deps: any[]): void; +// @Filename: /main.ts +import type { ComponentType } from "react"; +import { useState } from "react"; + +export function Component({ prop } : { prop: ComponentType }) { + const codeIsUnimportant = useState(1); + useEffect/*1*/(() => {}, []); +} +// @Filename: /main2.ts +import { useState } from "react"; +import type { ComponentType } from "react"; + +type _ = ComponentProps/*2*/;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "1") + f.VerifyImportFixAtPosition(t, []string{ + `import type { ComponentType } from "react"; +import { useEffect, useState } from "react"; + +export function Component({ prop } : { prop: ComponentType }) { + const codeIsUnimportant = useState(1); + useEffect(() => {}, []); +}`, + }, nil /*preferences*/) + f.GoToMarker(t, "2") + f.VerifyImportFixAtPosition(t, []string{ + `import { useState } from "react"; +import type { ComponentProps, ComponentType } from "react"; + +type _ = ComponentProps;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/autoImportsNodeNext1_test.go b/internal/fourslash/tests/gen/autoImportsNodeNext1_test.go new file mode 100644 index 0000000000..a174ed157c --- /dev/null +++ b/internal/fourslash/tests/gen/autoImportsNodeNext1_test.go @@ -0,0 +1,47 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + . "github.com/microsoft/typescript-go/internal/fourslash/tests/util" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestAutoImportsNodeNext1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: node18 +// @Filename: /node_modules/pack/package.json +{ + "name": "pack", + "version": "1.0.0", + "exports": { + ".": "./main.mjs" + } +} +// @Filename: /node_modules/pack/main.d.mts +import {} from "./unreachable.mjs"; +export const fromMain = 0; +// @Filename: /node_modules/pack/unreachable.d.mts +export const fromUnreachable = 0; +// @Filename: /index.mts +import { fromMain } from "pack"; +fromUnreachable/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{}, nil /*preferences*/) + f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{ + IsIncomplete: false, + ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{ + CommitCharacters: &DefaultCommitCharacters, + EditRange: Ignored, + }, + Items: &fourslash.CompletionsExpectedItems{ + Excludes: []string{ + "fromUnreachable", + }, + }, + }) +} diff --git a/internal/fourslash/tests/gen/importFixWithMultipleModuleExportAssignment_test.go b/internal/fourslash/tests/gen/importFixWithMultipleModuleExportAssignment_test.go new file mode 100644 index 0000000000..e0f9edde84 --- /dev/null +++ b/internal/fourslash/tests/gen/importFixWithMultipleModuleExportAssignment_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 TestImportFixWithMultipleModuleExportAssignment(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: esnext +// @allowJs: true +// @checkJs: true +// @Filename: /a.js +function f() {} +module.exports = f; +module.exports = 42; +// @Filename: /b.js +export const foo = 0; +// @Filename: /c.js +foo` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/c.js") + f.VerifyImportFixAtPosition(t, []string{ + `const { foo } = require("./b"); + +foo`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go b/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go new file mode 100644 index 0000000000..20d5b30843 --- /dev/null +++ b/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go @@ -0,0 +1,33 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportFixesGlobalTypingsCache(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /project/tsconfig.json + { "compilerOptions": { "allowJs": true, "checkJs": true } } +// @Filename: /home/src/Library/Caches/typescript/node_modules/@types/react-router-dom/package.json + { "name": "@types/react-router-dom", "version": "16.8.4", "types": "index.d.ts" } +// @Filename: /home/src/Library/Caches/typescript/node_modules/@types/react-router-dom/index.d.ts +export class BrowserRouter {} +// @Filename: /project/node_modules/react-router-dom/package.json + { "name": "react-router-dom", "version": "16.8.4", "main": "index.js" } +// @Filename: /project/node_modules/react-router-dom/index.js + export const BrowserRouter = () => null; +// @Filename: /project/index.js +BrowserRouter/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/project/index.js") + f.VerifyImportFixAtPosition(t, []string{ + `const { BrowserRouter } = require("react-router-dom"); + +BrowserRouter`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importFixes_quotePreferenceDouble_importHelpers_test.go b/internal/fourslash/tests/gen/importFixes_quotePreferenceDouble_importHelpers_test.go new file mode 100644 index 0000000000..06b9436e0a --- /dev/null +++ b/internal/fourslash/tests/gen/importFixes_quotePreferenceDouble_importHelpers_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 TestImportFixes_quotePreferenceDouble_importHelpers(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @importHelpers: true +// @filename: /a.ts +export default () => {}; +// @filename: /b.ts +export default () => {}; +// @filename: /test.ts +import a from "./a"; +[|b|];` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/test.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import b from "./b"; +b`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importFixes_quotePreferenceSingle_importHelpers_test.go b/internal/fourslash/tests/gen/importFixes_quotePreferenceSingle_importHelpers_test.go new file mode 100644 index 0000000000..228e3087e2 --- /dev/null +++ b/internal/fourslash/tests/gen/importFixes_quotePreferenceSingle_importHelpers_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 TestImportFixes_quotePreferenceSingle_importHelpers(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @importHelpers: true +// @filename: /a.ts +export default () => {}; +// @filename: /b.ts +export default () => {}; +// @filename: /test.ts +import a from './a'; +[|b|];` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/test.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import b from './b'; +b`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go b/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go new file mode 100644 index 0000000000..3857963f27 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_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 TestImportNameCodeFixConvertTypeOnly1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +export class A {} +export class B {} +// @Filename: /b.ts +import type { A } from './a'; +new B` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { B, type A } from './a'; +new B`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport1_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport1_test.go new file mode 100644 index 0000000000..52cea508c2 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport1_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 TestImportNameCodeFixDefaultExport1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /foo-bar.ts +export default function fooBar(); +// @Filename: /b.ts +[|import * as fb from "./foo-bar"; +foo/**/Bar|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import fooBar, * as fb from "./foo-bar"; +fooBar`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport2_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport2_test.go new file mode 100644 index 0000000000..de4fe9d2f6 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport2_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 TestImportNameCodeFixDefaultExport2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /lib.ts +class Base { } +export default Base; +// @Filename: /test.ts +[|class Derived extends Base { }|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/test.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import Base from "./lib"; + +class Derived extends Base { }`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport3_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport3_test.go new file mode 100644 index 0000000000..51fb3c50a6 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport3_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 TestImportNameCodeFixDefaultExport3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /foo-bar/index.ts +export default 0; +// @Filename: /b.ts +[|foo/**/Bar|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import fooBar from "./foo-bar"; + +fooBar`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport4_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport4_test.go new file mode 100644 index 0000000000..7b911543b5 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport4_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 TestImportNameCodeFixDefaultExport4(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /foo.ts +const a = () => {}; +export default a; +// @Filename: /test.ts +[|foo|];` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/test.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import foo from "./foo"; + +foo`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport5_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport5_test.go new file mode 100644 index 0000000000..c06e07ba0e --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport5_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 TestImportNameCodeFixDefaultExport5(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @moduleResolution: bundler +// @Filename: /node_modules/hooks/useFoo.ts +declare const _default: () => void; +export default _default; +// @Filename: /test.ts +[|useFoo|];` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/test.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import useFoo from "hooks/useFoo"; + +useFoo`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport7_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport7_test.go new file mode 100644 index 0000000000..1ca3fbf64a --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport7_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 TestImportNameCodeFixDefaultExport7(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @lib: dom +// @Filename: foo.ts +export default globalThis.localStorage; +// @Filename: index.ts +foo/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import foo from "./foo"; + +foo`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport_test.go new file mode 100644 index 0000000000..32c7ac6873 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport_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 TestImportNameCodeFixDefaultExport(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /foo-bar.ts +export default 0; +// @Filename: /b.ts +[|foo/**/Bar|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import fooBar from "./foo-bar"; + +fooBar`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport0_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport0_test.go new file mode 100644 index 0000000000..4553d948be --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport0_test.go @@ -0,0 +1,23 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixExistingImport0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `import [|{ v1 }|] from "./module"; +f1/*0*/(); +// @Filename: module.ts +export function f1() {} +export var v1 = 5;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `{ f1, v1 }`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go new file mode 100644 index 0000000000..b42825386b --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_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 TestImportNameCodeFixExistingImport10(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `import [|{ + v1, + v2 +}|] from "./module"; +f1/*0*/(); +// @Filename: module.ts +export function f1() {} +export var v1 = 5; +export var v2 = 5; +export var v3 = 5;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `{ + f1, + v1, + v2 +}`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go new file mode 100644 index 0000000000..dfb88bffd3 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_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 TestImportNameCodeFixExistingImport11(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `import [|{ + v1, v2, + v3 +}|] from "./module"; +f1/*0*/(); +// @Filename: module.ts + export function f1() {} + export var v1 = 5; + export var v2 = 5; + export var v3 = 5;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `{ + f1, + v1, v2, + v3 +}`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport12_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport12_test.go new file mode 100644 index 0000000000..9b5c7e8d75 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport12_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 TestImportNameCodeFixExistingImport12(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `import [|{}|] from "./module"; +f1/*0*/(); +// @Filename: module.ts +export function f1() {} +export var v1 = 5; +export var v2 = 5; +export var v3 = 5;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `{ f1 }`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport1_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport1_test.go new file mode 100644 index 0000000000..31c9f9ea01 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport1_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 TestImportNameCodeFixExistingImport1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `import d, [|{ v1 }|] from "./module"; +f1/*0*/(); +// @Filename: module.ts +export function f1() {} +export var v1 = 5; +export default var d1 = 6;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `{ f1, v1 }`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport2_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport2_test.go new file mode 100644 index 0000000000..0602242203 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport2_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 TestImportNameCodeFixExistingImport2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `import * as ns from "./module"; +// Comment +f1/*0*/(); +// @Filename: module.ts + export function f1() {} + export var v1 = 5;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import * as ns from "./module"; +// Comment +ns.f1();`, + `import * as ns from "./module"; +import { f1 } from "./module"; +// Comment +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport3_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport3_test.go new file mode 100644 index 0000000000..041f86f0e2 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport3_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 TestImportNameCodeFixExistingImport3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|import d, * as ns from "./module" ; +f1/*0*/();|] +// @Filename: module.ts +export function f1() {} +export var v1 = 5; +export default var d1 = 6;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import d, * as ns from "./module" ; +ns.f1();`, + `import d, * as ns from "./module" ; +import { f1 } from "./module"; +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport4_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport4_test.go new file mode 100644 index 0000000000..19e959db2d --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport4_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 TestImportNameCodeFixExistingImport4(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|import d from "./module"; +f1/*0*/();|] +// @Filename: module.ts +export function f1() {} +export var v1 = 5; +export default var d1 = 6;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import d, { f1 } from "./module"; +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go new file mode 100644 index 0000000000..31610760a8 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_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 TestImportNameCodeFixExistingImport5(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|import "./module"; +f1/*0*/();|] +// @Filename: module.ts +export function f1() {} +export var v1 = 5;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import "./module"; +import { f1 } from "./module"; +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport6_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport6_test.go new file mode 100644 index 0000000000..bc15f5e573 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport6_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 TestImportNameCodeFixExistingImport6(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `import [|{ v1 }|] from "fake-module"; +f1/*0*/(); +// @Filename: ../package.json +{ "dependencies": { "fake-module": "latest" } } +// @Filename: ../node_modules/fake-module/index.ts +export var v1 = 5; +export function f1();` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `{ f1, v1 }`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport7_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport7_test.go new file mode 100644 index 0000000000..e82d0ed3fd --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport7_test.go @@ -0,0 +1,23 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixExistingImport7(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `import [|{ v1 }|] from "../other_dir/module"; +f1/*0*/(); +// @Filename: ../other_dir/module.ts +export var v1 = 5; +export function f1();` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `{ f1, v1 }`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go new file mode 100644 index 0000000000..4daee97cc0 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_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 TestImportNameCodeFixExistingImport8(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `import [|{v1, v2, v3,}|] from "./module"; +v4/*0*/(); +// @Filename: module.ts +export function v4() {} +export var v1 = 5; +export var v2 = 5; +export var v3 = 5;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `{v1, v2, v3, v4,}`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go new file mode 100644 index 0000000000..cde3b9619e --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_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 TestImportNameCodeFixExistingImport9(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `import [|{ + v1 +}|] from "./module"; +f1/*0*/(); +// @Filename: module.ts +export function f1() {} +export var v1 = 5;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `{ + f1, + v1 +}`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go new file mode 100644 index 0000000000..99c363b38e --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_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 TestImportNameCodeFixExistingImportEquals0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|import ns = require("ambient-module"); +var x = v1/*0*/ + 5;|] +// @Filename: ambientModule.ts +declare module "ambient-module" { + export function f1(); + export var v1; +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import ns = require("ambient-module"); +var x = ns.v1 + 5;`, + `import { v1 } from "ambient-module"; +import ns = require("ambient-module"); +var x = v1 + 5;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExportAsDefaultExistingImport_test.go b/internal/fourslash/tests/gen/importNameCodeFixExportAsDefaultExistingImport_test.go new file mode 100644 index 0000000000..97df987bbe --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixExportAsDefaultExistingImport_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 TestImportNameCodeFixExportAsDefaultExistingImport(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `import [|{ v1, v2, v3 }|] from "./module"; +v4/*0*/(); +// @Filename: module.ts +const v4 = 5; +export { v4 as default }; +export const v1 = 5; +export const v2 = 5; +export const v3 = 5;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `v4, { v1, v2, v3 }`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixIndentedIdentifier_test.go b/internal/fourslash/tests/gen/importNameCodeFixIndentedIdentifier_test.go new file mode 100644 index 0000000000..b5c0e91aec --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixIndentedIdentifier_test.go @@ -0,0 +1,33 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixIndentedIdentifier(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +[|import * as b from "./b"; +{ + x/**/ +}|] +// @Filename: /b.ts +export const x = 0;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import * as b from "./b"; +{ + b.x +}`, + `import * as b from "./b"; +import { x } from "./b"; +{ + x +}`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports0_test.go new file mode 100644 index 0000000000..4c8fc42141 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports0_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 TestImportNameCodeFixNewImportAllowSyntheticDefaultImports0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @AllowSyntheticDefaultImports: true +// @Filename: a/f1.ts +[|export var x = 0; +bar/*0*/();|] +// @Filename: a/foo.d.ts +declare function bar(): number; +export = bar; +export as namespace bar;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import bar from "./foo"; + +export var x = 0; +bar();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports1_test.go new file mode 100644 index 0000000000..4e197d35c8 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports1_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 TestImportNameCodeFixNewImportAllowSyntheticDefaultImports1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Module: system +// @Filename: a/f1.ts +[|export var x = 0; +bar/*0*/();|] +// @Filename: a/foo.d.ts +declare function bar(): number; +export = bar; +export as namespace bar;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import bar from "./foo"; + +export var x = 0; +bar();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports2_test.go new file mode 100644 index 0000000000..3b3daf56b3 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports2_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 TestImportNameCodeFixNewImportAllowSyntheticDefaultImports2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @AllowSyntheticDefaultImports: false +// @Module: system +// @Filename: a/f1.ts +[|export var x = 0; +bar/*0*/();|] +// @Filename: a/foo.d.ts +declare function bar(): number; +export = bar; +export as namespace bar;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import * as bar from "./foo"; + +export var x = 0; +bar();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports3_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports3_test.go new file mode 100644 index 0000000000..4da5bbf181 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports3_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 TestImportNameCodeFixNewImportAllowSyntheticDefaultImports3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @AllowSyntheticDefaultImports: false +// @Module: commonjs +// @Filename: a/f1.ts +[|export var x = 0; +bar/*0*/();|] +// @Filename: a/foo.d.ts +declare function bar(): number; +export = bar; +export as namespace bar;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import bar = require("./foo"); + +export var x = 0; +bar();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports4_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports4_test.go new file mode 100644 index 0000000000..8611d94c55 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports4_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 TestImportNameCodeFixNewImportAllowSyntheticDefaultImports4(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @AllowSyntheticDefaultImports: false +// @Module: amd +// @Filename: a/f1.ts +[|export var x = 0; +bar/*0*/();|] +// @Filename: a/foo.d.ts +declare function bar(): number; +export = bar; +export as namespace bar;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import bar = require("./foo"); + +export var x = 0; +bar();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports5_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports5_test.go new file mode 100644 index 0000000000..97912e6a85 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports5_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 TestImportNameCodeFixNewImportAllowSyntheticDefaultImports5(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @AllowSyntheticDefaultImports: false +// @Module: umd +// @Filename: a/f1.ts +[|export var x = 0; +bar/*0*/();|] +// @Filename: a/foo.d.ts +declare function bar(): number; +export = bar; +export as namespace bar;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import bar = require("./foo"); + +export var x = 0; +bar();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient0_test.go new file mode 100644 index 0000000000..3b2776f970 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient0_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 TestImportNameCodeFixNewImportAmbient0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|f1/*0*/();|] +// @Filename: ambientModule.ts +declare module "ambient-module" { + export function f1(); + export var v1; +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "ambient-module"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go new file mode 100644 index 0000000000..3e8b1ed313 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_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 TestImportNameCodeFixNewImportAmbient1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `import d from "other-ambient-module"; +import * as ns from "yet-another-ambient-module"; +var x = v1/*0*/ + 5; +// @Filename: ambientModule.ts +declare module "ambient-module" { + export function f1(); + export var v1; +} +// @Filename: otherAmbientModule.ts +declare module "other-ambient-module" { + export default function f2(); +} +// @Filename: yetAnotherAmbientModule.ts +declare module "yet-another-ambient-module" { + export function f3(); + export var v3; +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { v1 } from "ambient-module"; +import d from "other-ambient-module"; +import * as ns from "yet-another-ambient-module"; +var x = v1 + 5;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient2_test.go new file mode 100644 index 0000000000..592328caa5 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient2_test.go @@ -0,0 +1,33 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportAmbient2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|/*! + * I'm a license or something + */ +f1/*0*/();|] +// @Filename: ambientModule.ts + declare module "ambient-module" { + export function f1(); + export var v1; + }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `/*! + * I'm a license or something + */ + +import { f1 } from "ambient-module"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go new file mode 100644 index 0000000000..edf25cbed7 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go @@ -0,0 +1,40 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportAmbient3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `let a = "I am a non-trivial statement that appears before imports"; +import d from "other-ambient-module" +import * as ns from "yet-another-ambient-module" +var x = v1/*0*/ + 5; +// @Filename: ambientModule.ts +declare module "ambient-module" { + export function f1(); + export var v1; +} +// @Filename: otherAmbientModule.ts +declare module "other-ambient-module" { + export default function f2(); +} +// @Filename: yetAnotherAmbientModule.ts +declare module "yet-another-ambient-module" { + export function f3(); + export var v3; +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `let a = "I am a non-trivial statement that appears before imports"; +import { v1 } from "ambient-module"; +import d from "other-ambient-module" +import * as ns from "yet-another-ambient-module" +var x = v1 + 5;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go new file mode 100644 index 0000000000..526c1daebe --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_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 TestImportNameCodeFixNewImportBaseUrl0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|f1/*0*/();|] +// @Filename: tsconfig.json +{ + "compilerOptions": { + "baseUrl": "./a" + } +} +// @Filename: a/b.ts +export function f1() { };` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "b"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go new file mode 100644 index 0000000000..6053cd87f2 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go @@ -0,0 +1,36 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportBaseUrl1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /tsconfig.json +{ + "compilerOptions": { + "baseUrl": "./a" + } +} +// @Filename: /a/b/x.ts +export function f1() { }; +// @Filename: /a/b/y.ts +[|f1/*0*/();|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/a/b/y.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "./x"; + +f1();`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "b/x"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go new file mode 100644 index 0000000000..d08006e545 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go @@ -0,0 +1,36 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportBaseUrl2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /tsconfig.json +{ + "compilerOptions": { + "baseUrl": "./a" + } +} +// @Filename: /a/b/x.ts +export function f1() { }; +// @Filename: /a/c/y.ts +[|f1/*0*/();|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/a/c/y.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "b/x"; + +f1();`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "../b/x"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportDefault0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportDefault0_test.go new file mode 100644 index 0000000000..f74774cf90 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportDefault0_test.go @@ -0,0 +1,23 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportDefault0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|f1/*0*/();|] +// @Filename: module.ts +export default function f1() { };` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import f1 from "./module"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsCommonJSInteropOn_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsCommonJSInteropOn_test.go new file mode 100644 index 0000000000..b058fb5b34 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsCommonJSInteropOn_test.go @@ -0,0 +1,62 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportExportEqualsCommonJSInteropOn(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Module: commonjs +// @EsModuleInterop: true +// @Filename: /foo.d.ts +declare module "bar" { + const bar: number; + export = bar; +} +declare module "foo" { + const foo: number; + export = foo; +} +declare module "es" { + const es = 0; + export default es; +} +// @Filename: /a.ts +import bar = require("bar"); + +foo +// @Filename: /b.ts +foo +// @Filename: /c.ts +import es from "es"; +import bar = require("bar"); + +foo` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/a.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import bar = require("bar"); +import foo = require("foo"); + +foo`, + }, nil /*preferences*/) + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import foo from "foo"; + +foo`, + }, nil /*preferences*/) + f.GoToFile(t, "/c.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import es from "es"; +import bar = require("bar"); +import foo = require("foo"); + +foo`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsESNextInteropOff_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsESNextInteropOff_test.go new file mode 100644 index 0000000000..b8b70b3191 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsESNextInteropOff_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 TestImportNameCodeFixNewImportExportEqualsESNextInteropOff(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Module: esnext +// @Filename: /foo.d.ts +declare module "foo" { + const foo: number; + export = foo; +} +// @Filename: /index.ts +foo` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/index.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import foo from "foo"; + +foo`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsESNextInteropOn_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsESNextInteropOn_test.go new file mode 100644 index 0000000000..acb8eaf0d3 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsESNextInteropOn_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 TestImportNameCodeFixNewImportExportEqualsESNextInteropOn(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @EsModuleInterop: true +// @Module: es2015 +// @Filename: /foo.d.ts +declare module "foo" { + const foo: number; + export = foo; +} +// @Filename: /index.ts +[|foo|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/index.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import foo from "foo"; + +foo`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFile0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile0_test.go new file mode 100644 index 0000000000..b72c4f7f00 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile0_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 TestImportNameCodeFixNewImportFile0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|f1/*0*/();|] +// @Filename: jalapeño.ts +export function f1() {} +export var v1 = 5;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "./jalapeño"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFile1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile1_test.go new file mode 100644 index 0000000000..a4babb34d7 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile1_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 TestImportNameCodeFixNewImportFile1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|/// +f1/*0*/();|] +// @Filename: Module.ts +export function f1() {} +export var v1 = 5; +// @Filename: tripleSlashReference.ts +var x = 5;/*dummy*/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `/// + +import { f1 } from "./Module"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go new file mode 100644 index 0000000000..1312e65b50 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_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 TestImportNameCodeFixNewImportFile2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|f1/*0*/();|] +// @Filename: ../../other_dir/module.ts +export var v1 = 5; +export function f1();` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "../../other_dir/module"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFile3_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile3_test.go new file mode 100644 index 0000000000..056d7c4900 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile3_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 TestImportNameCodeFixNewImportFile3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|let t: XXX/*0*/.I;|] +// @Filename: ./module.ts +export module XXX { + export interface I { + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { XXX } from "./module"; + +let t: XXX.I;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFile4_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile4_test.go new file mode 100644 index 0000000000..d1adddbd81 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile4_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 TestImportNameCodeFixNewImportFile4(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|let t: A/*0*/.B.I;|] +// @Filename: ./module.ts +export namespace A { + export namespace B { + export interface I { } + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { A } from "./module"; + +let t: A.B.I;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileAllComments_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileAllComments_test.go new file mode 100644 index 0000000000..f80f1c7ec9 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileAllComments_test.go @@ -0,0 +1,47 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportFileAllComments(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|/*! + * This is a license or something + */ +/// +/// +/// +/** + * This is a comment intended to be attached to this interface + */ +export interface SomeInterface { +} +f1/*0*/();|] +// @Filename: module.ts +export function f1() {} +export var v1 = 5;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `/*! + * This is a license or something + */ +/// +/// +/// + +import { f1 } from "./module"; + +/** + * This is a comment intended to be attached to this interface + */ +export interface SomeInterface { +} +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileDetachedComments_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileDetachedComments_test.go new file mode 100644 index 0000000000..9cb3620715 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileDetachedComments_test.go @@ -0,0 +1,34 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportFileDetachedComments(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|/** + * This is a comment intended to be attached to this interface + */ +export interface SomeInterface { +} +f1/*0*/();|] +// @Filename: module.ts +export function f1() {} +export var v1 = 5;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "./module"; + +/** + * This is a comment intended to be attached to this interface + */ +export interface SomeInterface { +} +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go new file mode 100644 index 0000000000..a8d873a59c --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_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 TestImportNameCodeFixNewImportFileQuoteStyle0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|import { v2 } from './module2'; + +f1/*0*/();|] +// @Filename: module1.ts +export function f1() {} +// @Filename: module2.ts +export var v2 = 6;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from './module1'; +import { v2 } from './module2'; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go new file mode 100644 index 0000000000..242da68c11 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_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 TestImportNameCodeFixNewImportFileQuoteStyle1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|import { v2 } from "./module2"; + +f1/*0*/();|] +// @Filename: module1.ts +export function f1() {} +// @Filename: module2.ts +export var v2 = 6;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "./module1"; +import { v2 } from "./module2"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go new file mode 100644 index 0000000000..7f071b8907 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_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 TestImportNameCodeFixNewImportFileQuoteStyle2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|import m2 = require('./module2'); + +f1/*0*/();|] +// @Filename: module1.ts +export function f1() {} +// @Filename: module2.ts +export var v2 = 6;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from './module1'; +import m2 = require('./module2'); + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle3_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle3_test.go new file mode 100644 index 0000000000..f7799d0470 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle3_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 TestImportNameCodeFixNewImportFileQuoteStyle3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|export { v2 } from './module2'; + +f1/*0*/();|] +// @Filename: module1.ts +export function f1() {} +// @Filename: module2.ts +export var v2 = 6;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from './module1'; + +export { v2 } from './module2'; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go new file mode 100644 index 0000000000..f46ecf26da --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_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 TestImportNameCodeFixNewImportFileQuoteStyleMixed0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|import { v2 } from "./module2"; +import { v3 } from './module3'; + +f1/*0*/();|] +// @Filename: module1.ts +export function f1() {} +// @Filename: module2.ts +export var v2 = 6; +// @Filename: module3.ts +export var v3 = 6;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "./module1"; +import { v2 } from "./module2"; +import { v3 } from './module3'; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go new file mode 100644 index 0000000000..6ca53ac621 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_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 TestImportNameCodeFixNewImportFileQuoteStyleMixed1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|import { v2 } from './module2'; +import { v3 } from "./module3"; + +f1/*0*/();|] +// @Filename: module1.ts +export function f1() {} +// @Filename: module2.ts +export var v2 = 6; +// @Filename: module3.ts +export var v3 = 6;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from './module1'; +import { v2 } from './module2'; +import { v3 } from "./module3"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFromAtTypesScopedPackage_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFromAtTypesScopedPackage_test.go new file mode 100644 index 0000000000..1bddf142ab --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFromAtTypesScopedPackage_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 TestImportNameCodeFixNewImportFromAtTypesScopedPackage(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|f1/*0*/();|] +// @Filename: node_modules/@types/myLib__scoped/index.d.ts +export function f1() {} +export var v1 = 5;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "@myLib/scoped"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFromAtTypes_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFromAtTypes_test.go new file mode 100644 index 0000000000..9999dd1b94 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFromAtTypes_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 TestImportNameCodeFixNewImportFromAtTypes(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|f1/*0*/();|] +// @Filename: node_modules/@types/myLib/index.d.ts +export function f1() {} +export var v1 = 5;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "myLib"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_notForClassicResolution_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_notForClassicResolution_test.go new file mode 100644 index 0000000000..28987429d2 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_notForClassicResolution_test.go @@ -0,0 +1,37 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportIndex_notForClassicResolution(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @moduleResolution: classic +// @Filename: /a/index.ts +export const foo = 0; +// @Filename: /node_modules/x/index.d.ts +export const bar = 0; +// @Filename: /b.ts +[|foo;|] +// @Filename: /c.ts +[|bar;|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/a/index.ts") + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "./a/index"; + +foo;`, + }, nil /*preferences*/) + f.GoToFile(t, "/c.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { bar } from "./node_modules/x/index"; + +bar;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_test.go new file mode 100644 index 0000000000..997183b8bb --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_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 TestImportNameCodeFixNewImportIndex(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a/index.ts +export const foo = 0; +// @Filename: /b.ts +[|/**/foo;|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/a/index.ts") + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "./a"; + +foo;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules0_test.go new file mode 100644 index 0000000000..37276238c6 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules0_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 TestImportNameCodeFixNewImportNodeModules0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|f1/*0*/();|] +// @Filename: ../package.json +{ "dependencies": { "fake-module": "latest" } } +// @Filename: ../node_modules/fake-module/index.ts +export var v1 = 5; +export function f1(); +// @Filename: ../node_modules/fake-module/package.json +{}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "fake-module"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules1_test.go new file mode 100644 index 0000000000..36d5ac9762 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules1_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 TestImportNameCodeFixNewImportNodeModules1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|f1/*0*/();|] +// @Filename: ../package.json +{ "dependencies": { "fake-module": "latest" } } +// @Filename: ../node_modules/fake-module/nested.ts +export var v1 = 5; +export function f1();` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "fake-module/nested"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules2_test.go new file mode 100644 index 0000000000..1c3c9f578b --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules2_test.go @@ -0,0 +1,33 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportNodeModules2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|f1/*0*/();|] +// @Filename: ../package.json +{ "dependencies": { "fake-module": "latest" } } +// @Filename: ../node_modules/fake-module/notindex.d.ts +export var v1 = 5; +export function f1(); +// @Filename: ../node_modules/fake-module/notindex.js +module.exports = { + v1: 5, + f1: function () {} +}; +// @Filename: ../node_modules/fake-module/package.json +{ "main":"./notindex.js", "typings":"./notindex.d.ts" }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "fake-module"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules3_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules3_test.go new file mode 100644 index 0000000000..93e39ffc5b --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules3_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 TestImportNameCodeFixNewImportNodeModules3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +[|f1/*0*/();|] +// @Filename: /node_modules/@types/random/index.d.ts +export var v1 = 5; +export function f1();` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "random"; + +f1();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules4_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules4_test.go new file mode 100644 index 0000000000..db140c6eaf --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules4_test.go @@ -0,0 +1,33 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportNodeModules4(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|f1/*0*/('');|] +// @Filename: package.json +{ "dependencies": { "package-name": "latest" } } +// @Filename: node_modules/package-name/bin/lib/libfile.d.ts +export function f1(text: string): string; +// @Filename: node_modules/package-name/bin/lib/libfile.js +function f1(text) { } +exports.f1 = f1; +// @Filename: node_modules/package-name/package.json +{ + "main": "bin/lib/libfile.js", + "types": "bin/lib/libfile.d.ts" +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "package-name"; + +f1('');`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules6_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules6_test.go new file mode 100644 index 0000000000..93c9eb9174 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules6_test.go @@ -0,0 +1,33 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportNodeModules6(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|f1/*0*/('');|] +// @Filename: package.json +{ "dependencies": { "package-name": "latest" } } +// @Filename: node_modules/package-name/bin/lib/index.d.ts +export function f1(text: string): string; +// @Filename: node_modules/package-name/bin/lib/index.js +function f1(text) { } +exports.f1 = f1; +// @Filename: node_modules/package-name/package.json +{ + "main": "bin/lib/index.js", + "types": "bin/lib/index.d.ts" +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "package-name"; + +f1('');`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules7_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules7_test.go new file mode 100644 index 0000000000..3b0216ab89 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules7_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 TestImportNameCodeFixNewImportNodeModules7(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|f1/*0*/('');|] +// @Filename: package.json +{ "dependencies": { "package-name": "0.0.1" } } +// @Filename: node_modules/package-name/bin/lib/libfile.d.ts +export declare function f1(text: string): string; +// @Filename: node_modules/package-name/bin/lib/libfile.js +function f1(text) {} +exports.f1 = f1; +// @Filename: node_modules/package-name/package.json +{ "main": "bin/lib/libfile.js" }` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "package-name"; + +f1('');`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules8_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules8_test.go new file mode 100644 index 0000000000..3be79505b8 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportNodeModules8_test.go @@ -0,0 +1,33 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportNodeModules8(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|f1/*0*/('');|] +// @Filename: package.json +{ "dependencies": { "@scope/package-name": "latest" } } +// @Filename: node_modules/@scope/package-name/bin/lib/index.d.ts +export function f1(text: string): string; +// @Filename: node_modules/@scope/package-name/bin/lib/index.js +function f1(text) { } +exports.f1 = f1; +// @Filename: node_modules/@scope/package-name/package.json +{ + "main": "bin/lib/index.js", + "types": "bin/lib/index.d.ts" +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { f1 } from "@scope/package-name"; + +f1('');`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths0_test.go new file mode 100644 index 0000000000..508996c694 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths0_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 TestImportNameCodeFixNewImportPaths0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|foo/*0*/();|] +// @Filename: folder_a/f2.ts +export function foo() {}; +// @Filename: tsconfig.json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "a": [ "folder_a/f2" ] + } + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "a"; + +foo();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths1_test.go new file mode 100644 index 0000000000..96f8460d4f --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths1_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 TestImportNameCodeFixNewImportPaths1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|foo/*0*/();|] +// @Filename: folder_b/f2.ts +export function foo() {}; +// @Filename: tsconfig.json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "b/*": [ "folder_b/*" ] + } + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "b/f2"; + +foo();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths2_test.go new file mode 100644 index 0000000000..b291f27f7b --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths2_test.go @@ -0,0 +1,37 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportPaths2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `[|foo/*0*/();|] +// @Filename: folder_b/index.ts +export function foo() {}; +// @Filename: tsconfig.path.json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "b": [ "folder_b/index" ] + } + } +} +// @Filename: tsconfig.json +{ + "extends": "./tsconfig.path", + "compilerOptions": { } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "b"; + +foo();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths_withExtension_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths_withExtension_test.go new file mode 100644 index 0000000000..8c137c06c9 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths_withExtension_test.go @@ -0,0 +1,33 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportPaths_withExtension(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /src/a.ts +[|foo|] +// @Filename: /src/thisHasPathMapping.ts +export function foo() {}; +// @Filename: /tsconfig.json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "foo": ["src/thisHasPathMapping.ts"] + } + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "foo"; + +foo`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths_withLeadingDotSlash_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths_withLeadingDotSlash_test.go new file mode 100644 index 0000000000..35d33b1f8d --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths_withLeadingDotSlash_test.go @@ -0,0 +1,33 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportPaths_withLeadingDotSlash(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +[|foo|] +// @Filename: /thisHasPathMapping.ts +export function foo() {}; +// @Filename: /tsconfig.json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "foo": ["././thisHasPathMapping"] + } + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "foo"; + +foo`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths_withParentRelativePath_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths_withParentRelativePath_test.go new file mode 100644 index 0000000000..f52909c872 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportPaths_withParentRelativePath_test.go @@ -0,0 +1,33 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportPaths_withParentRelativePath(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /src/a.ts +[|foo|] +// @Filename: /thisHasPathMapping.ts +export function foo() {}; +// @Filename: /tsconfig.json +{ + "compilerOptions": { + "baseUrl": "src", + "paths": { + "foo": ["..\\thisHasPathMapping"] + } + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "foo"; + +foo`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go new file mode 100644 index 0000000000..910ee7dbaa --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go @@ -0,0 +1,33 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportRootDirs0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: a/f1.ts +[|foo/*0*/();|] +// @Filename: b/c/f2.ts +export function foo() {}; +// @Filename: tsconfig.json +{ + "compilerOptions": { + "rootDirs": [ + "a", + "b/c" + ] + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "./f2"; + +foo();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs1_test.go new file mode 100644 index 0000000000..b122ccd697 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs1_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 TestImportNameCodeFixNewImportRootDirs1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: a/f1.ts +[|foo/*0*/();|] +// @Filename: a/b/index.ts +export function foo() {}; +// @Filename: tsconfig.json +{ + "compilerOptions": { + "rootDirs": [ + "a" + ] + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "./b"; + +foo();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots0_test.go new file mode 100644 index 0000000000..aad50b5007 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots0_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 TestImportNameCodeFixNewImportTypeRoots0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: a/f1.ts +[|foo/*0*/();|] +// @Filename: types/random/index.ts +export function foo() {}; +// @Filename: tsconfig.json +{ + "compilerOptions": { + "typeRoots": [ + "./types" + ] + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "../types/random"; + +foo();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go new file mode 100644 index 0000000000..f3baf33c4a --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go @@ -0,0 +1,33 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixNewImportTypeRoots1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: a/f1.ts +[|foo/*0*/();|] +// @Filename: types/random/index.ts +export function foo() {}; +// @Filename: tsconfig.json +{ + "compilerOptions": { + "baseUrl": ".", + "typeRoots": [ + "./types" + ] + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "types/random"; + +foo();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go new file mode 100644 index 0000000000..38ad76631d --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_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 TestImportNameCodeFixOptionalImport0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: a/f1.ts +[|import * as ns from "./foo"; +foo/*0*/();|] +// @Filename: a/foo/bar.ts +export function foo() {}; +// @Filename: a/foo.ts +export { foo } from "./foo/bar";` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import * as ns from "./foo"; +ns.foo();`, + `import * as ns from "./foo"; +import { foo } from "./foo"; +foo();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixOptionalImport1_test.go b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport1_test.go new file mode 100644 index 0000000000..a086546674 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport1_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 TestImportNameCodeFixOptionalImport1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: a/f1.ts +[|foo/*0*/();|] +// @Filename: a/node_modules/bar/index.ts +export function foo() {}; +// @Filename: a/foo.ts +export { foo } from "bar";` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "bar"; + +foo();`, + `import { foo } from "./foo"; + +foo();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixShebang_test.go b/internal/fourslash/tests/gen/importNameCodeFixShebang_test.go new file mode 100644 index 0000000000..d5f6f4d062 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixShebang_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 TestImportNameCodeFixShebang(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +export const foo = 0; +// @Filename: /b.ts +[|#!/usr/bin/env node +foo/**/|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/a.ts") + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `#!/usr/bin/env node + +import { foo } from "./a"; + +foo`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal0_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal0_test.go new file mode 100644 index 0000000000..117fb890cb --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal0_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 TestImportNameCodeFixUMDGlobal0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @AllowSyntheticDefaultImports: false +// @Module: es2015 +// @Filename: a/f1.ts +[|export function test() { }; +bar1/*0*/.bar;|] +// @Filename: a/foo.d.ts +export declare function bar(): number; +export as namespace bar1; ` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import * as bar1 from "./foo"; + +export function test() { }; +bar1.bar;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal1_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal1_test.go new file mode 100644 index 0000000000..b52bd9657b --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal1_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 TestImportNameCodeFixUMDGlobal1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @AllowSyntheticDefaultImports: false +// @Module: esnext +// @Filename: a/f1.ts +[|import { bar } from "./foo"; + +export function test() { }; +bar1/*0*/.bar();|] +// @Filename: a/foo.d.ts +export declare function bar(): number; +export as namespace bar1; ` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import * as bar1 from "./foo"; +import { bar } from "./foo"; + +export function test() { }; +bar1.bar();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalJavaScript_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalJavaScript_test.go new file mode 100644 index 0000000000..7fadc60437 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalJavaScript_test.go @@ -0,0 +1,31 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixUMDGlobalJavaScript(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @AllowSyntheticDefaultImports: false +// @Module: commonjs +// @CheckJs: true +// @AllowJs: true +// @Filename: a/f1.js +[|export function test() { }; +bar1/*0*/.bar;|] +// @Filename: a/foo.d.ts +export declare function bar(): number; +export as namespace bar1; ` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import * as bar1 from "./foo"; + +export function test() { }; +bar1.bar;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact0_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact0_test.go new file mode 100644 index 0000000000..97a304325c --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact0_test.go @@ -0,0 +1,50 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixUMDGlobalReact0(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @jsx: react +// @allowSyntheticDefaultImports: false +// @module: es2015 +// @moduleResolution: bundler +// @Filename: /node_modules/@types/react/index.d.ts +export = React; +export as namespace React; +declare namespace React { + export class Component { render(): JSX.Element | null; } +} +declare global { + namespace JSX { + interface Element {} + } +} +// @Filename: /a.tsx +[|import { Component } from "react"; +export class MyMap extends Component { } +;|] +// @Filename: /b.tsx +[|import { Component } from "react"; +<>;|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/a.tsx") + f.VerifyImportFixAtPosition(t, []string{ + `import * as React from "react"; +import { Component } from "react"; +export class MyMap extends Component { } +;`, + }, nil /*preferences*/) + f.GoToFile(t, "/b.tsx") + f.VerifyImportFixAtPosition(t, []string{ + `import * as React from "react"; +import { Component } from "react"; +<>;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go new file mode 100644 index 0000000000..a4772340ee --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go @@ -0,0 +1,41 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFixUMDGlobalReact1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @jsx: react +// @allowSyntheticDefaultImports: false +// @module: es2015 +// @moduleResolution: bundler +// @Filename: /node_modules/@types/react/index.d.ts +export = React; +export as namespace React; +declare namespace React { + export class Component { render(): JSX.Element | null; } +} +declare global { + namespace JSX { + interface Element {} + } +} +// @Filename: /a.tsx +[|import { Component } from "react"; +export class MyMap extends Component { } +;|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/a.tsx") + f.VerifyImportFixAtPosition(t, []string{ + `import * as React from "react"; +import { Component } from "react"; +export class MyMap extends Component { } +;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact2_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact2_test.go new file mode 100644 index 0000000000..4302412c8d --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact2_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 TestImportNameCodeFixUMDGlobalReact2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @jsx: react +// @jsxFactory: factory +// @Filename: /factory.ts +export function factory() { return {}; } +declare global { + namespace JSX { + interface Element {} + } +} +// @Filename: /a.tsx +[|
|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/a.tsx") + f.VerifyImportFixAtPosition(t, []string{ + `import { factory } from "./factory"; + +
`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go new file mode 100644 index 0000000000..57d7645b43 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go @@ -0,0 +1,36 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_HeaderComment1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +export const foo = 0; +// @Filename: /b.ts +export const bar = 0; +// @Filename: /c.ts +/*-------------------- + * Copyright Header + *--------------------*/ + +import { bar } from "./b"; +foo;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/c.ts") + f.VerifyImportFixAtPosition(t, []string{ + `/*-------------------- + * Copyright Header + *--------------------*/ + +import { foo } from "./a"; +import { bar } from "./b"; +foo;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go new file mode 100644 index 0000000000..8c159de368 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go @@ -0,0 +1,42 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_HeaderComment2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +export const foo = 0; +// @Filename: /b.ts +export const bar = 0; +// @Filename: /c.ts +/*-------------------- + * Copyright Header + *--------------------*/ + +const afterHeader = 1; + +// non-header comment +import { bar } from "./b"; +foo;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/c.ts") + f.VerifyImportFixAtPosition(t, []string{ + `/*-------------------- + * Copyright Header + *--------------------*/ + +const afterHeader = 1; + +import { foo } from "./a"; +// non-header comment +import { bar } from "./b"; +foo;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go b/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go new file mode 100644 index 0000000000..92b14c6521 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go @@ -0,0 +1,34 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_avoidRelativeNodeModules(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a/index.d.ts +// @Symlink: /b/node_modules/a/index.d.ts +// @Symlink: /c/node_modules/a/index.d.ts +export const a: number; +// @Filename: /b/index.ts +// @Symlink: /c/node_modules/b/index.d.ts +import { a } from 'a' +export const b: number; +// @Filename: /c/a_user.ts +import { a } from "a"; +// @Filename: /c/foo.ts +[|import { b } from "b"; +a;|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/c/foo.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { a } from "a"; +import { b } from "b"; +a;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_commonjs_allowSynthetic_test.go b/internal/fourslash/tests/gen/importNameCodeFix_commonjs_allowSynthetic_test.go new file mode 100644 index 0000000000..bf093cc95d --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_commonjs_allowSynthetic_test.go @@ -0,0 +1,35 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_commonjs_allowSynthetic(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: esnext +// @moduleResolution: bundler +// @allowJs: true +// @checkJs: true +// @allowSyntheticDefaultImports: true +// @Filename: /test_module.js +const MY_EXPORTS = {} +module.exports = MY_EXPORTS; +// @Filename: /index.js +const newVar = { + any: MY_EXPORTS/**/, +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `const MY_EXPORTS = require("./test_module"); + +const newVar = { + any: MY_EXPORTS, +}`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_defaultExport_test.go b/internal/fourslash/tests/gen/importNameCodeFix_defaultExport_test.go new file mode 100644 index 0000000000..5c1f1252e3 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_defaultExport_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 TestImportNameCodeFix_defaultExport(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: esnext +// @allowJs: true +// @checkJs: true +// @Filename: /a.js +class C {} +export default C; +// @Filename: /b.js +[|C;|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/b.js") + f.VerifyImportFixAtPosition(t, []string{ + `import C from "./a"; + +C;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_dollar_test.go b/internal/fourslash/tests/gen/importNameCodeFix_dollar_test.go new file mode 100644 index 0000000000..0b52076265 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_dollar_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 TestImportNameCodeFix_dollar(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: esnext +// @moduleResolution: bundler +// @Filename: /node_modules/qwik/index.d.ts +export declare const $: any; +// @Filename: /index.ts +import {} from "qwik"; +$/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { $ } from "qwik"; +$`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go b/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go new file mode 100644 index 0000000000..23586e5527 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_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 TestImportNameCodeFix_fileWithNoTrailingNewline(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +export const foo = 0; +// @Filename: /b.ts +export const bar = 0; +// @Filename: /c.ts +foo; +import { bar } from "./b";` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/c.ts") + f.VerifyImportFixAtPosition(t, []string{ + `foo; +import { foo } from "./a"; +import { bar } from "./b";`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_fromPathMapping_test.go b/internal/fourslash/tests/gen/importNameCodeFix_fromPathMapping_test.go new file mode 100644 index 0000000000..dc71d0e7eb --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_fromPathMapping_test.go @@ -0,0 +1,34 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_fromPathMapping(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +export const foo = 0; +// @Filename: /x/y.ts +foo; +// @Filename: /tsconfig.json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@root/*": ["*"], + } + } +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/x/y.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "@root/a"; + +foo;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_getCanonicalFileName_test.go b/internal/fourslash/tests/gen/importNameCodeFix_getCanonicalFileName_test.go new file mode 100644 index 0000000000..22ec6d259f --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_getCanonicalFileName_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 TestImportNameCodeFix_getCanonicalFileName(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /howNow/node_modules/brownCow/index.d.ts +export const foo: number; +// @Filename: /howNow/a.ts +foo;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/howNow/a.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "brownCow"; + +foo;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go new file mode 100644 index 0000000000..195caa8c72 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go @@ -0,0 +1,37 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_importType1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @verbatimModuleSyntax: true +// @module: es2015 +// @Filename: /exports.ts +export default someValue = 0; +export function Component() {} +export interface ComponentProps {} +// @Filename: /a.ts +import { Component } from "./exports.js"; +interface MoreProps extends /*a*/ComponentProps {} +// @Filename: /b.ts +import someValue from "./exports.js"; +interface MoreProps extends /*b*/ComponentProps {}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "a") + f.VerifyImportFixAtPosition(t, []string{ + `import { Component, type ComponentProps } from "./exports.js"; +interface MoreProps extends ComponentProps {}`, + }, nil /*preferences*/) + f.GoToMarker(t, "b") + f.VerifyImportFixAtPosition(t, []string{ + `import someValue, { type ComponentProps } from "./exports.js"; +interface MoreProps extends ComponentProps {}`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go new file mode 100644 index 0000000000..e1e2c7cd19 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go @@ -0,0 +1,57 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_importType2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @verbatimModuleSyntax: true +// @module: es2015 +// @Filename: /exports1.ts +export default interface SomeType {} +export interface OtherType {} +export interface OtherOtherType {} +export const someValue = 0; +// @Filename: /a.ts +import type SomeType from "./exports1.js"; +someValue/*a*/ +// @Filename: /b.ts +import { someValue } from "./exports1.js"; +const b: SomeType/*b*/ = someValue; +// @Filename: /c.ts +import type SomeType from "./exports1.js"; +const x: OtherType/*c*/ +// @Filename: /d.ts +import type { OtherType } from "./exports1.js"; +const x: OtherOtherType/*d*/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "a") + f.VerifyImportFixAtPosition(t, []string{ + `import type SomeType from "./exports1.js"; +import { someValue } from "./exports1.js"; +someValue`, + }, nil /*preferences*/) + f.GoToMarker(t, "b") + f.VerifyImportFixAtPosition(t, []string{ + `import type SomeType from "./exports1.js"; +import { someValue } from "./exports1.js"; +const b: SomeType = someValue;`, + }, nil /*preferences*/) + f.GoToMarker(t, "c") + f.VerifyImportFixAtPosition(t, []string{ + `import type { OtherType } from "./exports1.js"; +import type SomeType from "./exports1.js"; +const x: OtherType`, + }, nil /*preferences*/) + f.GoToMarker(t, "d") + f.VerifyImportFixAtPosition(t, []string{ + `import type { OtherOtherType, OtherType } from "./exports1.js"; +const x: OtherOtherType`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType3_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType3_test.go new file mode 100644 index 0000000000..abb40aa078 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType3_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 TestImportNameCodeFix_importType3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @verbatimModuleSyntax: true +// @module: es2015 +// @Filename: /exports.ts +class SomeClass {} +export type { SomeClass }; +// @Filename: /a.ts +import {} from "./exports.js"; +function takeSomeClass(c: SomeClass/**/)` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { type SomeClass } from "./exports.js"; +function takeSomeClass(c: SomeClass)`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go new file mode 100644 index 0000000000..616fe3f572 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType4_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 TestImportNameCodeFix_importType4(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @preserveValueImports: true +// @isolatedModules: true +// @module: es2015 +// @Filename: /exports.ts +export interface SomeInterface {} +export class SomePig {} +// @Filename: /a.ts +import type { SomeInterface } from "./exports.js"; +new SomePig/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { SomePig, type SomeInterface } from "./exports.js"; +new SomePig`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType5_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType5_test.go new file mode 100644 index 0000000000..e35bdb4cb7 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType5_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 TestImportNameCodeFix_importType5(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: es2015 +// @Filename: /exports.ts +export interface SomeInterface {} +export class SomePig {} +// @Filename: /a.ts +import type { SomeInterface, SomePig } from "./exports.js"; +new SomePig/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { SomeInterface, SomePig } from "./exports.js"; +new SomePig`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType6_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType6_test.go new file mode 100644 index 0000000000..775fc58e70 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType6_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 TestImportNameCodeFix_importType6(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: es2015 +// @esModuleInterop: true +// @jsx: react +// @Filename: /types.d.ts +declare module "react" { var React: any; export = React; export as namespace React; } +// @Filename: /a.tsx +import type React from "react"; +function Component() {} +()` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import React from "react"; +function Component() {} +()`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go new file mode 100644 index 0000000000..6c13fc69e0 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go @@ -0,0 +1,54 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_importType7(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: es2015 +// @Filename: /exports.ts +export interface SomeInterface {} +export class SomePig {} +// @Filename: /a.ts +import { + type SomeInterface, + type SomePig, +} from "./exports.js"; +new SomePig/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { + SomePig, + type SomeInterface, +} from "./exports.js"; +new SomePig`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { + SomePig, + type SomeInterface, +} from "./exports.js"; +new SomePig`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { + type SomeInterface, + SomePig, +} from "./exports.js"; +new SomePig`, + }, nil /*preferences*/) + f.VerifyImportFixAtPosition(t, []string{ + `import { + type SomeInterface, + SomePig, +} from "./exports.js"; +new SomePig`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go new file mode 100644 index 0000000000..50d43c8152 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType8_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 TestImportNameCodeFix_importType8(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: es2015 +// @verbatimModuleSyntax: true +// @Filename: /exports.ts +export interface SomeInterface {} +export class SomePig {} +// @Filename: /a.ts +import type { SomeInterface, SomePig } from "./exports.js"; +new SomePig/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { SomePig, type SomeInterface } from "./exports.js"; +new SomePig`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType_test.go new file mode 100644 index 0000000000..a0db33f11e --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType_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 TestImportNameCodeFix_importType(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @checkJs: true +// @Filename: /a.js +export {}; +/** @typedef {number} T */ +// @Filename: /b.js +/** @type {T} */ +const x = 0;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/b.js") + f.VerifyImportFixAtPosition(t, []string{ + `/** @type {import("./a").T} */ +const x = 0;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM1_test.go new file mode 100644 index 0000000000..3d5735dd2a --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM1_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 TestImportNameCodeFix_jsCJSvsESM1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @checkJs: true +// @Filename: types/dep.d.ts +export declare class Dep {} +// @Filename: index.js +Dep/**/ +// @Filename: util.js +import fs from 'fs';` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { Dep } from "./types/dep"; + +Dep`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM2_test.go new file mode 100644 index 0000000000..be73839c63 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM2_test.go @@ -0,0 +1,31 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_jsCJSvsESM2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @checkJs: true +// @Filename: types/dep.d.ts +export declare class Dep {} +// @Filename: index.js +Dep/**/ +// @Filename: util1.ts +import fs from 'fs'; +// @Filename: util2.js +const fs = require('fs');` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `const { Dep } = require("./types/dep"); + +Dep`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM3_test.go b/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM3_test.go new file mode 100644 index 0000000000..7006d6b90a --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM3_test.go @@ -0,0 +1,34 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_jsCJSvsESM3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @allowJs: true +// @checkJs: true +// @Filename: types/dep.d.ts +export declare class Dep {} +// @Filename: index.js +import fs from 'fs'; +const path = require('path'); + +Dep/**/ +// @Filename: util2.js +export {};` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import fs from 'fs'; +import { Dep } from './types/dep'; +const path = require('path'); + +Dep`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go new file mode 100644 index 0000000000..0f5ff35b9a --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go @@ -0,0 +1,42 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_jsx1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @jsx: react +// @Filename: /node_modules/react/index.d.ts +export const React: any; +// @Filename: /a.tsx +[||] +// @Filename: /Foo.tsx +export const Foo = 0; +// @Filename: /c.tsx +import { React } from "react"; +; +// @Filename: /d.tsx +import { Foo } from "./Foo"; +;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/a.tsx") + f.VerifyImportFixAtPosition(t, []string{}, nil /*preferences*/) + f.GoToFile(t, "/c.tsx") + f.VerifyImportFixAtPosition(t, []string{ + `import { React } from "react"; +import { Foo } from "./Foo"; +;`, + }, nil /*preferences*/) + f.GoToFile(t, "/d.tsx") + f.VerifyImportFixAtPosition(t, []string{ + `import { React } from "react"; +import { Foo } from "./Foo"; +;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_jsxOpeningTagImportDefault_test.go b/internal/fourslash/tests/gen/importNameCodeFix_jsxOpeningTagImportDefault_test.go new file mode 100644 index 0000000000..91aeb29425 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_jsxOpeningTagImportDefault_test.go @@ -0,0 +1,31 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_jsxOpeningTagImportDefault(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: commonjs +// @jsx: react-jsx +// @Filename: /component.tsx +export default function (props: any) {} +// @Filename: /index.tsx +export function Index() { + return ; +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import Component from "./component"; + +export function Index() { + return ; +}`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_jsxReact17_test.go b/internal/fourslash/tests/gen/importNameCodeFix_jsxReact17_test.go new file mode 100644 index 0000000000..6dbc973a45 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_jsxReact17_test.go @@ -0,0 +1,41 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_jsxReact17(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @jsx: preserve +// @module: commonjs +// @Filename: /node_modules/@types/react/index.d.ts +declare namespace React { + function createElement(): any; +} +export = React; +export as namespace React; + +declare global { + namespace JSX { + interface IntrinsicElements {} + interface IntrinsicAttributes {} + } +} +// @Filename: /component.tsx +import "react"; +export declare function Component(): any; +// @Filename: /index.tsx +();` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { Component } from "./component"; + +();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go new file mode 100644 index 0000000000..0f1ec18977 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go @@ -0,0 +1,54 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_order2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +export const _aB: number; +export const _Ab: number; +export const aB: number; +export const Ab: number; +// @Filename: /b.ts +[|import { + _aB, + _Ab, + Ab, +} from "./a"; +aB;|] +// @Filename: /c.ts +[|import { + _aB, + _Ab, + Ab, +} from "./a"; +aB;|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { + _aB, + _Ab, + Ab, + aB, +} from "./a"; +aB;`, + }, nil /*preferences*/) + f.GoToFile(t, "/c.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { + _aB, + _Ab, + aB, + Ab, +} from "./a"; +aB;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_order_test.go b/internal/fourslash/tests/gen/importNameCodeFix_order_test.go new file mode 100644 index 0000000000..ea6b469266 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_order_test.go @@ -0,0 +1,31 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_order(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +export const foo: number; +// @Filename: /b.ts +export const foo: number; +export const bar: number; +// @Filename: /c.ts +[|import { bar } from "./b"; +foo;|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/c.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { bar, foo } from "./b"; +foo;`, + `import { foo } from "./a"; +import { bar } from "./b"; +foo;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_pathsWithoutBaseUrl1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_pathsWithoutBaseUrl1_test.go new file mode 100644 index 0000000000..85aa10e76b --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_pathsWithoutBaseUrl1_test.go @@ -0,0 +1,34 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_pathsWithoutBaseUrl1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: tsconfig.json +{ + "compilerOptions": { + "module": "commonjs", + "paths": { + "@app/*": ["./lib/*"] + } + } +} +// @Filename: index.ts +utils/**/ +// @Filename: lib/utils.ts +export const utils = {};` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { utils } from "@app/utils"; + +utils`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_pathsWithoutBaseUrl2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_pathsWithoutBaseUrl2_test.go new file mode 100644 index 0000000000..ccda7d8e28 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_pathsWithoutBaseUrl2_test.go @@ -0,0 +1,34 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_pathsWithoutBaseUrl2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /packages/test-package-1/tsconfig.json +{ + "compilerOptions": { + "module": "commonjs", + "paths": { + "test-package-2/*": ["../test-package-2/src/*"] + } + } +} +// @Filename: /packages/test-package-1/src/common/logging.ts +export class Logger {}; +// @Filename: /packages/test-package-1/src/something/index.ts +Logger/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { Logger } from "../common/logging"; + +Logger`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go new file mode 100644 index 0000000000..9967048402 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_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 TestImportNameCodeFix_pnpm1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /home/src/workspaces/project/tsconfig.json +{ "compilerOptions": { "module": "commonjs" } } +// @Filename: /home/src/workspaces/project/node_modules/.pnpm/@types+react@17.0.7/node_modules/@types/react/index.d.ts +export declare function Component(): void; +// @Filename: /home/src/workspaces/project/index.ts +Component/**/ +// @link: /home/src/workspaces/project/node_modules/.pnpm/@types+react@17.0.7/node_modules/@types/react -> /home/src/workspaces/project/node_modules/@types/react` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { Component } from "react"; + +Component`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go b/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go new file mode 100644 index 0000000000..7c66bd3dc6 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_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 TestImportNameCodeFix_preferBaseUrl(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /tsconfig.json +{ "compilerOptions": { "baseUrl": "./src" } } +// @Filename: /src/d0/d1/d2/file.ts +foo/**/; +// @Filename: /src/d0/a.ts +export const foo = 0;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/src/d0/d1/d2/file.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "d0/a"; + +foo;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_quoteStyle_test.go b/internal/fourslash/tests/gen/importNameCodeFix_quoteStyle_test.go new file mode 100644 index 0000000000..ee57b2659d --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_quoteStyle_test.go @@ -0,0 +1,26 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/ls/lsutil" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_quoteStyle(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +export const foo: number; +// @Filename: /b.ts +[|foo;|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from './a'; + +foo;`, + }, &lsutil.UserPreferences{QuotePreference: lsutil.QuotePreference("single")}) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go b/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go new file mode 100644 index 0000000000..c5b775e568 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go @@ -0,0 +1,54 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_reExportDefault(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /user.ts +foo; +// @Filename: /user2.ts +unnamed; +// @Filename: /user3.ts +reExportUnnamed; +// @Filename: /reExportNamed.ts +export { default } from "./named"; +// @Filename: /reExportUnnamed.ts +export { default } from "./unnamed"; +// @Filename: /named.ts +function foo() {} +export default foo; +// @Filename: /unnamed.ts +export default 0;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/user.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import foo from "./named"; + +foo;`, + `import foo from "./reExportNamed"; + +foo;`, + }, nil /*preferences*/) + f.GoToFile(t, "/user2.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import unnamed from "./unnamed"; + +unnamed;`, + `import unnamed from "./reExportUnnamed"; + +unnamed;`, + }, nil /*preferences*/) + f.GoToFile(t, "/user3.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import reExportUnnamed from "./reExportUnnamed"; + +reExportUnnamed;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_reExport_test.go b/internal/fourslash/tests/gen/importNameCodeFix_reExport_test.go new file mode 100644 index 0000000000..f895975f15 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_reExport_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 TestImportNameCodeFix_reExport(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +export default function foo(): void {} +// @Filename: /b.ts +export { default } from "./a"; +// @Filename: /user.ts +[|foo;|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/user.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import foo from "./a"; + +foo;`, + `import foo from "./b"; + +foo;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment1_test.go new file mode 100644 index 0000000000..e828e39af6 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment1_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 TestImportNameCodeFix_shorthandPropertyAssignment1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +export const a = 1; +// @Filename: /b.ts +const b = { /**/a };` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { a } from "./a"; + +const b = { a };`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment2_test.go new file mode 100644 index 0000000000..0020bc1031 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment2_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 TestImportNameCodeFix_shorthandPropertyAssignment2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +const a = 1; +export default a; +// @Filename: /b.ts +const b = { /**/a };` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import a from "./a"; + +const b = { a };`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_sortByDistance_test.go b/internal/fourslash/tests/gen/importNameCodeFix_sortByDistance_test.go new file mode 100644 index 0000000000..f03212e595 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_sortByDistance_test.go @@ -0,0 +1,41 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_sortByDistance(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: commonjs +// @Filename: /src/admin/utils/db/db.ts +export const db = {}; +// @Filename: /src/admin/utils/db/index.ts +export * from "./db"; +// @Filename: /src/client/helpers/db.ts +export const db = {}; +// @Filename: /src/client/db.ts +export const db = {}; +// @Filename: /src/client/foo.ts +db/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { db } from "./db"; + +db`, + `import { db } from "./helpers/db"; + +db`, + `import { db } from "../admin/utils/db"; + +db`, + `import { db } from "../admin/utils/db/db"; + +db`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_symlink_own_package_2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_symlink_own_package_2_test.go new file mode 100644 index 0000000000..0381a6302c --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_symlink_own_package_2_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 TestImportNameCodeFix_symlink_own_package_2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /packages/a/test.ts +// @Symlink: /node_modules/a/test.ts +x; +// @Filename: /packages/a/utils.ts +// @Symlink: /node_modules/a/utils.ts +import {} from "a/utils"; +export const x = 0;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/packages/a/test.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { x } from "./utils"; + +x;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_symlink_own_package_test.go b/internal/fourslash/tests/gen/importNameCodeFix_symlink_own_package_test.go new file mode 100644 index 0000000000..1e4a28c2da --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_symlink_own_package_test.go @@ -0,0 +1,31 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_symlink_own_package(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /packages/b/b0.ts +// @Symlink: /node_modules/b/b0.ts +x; +// @Filename: /packages/b/b1.ts +// @Symlink: /node_modules/b/b1.ts +import { a } from "a"; +export const x = 0; +// @Filename: /packages/a/index.d.ts +// @Symlink: /node_modules/a/index.d.ts +export const a: number;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/packages/b/b0.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { x } from "./b1"; + +x;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go b/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go new file mode 100644 index 0000000000..8c3dbe4a11 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go @@ -0,0 +1,33 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_symlink(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @moduleResolution: bundler +// @noLib: true +// @Filename: /node_modules/real/index.d.ts +// @Symlink: /node_modules/link/index.d.ts +export const foo: number; +// @Filename: /a.ts +import { foo } from "link"; +// @Filename: /b.ts +[|foo;|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { foo } from "link"; + +foo;`, + `import { foo } from "real"; + +foo;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go b/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go new file mode 100644 index 0000000000..20f332b4bd --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go @@ -0,0 +1,35 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_trailingComma(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: index.ts +import { + T2, + T1, +} from "./types"; + +const x: T3/**/ +// @Filename: types.ts +export type T1 = 0; +export type T2 = 0; +export type T3 = 0;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyImportFixAtPosition(t, []string{ + `import { + T2, + T1, + T3, +} from "./types"; + +const x: T3`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_tripleSlashOrdering_test.go b/internal/fourslash/tests/gen/importNameCodeFix_tripleSlashOrdering_test.go new file mode 100644 index 0000000000..d03ba3b561 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_tripleSlashOrdering_test.go @@ -0,0 +1,119 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestImportNameCodeFix_tripleSlashOrdering(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /tsconfig.json +{ + "compilerOptions": { + "skipDefaultLibCheck": false + } +} +// @Filename: /a.ts +export const x = 0; +// @Filename: /b.ts +// some comment + +/// + +const y = x + 1; +// @Filename: /c.ts +// some comment + +/// + +const y = x + 1; +// @Filename: /d.ts +// some comment + +/// + +const y = x + 1; +// @Filename: /e.ts +// some comment + +/// + +const y = x + 1; +// @Filename: /f.ts +// some comment + +/// + +const y = x + 1; +// @Filename: /g.ts +// some comment + +/// + +const y = x + 1;` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `// some comment + +/// + +import { x } from "./a"; + +const y = x + 1;`, + }, nil /*preferences*/) + f.GoToFile(t, "/c.ts") + f.VerifyImportFixAtPosition(t, []string{ + `// some comment + +/// + +import { x } from "./a"; + +const y = x + 1;`, + }, nil /*preferences*/) + f.GoToFile(t, "/d.ts") + f.VerifyImportFixAtPosition(t, []string{ + `// some comment + +/// + +import { x } from "./a"; + +const y = x + 1;`, + }, nil /*preferences*/) + f.GoToFile(t, "/e.ts") + f.VerifyImportFixAtPosition(t, []string{ + `// some comment + +/// + +import { x } from "./a"; + +const y = x + 1;`, + }, nil /*preferences*/) + f.GoToFile(t, "/f.ts") + f.VerifyImportFixAtPosition(t, []string{ + `// some comment + +/// + +import { x } from "./a"; + +const y = x + 1;`, + }, nil /*preferences*/) + f.GoToFile(t, "/g.ts") + f.VerifyImportFixAtPosition(t, []string{ + `// some comment + +/// + +import { x } from "./a"; + +const y = x + 1;`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_typeOnly_test.go b/internal/fourslash/tests/gen/importNameCodeFix_typeOnly_test.go new file mode 100644 index 0000000000..c81ef37ec3 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_typeOnly_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 TestImportNameCodeFix_typeOnly(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @module: esnext +// @verbatimModuleSyntax: true +// @Filename: types.ts +export class A {} +// @Filename: index.ts +const a: /**/A` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import type { A } from "./types"; + +const a: A`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_typeUsedAsValue_test.go b/internal/fourslash/tests/gen/importNameCodeFix_typeUsedAsValue_test.go new file mode 100644 index 0000000000..c44a172826 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_typeUsedAsValue_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 TestImportNameCodeFix_typeUsedAsValue(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +export class ReadonlyArray {} +// @Filename: /b.ts +[|new ReadonlyArray();|]` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { ReadonlyArray } from "./a"; + +new ReadonlyArray();`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go b/internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go new file mode 100644 index 0000000000..5000eff555 --- /dev/null +++ b/internal/fourslash/tests/gen/importNameCodeFix_withJson_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 TestImportNameCodeFix_withJson(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +export const a = 'a'; +// @Filename: /b.ts +import "./anything.json"; + +a/**/` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToFile(t, "/b.ts") + f.VerifyImportFixAtPosition(t, []string{ + `import { a } from "./a"; +import "./anything.json"; + +a`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/moduleNodeNextAutoImport1_test.go b/internal/fourslash/tests/gen/moduleNodeNextAutoImport1_test.go new file mode 100644 index 0000000000..6434da678c --- /dev/null +++ b/internal/fourslash/tests/gen/moduleNodeNextAutoImport1_test.go @@ -0,0 +1,31 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestModuleNodeNextAutoImport1(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /tsconfig.json +{ "compilerOptions": { "module": "nodenext" } } +// @Filename: /package.json +{ "type": "module" } +// @Filename: /mobx.d.ts +export declare function autorun(): void; +// @Filename: /index.ts +autorun/**/ +// @Filename: /utils.ts +import "./mobx.js";` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { autorun } from "./mobx.js"; + +autorun`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go b/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go new file mode 100644 index 0000000000..9c86a023e2 --- /dev/null +++ b/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go @@ -0,0 +1,31 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestModuleNodeNextAutoImport2(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /tsconfig.json +{ "compilerOptions": { "module": "nodenext" } } +// @Filename: /package.json +{ "type": "module" } +// @Filename: /mobx.d.cts +export declare function autorun(): void; +// @Filename: /index.ts +autorun/**/ +// @Filename: /utils.ts +import "./mobx.cjs";` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { autorun } from "./mobx.cjs"; + +autorun`, + }, nil /*preferences*/) +} diff --git a/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go b/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go new file mode 100644 index 0000000000..0f9ba1e8ef --- /dev/null +++ b/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go @@ -0,0 +1,31 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestModuleNodeNextAutoImport3(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /tsconfig.json +{ "compilerOptions": { "module": "nodenext" } } +// @Filename: /package.json +{ "type": "module" } +// @Filename: /mobx.d.mts +export declare function autorun(): void; +// @Filename: /index.ts +autorun/**/ +// @Filename: /utils.ts +import "./mobx.mjs";` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.GoToMarker(t, "") + f.VerifyImportFixAtPosition(t, []string{ + `import { autorun } from "./mobx.mjs"; + +autorun`, + }, nil /*preferences*/) +} diff --git a/internal/ls/codeactions.go b/internal/ls/codeactions.go index 329d60a7ab..26b500ffa1 100644 --- a/internal/ls/codeactions.go +++ b/internal/ls/codeactions.go @@ -41,7 +41,7 @@ func (l *LanguageService) ProvideCodeActions(ctx context.Context, params *lsprot } if len(actions) == 0 { - return lsproto.CommandOrCodeActionArrayOrNull{}, nil + return lsproto.CommandOrCodeActionArrayOrNull{CommandOrCodeActionArray: &[]lsproto.CommandOrCodeAction{}}, nil } return lsproto.CommandOrCodeActionArrayOrNull{CommandOrCodeActionArray: &actions}, nil From 8132a8cdc5f2b2fb1c34baac614047ee77e4dce7 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 17:10:20 -0800 Subject: [PATCH 04/48] Silence failing --- internal/fourslash/_scripts/failingTests.txt | 98 +++++++++++++++++++ ...portCrossProject_symlinks_stripSrc_test.go | 2 +- ...ImportCrossProject_symlinks_toDist_test.go | 2 +- ...oImportCrossProject_symlinks_toSrc_test.go | 2 +- .../tests/gen/autoImportJsDocImport1_test.go | 2 +- .../gen/autoImportNodeNextJSRequire_test.go | 2 +- ...rtPackageJsonFilterExistingImport2_test.go | 2 +- ...rtPackageJsonFilterExistingImport3_test.go | 2 +- .../tests/gen/autoImportPnpm_test.go | 2 +- .../tests/gen/autoImportProvider4_test.go | 2 +- .../tests/gen/autoImportProvider5_test.go | 2 +- .../tests/gen/autoImportProvider_pnpm_test.go | 2 +- .../autoImportSortCaseSensitivity1_test.go | 2 +- .../autoImportSymlinkCaseSensitive_test.go | 2 +- .../tests/gen/autoImportTypeImport1_test.go | 2 +- .../tests/gen/autoImportTypeImport2_test.go | 2 +- .../tests/gen/autoImportTypeImport3_test.go | 2 +- .../tests/gen/autoImportTypeImport4_test.go | 2 +- .../gen/autoImportTypeOnlyPreferred2_test.go | 2 +- .../gen/importFixesGlobalTypingsCache_test.go | 2 +- ...uotePreferenceDouble_importHelpers_test.go | 2 +- ...uotePreferenceSingle_importHelpers_test.go | 2 +- .../importNameCodeFixConvertTypeOnly1_test.go | 2 +- .../importNameCodeFixDefaultExport1_test.go | 2 +- .../importNameCodeFixDefaultExport2_test.go | 2 +- .../importNameCodeFixDefaultExport3_test.go | 2 +- .../importNameCodeFixDefaultExport4_test.go | 2 +- .../importNameCodeFixDefaultExport5_test.go | 2 +- .../importNameCodeFixDefaultExport7_test.go | 2 +- .../importNameCodeFixDefaultExport_test.go | 2 +- .../importNameCodeFixExistingImport10_test.go | 2 +- .../importNameCodeFixExistingImport11_test.go | 2 +- .../importNameCodeFixExistingImport5_test.go | 2 +- .../importNameCodeFixExistingImport8_test.go | 2 +- .../importNameCodeFixExistingImport9_test.go | 2 +- ...rtNameCodeFixExistingImportEquals0_test.go | 2 +- ...deFixExportAsDefaultExistingImport_test.go | 2 +- ...mportAllowSyntheticDefaultImports0_test.go | 2 +- ...mportAllowSyntheticDefaultImports1_test.go | 2 +- ...mportAllowSyntheticDefaultImports2_test.go | 2 +- ...mportAllowSyntheticDefaultImports3_test.go | 2 +- ...mportAllowSyntheticDefaultImports4_test.go | 2 +- ...mportAllowSyntheticDefaultImports5_test.go | 2 +- ...importNameCodeFixNewImportAmbient1_test.go | 2 +- ...importNameCodeFixNewImportAmbient3_test.go | 2 +- ...importNameCodeFixNewImportBaseUrl0_test.go | 2 +- ...importNameCodeFixNewImportBaseUrl1_test.go | 2 +- ...importNameCodeFixNewImportBaseUrl2_test.go | 2 +- ...importNameCodeFixNewImportDefault0_test.go | 2 +- .../importNameCodeFixNewImportFile2_test.go | 2 +- ...ameCodeFixNewImportFileQuoteStyle0_test.go | 2 +- ...ameCodeFixNewImportFileQuoteStyle1_test.go | 2 +- ...ameCodeFixNewImportFileQuoteStyle2_test.go | 2 +- ...deFixNewImportFileQuoteStyleMixed0_test.go | 2 +- ...deFixNewImportFileQuoteStyleMixed1_test.go | 2 +- ...mportIndex_notForClassicResolution_test.go | 2 +- ...mportNameCodeFixNewImportRootDirs0_test.go | 2 +- ...portNameCodeFixNewImportTypeRoots1_test.go | 2 +- .../importNameCodeFixOptionalImport0_test.go | 2 +- .../importNameCodeFixOptionalImport1_test.go | 2 +- .../gen/importNameCodeFixUMDGlobal0_test.go | 2 +- .../gen/importNameCodeFixUMDGlobal1_test.go | 2 +- ...portNameCodeFixUMDGlobalJavaScript_test.go | 2 +- .../importNameCodeFixUMDGlobalReact0_test.go | 2 +- .../importNameCodeFixUMDGlobalReact1_test.go | 2 +- .../importNameCodeFixUMDGlobalReact2_test.go | 2 +- .../importNameCodeFix_HeaderComment1_test.go | 2 +- .../importNameCodeFix_HeaderComment2_test.go | 2 +- ...meCodeFix_avoidRelativeNodeModules_test.go | 2 +- .../importNameCodeFix_defaultExport_test.go | 2 +- .../gen/importNameCodeFix_dollar_test.go | 2 +- ...eCodeFix_fileWithNoTrailingNewline_test.go | 2 +- .../gen/importNameCodeFix_importType1_test.go | 2 +- .../gen/importNameCodeFix_importType2_test.go | 2 +- .../gen/importNameCodeFix_importType3_test.go | 2 +- .../gen/importNameCodeFix_importType4_test.go | 2 +- .../gen/importNameCodeFix_importType5_test.go | 2 +- .../gen/importNameCodeFix_importType6_test.go | 2 +- .../gen/importNameCodeFix_importType7_test.go | 2 +- .../gen/importNameCodeFix_importType8_test.go | 2 +- .../gen/importNameCodeFix_importType_test.go | 2 +- .../tests/gen/importNameCodeFix_jsx1_test.go | 2 +- ...CodeFix_jsxOpeningTagImportDefault_test.go | 2 +- .../gen/importNameCodeFix_order2_test.go | 2 +- .../tests/gen/importNameCodeFix_order_test.go | 2 +- .../tests/gen/importNameCodeFix_pnpm1_test.go | 2 +- .../importNameCodeFix_preferBaseUrl_test.go | 2 +- .../importNameCodeFix_reExportDefault_test.go | 2 +- .../gen/importNameCodeFix_reExport_test.go | 2 +- ...deFix_shorthandPropertyAssignment1_test.go | 2 +- ...deFix_shorthandPropertyAssignment2_test.go | 2 +- .../importNameCodeFix_sortByDistance_test.go | 2 +- .../gen/importNameCodeFix_symlink_test.go | 2 +- .../importNameCodeFix_trailingComma_test.go | 2 +- .../gen/importNameCodeFix_typeOnly_test.go | 2 +- .../importNameCodeFix_typeUsedAsValue_test.go | 2 +- .../gen/importNameCodeFix_withJson_test.go | 2 +- .../gen/moduleNodeNextAutoImport2_test.go | 2 +- .../gen/moduleNodeNextAutoImport3_test.go | 2 +- 99 files changed, 196 insertions(+), 98 deletions(-) diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt index 4152b6c5f7..9fd21e7e87 100644 --- a/internal/fourslash/_scripts/failingTests.txt +++ b/internal/fourslash/_scripts/failingTests.txt @@ -9,8 +9,18 @@ TestAutoImportCompletionExportListAugmentation1 TestAutoImportCompletionExportListAugmentation2 TestAutoImportCompletionExportListAugmentation3 TestAutoImportCompletionExportListAugmentation4 +TestAutoImportCrossProject_symlinks_stripSrc +TestAutoImportCrossProject_symlinks_toDist +TestAutoImportCrossProject_symlinks_toSrc TestAutoImportFileExcludePatterns3 +TestAutoImportJsDocImport1 +TestAutoImportNodeNextJSRequire +TestAutoImportPackageJsonFilterExistingImport2 +TestAutoImportPackageJsonFilterExistingImport3 TestAutoImportPathsAliasesAndBarrels +TestAutoImportPnpm +TestAutoImportProvider4 +TestAutoImportProvider5 TestAutoImportProvider_exportMap1 TestAutoImportProvider_exportMap2 TestAutoImportProvider_exportMap3 @@ -22,9 +32,17 @@ TestAutoImportProvider_exportMap8 TestAutoImportProvider_exportMap9 TestAutoImportProvider_globalTypingsCache TestAutoImportProvider_namespaceSameNameAsIntrinsic +TestAutoImportProvider_pnpm TestAutoImportProvider_wildcardExports1 TestAutoImportProvider_wildcardExports2 TestAutoImportProvider_wildcardExports3 +TestAutoImportSortCaseSensitivity1 +TestAutoImportSymlinkCaseSensitive +TestAutoImportTypeImport1 +TestAutoImportTypeImport2 +TestAutoImportTypeImport3 +TestAutoImportTypeImport4 +TestAutoImportTypeOnlyPreferred2 TestAutoImportVerbatimTypeOnly1 TestBestCommonTypeObjectLiterals TestBestCommonTypeObjectLiterals1 @@ -269,7 +287,85 @@ TestImportCompletions_importsMap2 TestImportCompletions_importsMap3 TestImportCompletions_importsMap4 TestImportCompletions_importsMap5 +TestImportFixesGlobalTypingsCache +TestImportFixes_quotePreferenceDouble_importHelpers +TestImportFixes_quotePreferenceSingle_importHelpers +TestImportNameCodeFixConvertTypeOnly1 +TestImportNameCodeFixDefaultExport +TestImportNameCodeFixDefaultExport1 +TestImportNameCodeFixDefaultExport2 +TestImportNameCodeFixDefaultExport3 +TestImportNameCodeFixDefaultExport4 +TestImportNameCodeFixDefaultExport5 +TestImportNameCodeFixDefaultExport7 +TestImportNameCodeFixExistingImport10 +TestImportNameCodeFixExistingImport11 +TestImportNameCodeFixExistingImport5 +TestImportNameCodeFixExistingImport8 +TestImportNameCodeFixExistingImport9 +TestImportNameCodeFixExistingImportEquals0 TestImportNameCodeFixExportAsDefault +TestImportNameCodeFixExportAsDefaultExistingImport +TestImportNameCodeFixNewImportAllowSyntheticDefaultImports0 +TestImportNameCodeFixNewImportAllowSyntheticDefaultImports1 +TestImportNameCodeFixNewImportAllowSyntheticDefaultImports2 +TestImportNameCodeFixNewImportAllowSyntheticDefaultImports3 +TestImportNameCodeFixNewImportAllowSyntheticDefaultImports4 +TestImportNameCodeFixNewImportAllowSyntheticDefaultImports5 +TestImportNameCodeFixNewImportAmbient1 +TestImportNameCodeFixNewImportAmbient3 +TestImportNameCodeFixNewImportBaseUrl0 +TestImportNameCodeFixNewImportBaseUrl1 +TestImportNameCodeFixNewImportBaseUrl2 +TestImportNameCodeFixNewImportDefault0 +TestImportNameCodeFixNewImportFile2 +TestImportNameCodeFixNewImportFileQuoteStyle0 +TestImportNameCodeFixNewImportFileQuoteStyle1 +TestImportNameCodeFixNewImportFileQuoteStyle2 +TestImportNameCodeFixNewImportFileQuoteStyleMixed0 +TestImportNameCodeFixNewImportFileQuoteStyleMixed1 +TestImportNameCodeFixNewImportIndex_notForClassicResolution +TestImportNameCodeFixNewImportRootDirs0 +TestImportNameCodeFixNewImportTypeRoots1 +TestImportNameCodeFixOptionalImport0 +TestImportNameCodeFixOptionalImport1 +TestImportNameCodeFixUMDGlobal0 +TestImportNameCodeFixUMDGlobal1 +TestImportNameCodeFixUMDGlobalJavaScript +TestImportNameCodeFixUMDGlobalReact0 +TestImportNameCodeFixUMDGlobalReact1 +TestImportNameCodeFixUMDGlobalReact2 +TestImportNameCodeFix_HeaderComment1 +TestImportNameCodeFix_HeaderComment2 +TestImportNameCodeFix_avoidRelativeNodeModules +TestImportNameCodeFix_defaultExport +TestImportNameCodeFix_dollar +TestImportNameCodeFix_fileWithNoTrailingNewline +TestImportNameCodeFix_importType +TestImportNameCodeFix_importType1 +TestImportNameCodeFix_importType2 +TestImportNameCodeFix_importType3 +TestImportNameCodeFix_importType4 +TestImportNameCodeFix_importType5 +TestImportNameCodeFix_importType6 +TestImportNameCodeFix_importType7 +TestImportNameCodeFix_importType8 +TestImportNameCodeFix_jsx1 +TestImportNameCodeFix_jsxOpeningTagImportDefault +TestImportNameCodeFix_order +TestImportNameCodeFix_order2 +TestImportNameCodeFix_pnpm1 +TestImportNameCodeFix_preferBaseUrl +TestImportNameCodeFix_reExport +TestImportNameCodeFix_reExportDefault +TestImportNameCodeFix_shorthandPropertyAssignment1 +TestImportNameCodeFix_shorthandPropertyAssignment2 +TestImportNameCodeFix_sortByDistance +TestImportNameCodeFix_symlink +TestImportNameCodeFix_trailingComma +TestImportNameCodeFix_typeOnly +TestImportNameCodeFix_typeUsedAsValue +TestImportNameCodeFix_withJson TestImportTypeCompletions1 TestImportTypeCompletions3 TestImportTypeCompletions4 @@ -327,6 +423,8 @@ TestMemberListInReopenedEnum TestMemberListInWithBlock TestMemberListOfExportedClass TestMemberListOnContextualThis +TestModuleNodeNextAutoImport2 +TestModuleNodeNextAutoImport3 TestNgProxy1 TestNoQuickInfoForLabel TestNoQuickInfoInWhitespace diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go index b7358d23e9..e369963053 100644 --- a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go +++ b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportCrossProject_symlinks_stripSrc(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json { "name": "app", "dependencies": { "dep": "*" } } diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go index d7be784d54..b577b3b28d 100644 --- a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go +++ b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportCrossProject_symlinks_toDist(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json { "name": "app", "dependencies": { "dep": "*" } } diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go index 2da97bbd63..17ae9884b0 100644 --- a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go +++ b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportCrossProject_symlinks_toSrc(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json { "name": "app", "dependencies": { "dep": "*" } } diff --git a/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go b/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go index 800437b6a5..38b88edb01 100644 --- a/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go +++ b/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportJsDocImport1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go b/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go index 823a6add81..0afe25bc07 100644 --- a/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go +++ b/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportNodeNextJSRequire(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: node18 // @allowJs: true diff --git a/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport2_test.go b/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport2_test.go index 7d881d0e9f..8db79f0bde 100644 --- a/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport2_test.go +++ b/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport2_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportPackageJsonFilterExistingImport2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: preserve // @Filename: /home/src/workspaces/project/node_modules/@types/react/index.d.ts diff --git a/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport3_test.go b/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport3_test.go index 8e8144e077..986ab6fd57 100644 --- a/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport3_test.go +++ b/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport3_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportPackageJsonFilterExistingImport3(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: preserve // @Filename: /home/src/workspaces/project/node_modules/@types/node/index.d.ts diff --git a/internal/fourslash/tests/gen/autoImportPnpm_test.go b/internal/fourslash/tests/gen/autoImportPnpm_test.go index dac4cd2cc0..1f05b32afc 100644 --- a/internal/fourslash/tests/gen/autoImportPnpm_test.go +++ b/internal/fourslash/tests/gen/autoImportPnpm_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportPnpm(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "module": "commonjs" } } diff --git a/internal/fourslash/tests/gen/autoImportProvider4_test.go b/internal/fourslash/tests/gen/autoImportProvider4_test.go index ebb026c217..44dcb137e8 100644 --- a/internal/fourslash/tests/gen/autoImportProvider4_test.go +++ b/internal/fourslash/tests/gen/autoImportProvider4_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportProvider4(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/a/package.json { "dependencies": { "b": "*" } } diff --git a/internal/fourslash/tests/gen/autoImportProvider5_test.go b/internal/fourslash/tests/gen/autoImportProvider5_test.go index 147ea11146..6904fa55a3 100644 --- a/internal/fourslash/tests/gen/autoImportProvider5_test.go +++ b/internal/fourslash/tests/gen/autoImportProvider5_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportProvider5(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/package.json { "dependencies": { "react-hook-form": "*" } } diff --git a/internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go b/internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go index 9f7d4698f6..d2b4646c72 100644 --- a/internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go +++ b/internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportProvider_pnpm(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/tsconfig.json { "compilerOptions": { "module": "commonjs" } } diff --git a/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go b/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go index 3c2e74a682..020cfb9d4e 100644 --- a/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go +++ b/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportSortCaseSensitivity1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /exports1.ts export const a = 0; diff --git a/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go b/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go index 3ff780778d..e8553396d2 100644 --- a/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go +++ b/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportSymlinkCaseSensitive(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "module": "commonjs" } } diff --git a/internal/fourslash/tests/gen/autoImportTypeImport1_test.go b/internal/fourslash/tests/gen/autoImportTypeImport1_test.go index e9da922dd9..7fc9f0a982 100644 --- a/internal/fourslash/tests/gen/autoImportTypeImport1_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeImport1_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeImport1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/autoImportTypeImport2_test.go b/internal/fourslash/tests/gen/autoImportTypeImport2_test.go index 571315406c..202dfc0dd1 100644 --- a/internal/fourslash/tests/gen/autoImportTypeImport2_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeImport2_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeImport2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/autoImportTypeImport3_test.go b/internal/fourslash/tests/gen/autoImportTypeImport3_test.go index 67432c61fd..20dd8d97fd 100644 --- a/internal/fourslash/tests/gen/autoImportTypeImport3_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeImport3_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeImport3(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/autoImportTypeImport4_test.go b/internal/fourslash/tests/gen/autoImportTypeImport4_test.go index 33ccd2d46d..ae19d60f17 100644 --- a/internal/fourslash/tests/gen/autoImportTypeImport4_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeImport4_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeImport4(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go b/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go index 857cd76d56..c79ec30ad6 100644 --- a/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeOnlyPreferred2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /node_modules/react/index.d.ts export interface ComponentType {} diff --git a/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go b/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go index 20d5b30843..b0393b485a 100644 --- a/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go +++ b/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go @@ -9,7 +9,7 @@ import ( func TestImportFixesGlobalTypingsCache(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /project/tsconfig.json { "compilerOptions": { "allowJs": true, "checkJs": true } } diff --git a/internal/fourslash/tests/gen/importFixes_quotePreferenceDouble_importHelpers_test.go b/internal/fourslash/tests/gen/importFixes_quotePreferenceDouble_importHelpers_test.go index 06b9436e0a..c65e1d1a17 100644 --- a/internal/fourslash/tests/gen/importFixes_quotePreferenceDouble_importHelpers_test.go +++ b/internal/fourslash/tests/gen/importFixes_quotePreferenceDouble_importHelpers_test.go @@ -9,7 +9,7 @@ import ( func TestImportFixes_quotePreferenceDouble_importHelpers(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @importHelpers: true // @filename: /a.ts diff --git a/internal/fourslash/tests/gen/importFixes_quotePreferenceSingle_importHelpers_test.go b/internal/fourslash/tests/gen/importFixes_quotePreferenceSingle_importHelpers_test.go index 228e3087e2..16a84f3394 100644 --- a/internal/fourslash/tests/gen/importFixes_quotePreferenceSingle_importHelpers_test.go +++ b/internal/fourslash/tests/gen/importFixes_quotePreferenceSingle_importHelpers_test.go @@ -9,7 +9,7 @@ import ( func TestImportFixes_quotePreferenceSingle_importHelpers(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @importHelpers: true // @filename: /a.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go b/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go index 3857963f27..fdf289e16a 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixConvertTypeOnly1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export class A {} diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport1_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport1_test.go index 52cea508c2..66c20ceda0 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixDefaultExport1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /foo-bar.ts export default function fooBar(); diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport2_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport2_test.go index de4fe9d2f6..0765ba5b52 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixDefaultExport2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /lib.ts class Base { } diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport3_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport3_test.go index 51fb3c50a6..eda81ad654 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport3_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport3_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixDefaultExport3(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /foo-bar/index.ts export default 0; diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport4_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport4_test.go index 7b911543b5..52c0e6e2f1 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport4_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport4_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixDefaultExport4(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /foo.ts const a = () => {}; diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport5_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport5_test.go index c06e07ba0e..25fce26351 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport5_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport5_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixDefaultExport5(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @moduleResolution: bundler // @Filename: /node_modules/hooks/useFoo.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport7_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport7_test.go index 1ca3fbf64a..eb9a3447de 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport7_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport7_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixDefaultExport7(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @lib: dom // @Filename: foo.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport_test.go index 32c7ac6873..6b745d4a9b 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixDefaultExport(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /foo-bar.ts export default 0; diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go index b42825386b..836756a4f6 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport10(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import [|{ v1, diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go index dfb88bffd3..da6b393b5b 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport11(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import [|{ v1, v2, diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go index 31610760a8..707bf1903b 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport5(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import "./module"; f1/*0*/();|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go index 4daee97cc0..0ae3edc2e4 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport8(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import [|{v1, v2, v3,}|] from "./module"; v4/*0*/(); diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go index cde3b9619e..71964dca5f 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport9(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import [|{ v1 diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go index 99c363b38e..0cf8875bb5 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImportEquals0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import ns = require("ambient-module"); var x = v1/*0*/ + 5;|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixExportAsDefaultExistingImport_test.go b/internal/fourslash/tests/gen/importNameCodeFixExportAsDefaultExistingImport_test.go index 97df987bbe..84ce039acc 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExportAsDefaultExistingImport_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExportAsDefaultExistingImport_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExportAsDefaultExistingImport(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import [|{ v1, v2, v3 }|] from "./module"; v4/*0*/(); diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports0_test.go index 4c8fc42141..984bbc2f8a 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAllowSyntheticDefaultImports0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: true // @Filename: a/f1.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports1_test.go index 4e197d35c8..30b6aba6f4 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAllowSyntheticDefaultImports1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Module: system // @Filename: a/f1.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports2_test.go index 3b3daf56b3..c2f0702d42 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAllowSyntheticDefaultImports2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: false // @Module: system diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports3_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports3_test.go index 4da5bbf181..629a3cd8f9 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports3_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports3_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAllowSyntheticDefaultImports3(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: false // @Module: commonjs diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports4_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports4_test.go index 8611d94c55..06b9f1d825 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports4_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports4_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAllowSyntheticDefaultImports4(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: false // @Module: amd diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports5_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports5_test.go index 97912e6a85..d49cb8769f 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports5_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports5_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAllowSyntheticDefaultImports5(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: false // @Module: umd diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go index 3e8b1ed313..22892b732c 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAmbient1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import d from "other-ambient-module"; import * as ns from "yet-another-ambient-module"; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go index edf25cbed7..d20e88242d 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAmbient3(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `let a = "I am a non-trivial statement that appears before imports"; import d from "other-ambient-module" diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go index 526c1daebe..dd4b002813 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportBaseUrl0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|f1/*0*/();|] // @Filename: tsconfig.json diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go index 6053cd87f2..a3ce15ee9c 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportBaseUrl1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go index d08006e545..0796d349b6 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportBaseUrl2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportDefault0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportDefault0_test.go index f74774cf90..71d1d998f4 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportDefault0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportDefault0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportDefault0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|f1/*0*/();|] // @Filename: module.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go index 1312e65b50..a1e91b616c 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFile2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|f1/*0*/();|] // @Filename: ../../other_dir/module.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go index a8d873a59c..40922da0e1 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyle0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import { v2 } from './module2'; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go index 242da68c11..04cdc80d4b 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyle1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import { v2 } from "./module2"; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go index 7f071b8907..464fae8baa 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyle2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import m2 = require('./module2'); diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go index f46ecf26da..5be114b185 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyleMixed0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import { v2 } from "./module2"; import { v3 } from './module3'; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go index 6ca53ac621..ea402be77d 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyleMixed1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import { v2 } from './module2'; import { v3 } from "./module3"; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_notForClassicResolution_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_notForClassicResolution_test.go index 28987429d2..8f345f3a49 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_notForClassicResolution_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_notForClassicResolution_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportIndex_notForClassicResolution(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @moduleResolution: classic // @Filename: /a/index.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go index 910ee7dbaa..c192ad7931 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportRootDirs0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: a/f1.ts [|foo/*0*/();|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go index f3baf33c4a..c92b250137 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportTypeRoots1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: a/f1.ts [|foo/*0*/();|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go index 38ad76631d..d6e2f78696 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixOptionalImport0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: a/f1.ts [|import * as ns from "./foo"; diff --git a/internal/fourslash/tests/gen/importNameCodeFixOptionalImport1_test.go b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport1_test.go index a086546674..13d417324c 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixOptionalImport1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixOptionalImport1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: a/f1.ts [|foo/*0*/();|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal0_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal0_test.go index 117fb890cb..8e3c2320fe 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixUMDGlobal0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: false // @Module: es2015 diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal1_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal1_test.go index b52bd9657b..5415a73022 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixUMDGlobal1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: false // @Module: esnext diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalJavaScript_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalJavaScript_test.go index 7fadc60437..1c2e874232 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalJavaScript_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalJavaScript_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixUMDGlobalJavaScript(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: false // @Module: commonjs diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact0_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact0_test.go index 97a304325c..c2edb835c2 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixUMDGlobalReact0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @jsx: react // @allowSyntheticDefaultImports: false diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go index a4772340ee..29d083e101 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixUMDGlobalReact1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @jsx: react // @allowSyntheticDefaultImports: false diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact2_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact2_test.go index 4302412c8d..a3fcec0d45 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixUMDGlobalReact2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @jsx: react // @jsxFactory: factory diff --git a/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go index 57d7645b43..7bc55cb9ae 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_HeaderComment1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const foo = 0; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go index 8c159de368..36b33f05fe 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_HeaderComment2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const foo = 0; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go b/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go index 92b14c6521..4b0885f69d 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_avoidRelativeNodeModules(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a/index.d.ts // @Symlink: /b/node_modules/a/index.d.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFix_defaultExport_test.go b/internal/fourslash/tests/gen/importNameCodeFix_defaultExport_test.go index 5c1f1252e3..1103364f95 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_defaultExport_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_defaultExport_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_defaultExport(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: esnext // @allowJs: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_dollar_test.go b/internal/fourslash/tests/gen/importNameCodeFix_dollar_test.go index 0b52076265..caf72c0c6a 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_dollar_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_dollar_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_dollar(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: esnext // @moduleResolution: bundler diff --git a/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go b/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go index 23586e5527..819c94f71c 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_fileWithNoTrailingNewline(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const foo = 0; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go index 195caa8c72..058e1a75f8 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @module: es2015 diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go index e1e2c7cd19..1a09b188c4 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @module: es2015 diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType3_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType3_test.go index abb40aa078..379f454072 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType3_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType3_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType3(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @module: es2015 diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go index 616fe3f572..3fadc0f617 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType4(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @preserveValueImports: true // @isolatedModules: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType5_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType5_test.go index e35bdb4cb7..77383c5a10 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType5_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType5_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType5(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: es2015 // @Filename: /exports.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType6_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType6_test.go index 775fc58e70..f1b02172d6 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType6_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType6_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType6(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: es2015 // @esModuleInterop: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go index 6c13fc69e0..3f5d77e92a 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType7(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: es2015 // @Filename: /exports.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go index 50d43c8152..f239ddfd14 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType8(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: es2015 // @verbatimModuleSyntax: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType_test.go index a0db33f11e..2b9a735b83 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @allowJs: true // @checkJs: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go index 0f5ff35b9a..655a57f416 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_jsx1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @jsx: react // @Filename: /node_modules/react/index.d.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFix_jsxOpeningTagImportDefault_test.go b/internal/fourslash/tests/gen/importNameCodeFix_jsxOpeningTagImportDefault_test.go index 91aeb29425..c7b35cf57f 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_jsxOpeningTagImportDefault_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_jsxOpeningTagImportDefault_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_jsxOpeningTagImportDefault(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: commonjs // @jsx: react-jsx diff --git a/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go index 0f1ec18977..ff7d259f51 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_order2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const _aB: number; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_order_test.go b/internal/fourslash/tests/gen/importNameCodeFix_order_test.go index ea6b469266..e24829a31b 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_order_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_order_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_order(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const foo: number; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go index 9967048402..2d91a8fd41 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_pnpm1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/tsconfig.json { "compilerOptions": { "module": "commonjs" } } diff --git a/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go b/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go index 7c66bd3dc6..06168a5bfc 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_preferBaseUrl(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "baseUrl": "./src" } } diff --git a/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go b/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go index c5b775e568..8a99b77559 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_reExportDefault(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /user.ts foo; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_reExport_test.go b/internal/fourslash/tests/gen/importNameCodeFix_reExport_test.go index f895975f15..0822abc790 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_reExport_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_reExport_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_reExport(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export default function foo(): void {} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment1_test.go index e828e39af6..5fd83300b8 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_shorthandPropertyAssignment1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const a = 1; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment2_test.go index 0020bc1031..9fbaef01d9 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_shorthandPropertyAssignment2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts const a = 1; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_sortByDistance_test.go b/internal/fourslash/tests/gen/importNameCodeFix_sortByDistance_test.go index f03212e595..394c1f9236 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_sortByDistance_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_sortByDistance_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_sortByDistance(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: commonjs // @Filename: /src/admin/utils/db/db.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go b/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go index 8c3dbe4a11..ca04ad52c6 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_symlink(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @moduleResolution: bundler // @noLib: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go b/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go index 20f332b4bd..07f720b6e5 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_trailingComma(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: index.ts import { diff --git a/internal/fourslash/tests/gen/importNameCodeFix_typeOnly_test.go b/internal/fourslash/tests/gen/importNameCodeFix_typeOnly_test.go index c81ef37ec3..c0ab3d1b70 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_typeOnly_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_typeOnly_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_typeOnly(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: esnext // @verbatimModuleSyntax: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_typeUsedAsValue_test.go b/internal/fourslash/tests/gen/importNameCodeFix_typeUsedAsValue_test.go index c44a172826..53d2931c4f 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_typeUsedAsValue_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_typeUsedAsValue_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_typeUsedAsValue(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export class ReadonlyArray {} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go b/internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go index 5000eff555..3af50482e0 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_withJson(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const a = 'a'; diff --git a/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go b/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go index 9c86a023e2..0803a88deb 100644 --- a/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go +++ b/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go @@ -9,7 +9,7 @@ import ( func TestModuleNodeNextAutoImport2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "module": "nodenext" } } diff --git a/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go b/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go index 0f9ba1e8ef..79a3a1c638 100644 --- a/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go +++ b/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go @@ -9,7 +9,7 @@ import ( func TestModuleNodeNextAutoImport3(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "module": "nodenext" } } From a1d5c8335fe2fc9eb760b3498c7cc1c3e014a4b1 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 17:18:05 -0800 Subject: [PATCH 05/48] Revert "Silence failing" This reverts commit 8132a8cdc5f2b2fb1c34baac614047ee77e4dce7. --- internal/fourslash/_scripts/failingTests.txt | 98 ------------------- ...portCrossProject_symlinks_stripSrc_test.go | 2 +- ...ImportCrossProject_symlinks_toDist_test.go | 2 +- ...oImportCrossProject_symlinks_toSrc_test.go | 2 +- .../tests/gen/autoImportJsDocImport1_test.go | 2 +- .../gen/autoImportNodeNextJSRequire_test.go | 2 +- ...rtPackageJsonFilterExistingImport2_test.go | 2 +- ...rtPackageJsonFilterExistingImport3_test.go | 2 +- .../tests/gen/autoImportPnpm_test.go | 2 +- .../tests/gen/autoImportProvider4_test.go | 2 +- .../tests/gen/autoImportProvider5_test.go | 2 +- .../tests/gen/autoImportProvider_pnpm_test.go | 2 +- .../autoImportSortCaseSensitivity1_test.go | 2 +- .../autoImportSymlinkCaseSensitive_test.go | 2 +- .../tests/gen/autoImportTypeImport1_test.go | 2 +- .../tests/gen/autoImportTypeImport2_test.go | 2 +- .../tests/gen/autoImportTypeImport3_test.go | 2 +- .../tests/gen/autoImportTypeImport4_test.go | 2 +- .../gen/autoImportTypeOnlyPreferred2_test.go | 2 +- .../gen/importFixesGlobalTypingsCache_test.go | 2 +- ...uotePreferenceDouble_importHelpers_test.go | 2 +- ...uotePreferenceSingle_importHelpers_test.go | 2 +- .../importNameCodeFixConvertTypeOnly1_test.go | 2 +- .../importNameCodeFixDefaultExport1_test.go | 2 +- .../importNameCodeFixDefaultExport2_test.go | 2 +- .../importNameCodeFixDefaultExport3_test.go | 2 +- .../importNameCodeFixDefaultExport4_test.go | 2 +- .../importNameCodeFixDefaultExport5_test.go | 2 +- .../importNameCodeFixDefaultExport7_test.go | 2 +- .../importNameCodeFixDefaultExport_test.go | 2 +- .../importNameCodeFixExistingImport10_test.go | 2 +- .../importNameCodeFixExistingImport11_test.go | 2 +- .../importNameCodeFixExistingImport5_test.go | 2 +- .../importNameCodeFixExistingImport8_test.go | 2 +- .../importNameCodeFixExistingImport9_test.go | 2 +- ...rtNameCodeFixExistingImportEquals0_test.go | 2 +- ...deFixExportAsDefaultExistingImport_test.go | 2 +- ...mportAllowSyntheticDefaultImports0_test.go | 2 +- ...mportAllowSyntheticDefaultImports1_test.go | 2 +- ...mportAllowSyntheticDefaultImports2_test.go | 2 +- ...mportAllowSyntheticDefaultImports3_test.go | 2 +- ...mportAllowSyntheticDefaultImports4_test.go | 2 +- ...mportAllowSyntheticDefaultImports5_test.go | 2 +- ...importNameCodeFixNewImportAmbient1_test.go | 2 +- ...importNameCodeFixNewImportAmbient3_test.go | 2 +- ...importNameCodeFixNewImportBaseUrl0_test.go | 2 +- ...importNameCodeFixNewImportBaseUrl1_test.go | 2 +- ...importNameCodeFixNewImportBaseUrl2_test.go | 2 +- ...importNameCodeFixNewImportDefault0_test.go | 2 +- .../importNameCodeFixNewImportFile2_test.go | 2 +- ...ameCodeFixNewImportFileQuoteStyle0_test.go | 2 +- ...ameCodeFixNewImportFileQuoteStyle1_test.go | 2 +- ...ameCodeFixNewImportFileQuoteStyle2_test.go | 2 +- ...deFixNewImportFileQuoteStyleMixed0_test.go | 2 +- ...deFixNewImportFileQuoteStyleMixed1_test.go | 2 +- ...mportIndex_notForClassicResolution_test.go | 2 +- ...mportNameCodeFixNewImportRootDirs0_test.go | 2 +- ...portNameCodeFixNewImportTypeRoots1_test.go | 2 +- .../importNameCodeFixOptionalImport0_test.go | 2 +- .../importNameCodeFixOptionalImport1_test.go | 2 +- .../gen/importNameCodeFixUMDGlobal0_test.go | 2 +- .../gen/importNameCodeFixUMDGlobal1_test.go | 2 +- ...portNameCodeFixUMDGlobalJavaScript_test.go | 2 +- .../importNameCodeFixUMDGlobalReact0_test.go | 2 +- .../importNameCodeFixUMDGlobalReact1_test.go | 2 +- .../importNameCodeFixUMDGlobalReact2_test.go | 2 +- .../importNameCodeFix_HeaderComment1_test.go | 2 +- .../importNameCodeFix_HeaderComment2_test.go | 2 +- ...meCodeFix_avoidRelativeNodeModules_test.go | 2 +- .../importNameCodeFix_defaultExport_test.go | 2 +- .../gen/importNameCodeFix_dollar_test.go | 2 +- ...eCodeFix_fileWithNoTrailingNewline_test.go | 2 +- .../gen/importNameCodeFix_importType1_test.go | 2 +- .../gen/importNameCodeFix_importType2_test.go | 2 +- .../gen/importNameCodeFix_importType3_test.go | 2 +- .../gen/importNameCodeFix_importType4_test.go | 2 +- .../gen/importNameCodeFix_importType5_test.go | 2 +- .../gen/importNameCodeFix_importType6_test.go | 2 +- .../gen/importNameCodeFix_importType7_test.go | 2 +- .../gen/importNameCodeFix_importType8_test.go | 2 +- .../gen/importNameCodeFix_importType_test.go | 2 +- .../tests/gen/importNameCodeFix_jsx1_test.go | 2 +- ...CodeFix_jsxOpeningTagImportDefault_test.go | 2 +- .../gen/importNameCodeFix_order2_test.go | 2 +- .../tests/gen/importNameCodeFix_order_test.go | 2 +- .../tests/gen/importNameCodeFix_pnpm1_test.go | 2 +- .../importNameCodeFix_preferBaseUrl_test.go | 2 +- .../importNameCodeFix_reExportDefault_test.go | 2 +- .../gen/importNameCodeFix_reExport_test.go | 2 +- ...deFix_shorthandPropertyAssignment1_test.go | 2 +- ...deFix_shorthandPropertyAssignment2_test.go | 2 +- .../importNameCodeFix_sortByDistance_test.go | 2 +- .../gen/importNameCodeFix_symlink_test.go | 2 +- .../importNameCodeFix_trailingComma_test.go | 2 +- .../gen/importNameCodeFix_typeOnly_test.go | 2 +- .../importNameCodeFix_typeUsedAsValue_test.go | 2 +- .../gen/importNameCodeFix_withJson_test.go | 2 +- .../gen/moduleNodeNextAutoImport2_test.go | 2 +- .../gen/moduleNodeNextAutoImport3_test.go | 2 +- 99 files changed, 98 insertions(+), 196 deletions(-) diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt index 9fd21e7e87..4152b6c5f7 100644 --- a/internal/fourslash/_scripts/failingTests.txt +++ b/internal/fourslash/_scripts/failingTests.txt @@ -9,18 +9,8 @@ TestAutoImportCompletionExportListAugmentation1 TestAutoImportCompletionExportListAugmentation2 TestAutoImportCompletionExportListAugmentation3 TestAutoImportCompletionExportListAugmentation4 -TestAutoImportCrossProject_symlinks_stripSrc -TestAutoImportCrossProject_symlinks_toDist -TestAutoImportCrossProject_symlinks_toSrc TestAutoImportFileExcludePatterns3 -TestAutoImportJsDocImport1 -TestAutoImportNodeNextJSRequire -TestAutoImportPackageJsonFilterExistingImport2 -TestAutoImportPackageJsonFilterExistingImport3 TestAutoImportPathsAliasesAndBarrels -TestAutoImportPnpm -TestAutoImportProvider4 -TestAutoImportProvider5 TestAutoImportProvider_exportMap1 TestAutoImportProvider_exportMap2 TestAutoImportProvider_exportMap3 @@ -32,17 +22,9 @@ TestAutoImportProvider_exportMap8 TestAutoImportProvider_exportMap9 TestAutoImportProvider_globalTypingsCache TestAutoImportProvider_namespaceSameNameAsIntrinsic -TestAutoImportProvider_pnpm TestAutoImportProvider_wildcardExports1 TestAutoImportProvider_wildcardExports2 TestAutoImportProvider_wildcardExports3 -TestAutoImportSortCaseSensitivity1 -TestAutoImportSymlinkCaseSensitive -TestAutoImportTypeImport1 -TestAutoImportTypeImport2 -TestAutoImportTypeImport3 -TestAutoImportTypeImport4 -TestAutoImportTypeOnlyPreferred2 TestAutoImportVerbatimTypeOnly1 TestBestCommonTypeObjectLiterals TestBestCommonTypeObjectLiterals1 @@ -287,85 +269,7 @@ TestImportCompletions_importsMap2 TestImportCompletions_importsMap3 TestImportCompletions_importsMap4 TestImportCompletions_importsMap5 -TestImportFixesGlobalTypingsCache -TestImportFixes_quotePreferenceDouble_importHelpers -TestImportFixes_quotePreferenceSingle_importHelpers -TestImportNameCodeFixConvertTypeOnly1 -TestImportNameCodeFixDefaultExport -TestImportNameCodeFixDefaultExport1 -TestImportNameCodeFixDefaultExport2 -TestImportNameCodeFixDefaultExport3 -TestImportNameCodeFixDefaultExport4 -TestImportNameCodeFixDefaultExport5 -TestImportNameCodeFixDefaultExport7 -TestImportNameCodeFixExistingImport10 -TestImportNameCodeFixExistingImport11 -TestImportNameCodeFixExistingImport5 -TestImportNameCodeFixExistingImport8 -TestImportNameCodeFixExistingImport9 -TestImportNameCodeFixExistingImportEquals0 TestImportNameCodeFixExportAsDefault -TestImportNameCodeFixExportAsDefaultExistingImport -TestImportNameCodeFixNewImportAllowSyntheticDefaultImports0 -TestImportNameCodeFixNewImportAllowSyntheticDefaultImports1 -TestImportNameCodeFixNewImportAllowSyntheticDefaultImports2 -TestImportNameCodeFixNewImportAllowSyntheticDefaultImports3 -TestImportNameCodeFixNewImportAllowSyntheticDefaultImports4 -TestImportNameCodeFixNewImportAllowSyntheticDefaultImports5 -TestImportNameCodeFixNewImportAmbient1 -TestImportNameCodeFixNewImportAmbient3 -TestImportNameCodeFixNewImportBaseUrl0 -TestImportNameCodeFixNewImportBaseUrl1 -TestImportNameCodeFixNewImportBaseUrl2 -TestImportNameCodeFixNewImportDefault0 -TestImportNameCodeFixNewImportFile2 -TestImportNameCodeFixNewImportFileQuoteStyle0 -TestImportNameCodeFixNewImportFileQuoteStyle1 -TestImportNameCodeFixNewImportFileQuoteStyle2 -TestImportNameCodeFixNewImportFileQuoteStyleMixed0 -TestImportNameCodeFixNewImportFileQuoteStyleMixed1 -TestImportNameCodeFixNewImportIndex_notForClassicResolution -TestImportNameCodeFixNewImportRootDirs0 -TestImportNameCodeFixNewImportTypeRoots1 -TestImportNameCodeFixOptionalImport0 -TestImportNameCodeFixOptionalImport1 -TestImportNameCodeFixUMDGlobal0 -TestImportNameCodeFixUMDGlobal1 -TestImportNameCodeFixUMDGlobalJavaScript -TestImportNameCodeFixUMDGlobalReact0 -TestImportNameCodeFixUMDGlobalReact1 -TestImportNameCodeFixUMDGlobalReact2 -TestImportNameCodeFix_HeaderComment1 -TestImportNameCodeFix_HeaderComment2 -TestImportNameCodeFix_avoidRelativeNodeModules -TestImportNameCodeFix_defaultExport -TestImportNameCodeFix_dollar -TestImportNameCodeFix_fileWithNoTrailingNewline -TestImportNameCodeFix_importType -TestImportNameCodeFix_importType1 -TestImportNameCodeFix_importType2 -TestImportNameCodeFix_importType3 -TestImportNameCodeFix_importType4 -TestImportNameCodeFix_importType5 -TestImportNameCodeFix_importType6 -TestImportNameCodeFix_importType7 -TestImportNameCodeFix_importType8 -TestImportNameCodeFix_jsx1 -TestImportNameCodeFix_jsxOpeningTagImportDefault -TestImportNameCodeFix_order -TestImportNameCodeFix_order2 -TestImportNameCodeFix_pnpm1 -TestImportNameCodeFix_preferBaseUrl -TestImportNameCodeFix_reExport -TestImportNameCodeFix_reExportDefault -TestImportNameCodeFix_shorthandPropertyAssignment1 -TestImportNameCodeFix_shorthandPropertyAssignment2 -TestImportNameCodeFix_sortByDistance -TestImportNameCodeFix_symlink -TestImportNameCodeFix_trailingComma -TestImportNameCodeFix_typeOnly -TestImportNameCodeFix_typeUsedAsValue -TestImportNameCodeFix_withJson TestImportTypeCompletions1 TestImportTypeCompletions3 TestImportTypeCompletions4 @@ -423,8 +327,6 @@ TestMemberListInReopenedEnum TestMemberListInWithBlock TestMemberListOfExportedClass TestMemberListOnContextualThis -TestModuleNodeNextAutoImport2 -TestModuleNodeNextAutoImport3 TestNgProxy1 TestNoQuickInfoForLabel TestNoQuickInfoInWhitespace diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go index e369963053..b7358d23e9 100644 --- a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go +++ b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportCrossProject_symlinks_stripSrc(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json { "name": "app", "dependencies": { "dep": "*" } } diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go index b577b3b28d..d7be784d54 100644 --- a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go +++ b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportCrossProject_symlinks_toDist(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json { "name": "app", "dependencies": { "dep": "*" } } diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go index 17ae9884b0..2da97bbd63 100644 --- a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go +++ b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportCrossProject_symlinks_toSrc(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json { "name": "app", "dependencies": { "dep": "*" } } diff --git a/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go b/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go index 38b88edb01..800437b6a5 100644 --- a/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go +++ b/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportJsDocImport1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go b/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go index 0afe25bc07..823a6add81 100644 --- a/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go +++ b/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportNodeNextJSRequire(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: node18 // @allowJs: true diff --git a/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport2_test.go b/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport2_test.go index 8db79f0bde..7d881d0e9f 100644 --- a/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport2_test.go +++ b/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport2_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportPackageJsonFilterExistingImport2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: preserve // @Filename: /home/src/workspaces/project/node_modules/@types/react/index.d.ts diff --git a/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport3_test.go b/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport3_test.go index 986ab6fd57..8e8144e077 100644 --- a/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport3_test.go +++ b/internal/fourslash/tests/gen/autoImportPackageJsonFilterExistingImport3_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportPackageJsonFilterExistingImport3(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: preserve // @Filename: /home/src/workspaces/project/node_modules/@types/node/index.d.ts diff --git a/internal/fourslash/tests/gen/autoImportPnpm_test.go b/internal/fourslash/tests/gen/autoImportPnpm_test.go index 1f05b32afc..dac4cd2cc0 100644 --- a/internal/fourslash/tests/gen/autoImportPnpm_test.go +++ b/internal/fourslash/tests/gen/autoImportPnpm_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportPnpm(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "module": "commonjs" } } diff --git a/internal/fourslash/tests/gen/autoImportProvider4_test.go b/internal/fourslash/tests/gen/autoImportProvider4_test.go index 44dcb137e8..ebb026c217 100644 --- a/internal/fourslash/tests/gen/autoImportProvider4_test.go +++ b/internal/fourslash/tests/gen/autoImportProvider4_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportProvider4(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/a/package.json { "dependencies": { "b": "*" } } diff --git a/internal/fourslash/tests/gen/autoImportProvider5_test.go b/internal/fourslash/tests/gen/autoImportProvider5_test.go index 6904fa55a3..147ea11146 100644 --- a/internal/fourslash/tests/gen/autoImportProvider5_test.go +++ b/internal/fourslash/tests/gen/autoImportProvider5_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportProvider5(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/package.json { "dependencies": { "react-hook-form": "*" } } diff --git a/internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go b/internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go index d2b4646c72..9f7d4698f6 100644 --- a/internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go +++ b/internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportProvider_pnpm(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/tsconfig.json { "compilerOptions": { "module": "commonjs" } } diff --git a/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go b/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go index 020cfb9d4e..3c2e74a682 100644 --- a/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go +++ b/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportSortCaseSensitivity1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /exports1.ts export const a = 0; diff --git a/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go b/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go index e8553396d2..3ff780778d 100644 --- a/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go +++ b/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportSymlinkCaseSensitive(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "module": "commonjs" } } diff --git a/internal/fourslash/tests/gen/autoImportTypeImport1_test.go b/internal/fourslash/tests/gen/autoImportTypeImport1_test.go index 7fc9f0a982..e9da922dd9 100644 --- a/internal/fourslash/tests/gen/autoImportTypeImport1_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeImport1_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeImport1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/autoImportTypeImport2_test.go b/internal/fourslash/tests/gen/autoImportTypeImport2_test.go index 202dfc0dd1..571315406c 100644 --- a/internal/fourslash/tests/gen/autoImportTypeImport2_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeImport2_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeImport2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/autoImportTypeImport3_test.go b/internal/fourslash/tests/gen/autoImportTypeImport3_test.go index 20dd8d97fd..67432c61fd 100644 --- a/internal/fourslash/tests/gen/autoImportTypeImport3_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeImport3_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeImport3(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/autoImportTypeImport4_test.go b/internal/fourslash/tests/gen/autoImportTypeImport4_test.go index ae19d60f17..33ccd2d46d 100644 --- a/internal/fourslash/tests/gen/autoImportTypeImport4_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeImport4_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeImport4(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go b/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go index c79ec30ad6..857cd76d56 100644 --- a/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeOnlyPreferred2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /node_modules/react/index.d.ts export interface ComponentType {} diff --git a/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go b/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go index b0393b485a..20d5b30843 100644 --- a/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go +++ b/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go @@ -9,7 +9,7 @@ import ( func TestImportFixesGlobalTypingsCache(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /project/tsconfig.json { "compilerOptions": { "allowJs": true, "checkJs": true } } diff --git a/internal/fourslash/tests/gen/importFixes_quotePreferenceDouble_importHelpers_test.go b/internal/fourslash/tests/gen/importFixes_quotePreferenceDouble_importHelpers_test.go index c65e1d1a17..06b9436e0a 100644 --- a/internal/fourslash/tests/gen/importFixes_quotePreferenceDouble_importHelpers_test.go +++ b/internal/fourslash/tests/gen/importFixes_quotePreferenceDouble_importHelpers_test.go @@ -9,7 +9,7 @@ import ( func TestImportFixes_quotePreferenceDouble_importHelpers(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @importHelpers: true // @filename: /a.ts diff --git a/internal/fourslash/tests/gen/importFixes_quotePreferenceSingle_importHelpers_test.go b/internal/fourslash/tests/gen/importFixes_quotePreferenceSingle_importHelpers_test.go index 16a84f3394..228e3087e2 100644 --- a/internal/fourslash/tests/gen/importFixes_quotePreferenceSingle_importHelpers_test.go +++ b/internal/fourslash/tests/gen/importFixes_quotePreferenceSingle_importHelpers_test.go @@ -9,7 +9,7 @@ import ( func TestImportFixes_quotePreferenceSingle_importHelpers(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @importHelpers: true // @filename: /a.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go b/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go index fdf289e16a..3857963f27 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixConvertTypeOnly1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export class A {} diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport1_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport1_test.go index 66c20ceda0..52cea508c2 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixDefaultExport1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /foo-bar.ts export default function fooBar(); diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport2_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport2_test.go index 0765ba5b52..de4fe9d2f6 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixDefaultExport2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /lib.ts class Base { } diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport3_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport3_test.go index eda81ad654..51fb3c50a6 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport3_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport3_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixDefaultExport3(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /foo-bar/index.ts export default 0; diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport4_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport4_test.go index 52c0e6e2f1..7b911543b5 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport4_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport4_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixDefaultExport4(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /foo.ts const a = () => {}; diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport5_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport5_test.go index 25fce26351..c06e07ba0e 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport5_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport5_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixDefaultExport5(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @moduleResolution: bundler // @Filename: /node_modules/hooks/useFoo.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport7_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport7_test.go index eb9a3447de..1ca3fbf64a 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport7_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport7_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixDefaultExport7(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @lib: dom // @Filename: foo.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport_test.go b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport_test.go index 6b745d4a9b..32c7ac6873 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixDefaultExport_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixDefaultExport_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixDefaultExport(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /foo-bar.ts export default 0; diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go index 836756a4f6..b42825386b 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport10(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import [|{ v1, diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go index da6b393b5b..dfb88bffd3 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport11(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import [|{ v1, v2, diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go index 707bf1903b..31610760a8 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport5(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import "./module"; f1/*0*/();|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go index 0ae3edc2e4..4daee97cc0 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport8(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import [|{v1, v2, v3,}|] from "./module"; v4/*0*/(); diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go index 71964dca5f..cde3b9619e 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport9(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import [|{ v1 diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go index 0cf8875bb5..99c363b38e 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImportEquals0(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import ns = require("ambient-module"); var x = v1/*0*/ + 5;|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixExportAsDefaultExistingImport_test.go b/internal/fourslash/tests/gen/importNameCodeFixExportAsDefaultExistingImport_test.go index 84ce039acc..97df987bbe 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExportAsDefaultExistingImport_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExportAsDefaultExistingImport_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExportAsDefaultExistingImport(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import [|{ v1, v2, v3 }|] from "./module"; v4/*0*/(); diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports0_test.go index 984bbc2f8a..4c8fc42141 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAllowSyntheticDefaultImports0(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: true // @Filename: a/f1.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports1_test.go index 30b6aba6f4..4e197d35c8 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAllowSyntheticDefaultImports1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Module: system // @Filename: a/f1.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports2_test.go index c2f0702d42..3b3daf56b3 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAllowSyntheticDefaultImports2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: false // @Module: system diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports3_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports3_test.go index 629a3cd8f9..4da5bbf181 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports3_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports3_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAllowSyntheticDefaultImports3(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: false // @Module: commonjs diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports4_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports4_test.go index 06b9f1d825..8611d94c55 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports4_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports4_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAllowSyntheticDefaultImports4(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: false // @Module: amd diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports5_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports5_test.go index d49cb8769f..97912e6a85 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports5_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAllowSyntheticDefaultImports5_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAllowSyntheticDefaultImports5(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: false // @Module: umd diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go index 22892b732c..3e8b1ed313 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAmbient1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import d from "other-ambient-module"; import * as ns from "yet-another-ambient-module"; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go index d20e88242d..edf25cbed7 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAmbient3(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `let a = "I am a non-trivial statement that appears before imports"; import d from "other-ambient-module" diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go index dd4b002813..526c1daebe 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportBaseUrl0(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|f1/*0*/();|] // @Filename: tsconfig.json diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go index a3ce15ee9c..6053cd87f2 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportBaseUrl1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go index 0796d349b6..d08006e545 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportBaseUrl2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportDefault0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportDefault0_test.go index 71d1d998f4..f74774cf90 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportDefault0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportDefault0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportDefault0(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|f1/*0*/();|] // @Filename: module.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go index a1e91b616c..1312e65b50 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFile2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|f1/*0*/();|] // @Filename: ../../other_dir/module.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go index 40922da0e1..a8d873a59c 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyle0(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import { v2 } from './module2'; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go index 04cdc80d4b..242da68c11 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyle1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import { v2 } from "./module2"; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go index 464fae8baa..7f071b8907 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyle2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import m2 = require('./module2'); diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go index 5be114b185..f46ecf26da 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyleMixed0(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import { v2 } from "./module2"; import { v3 } from './module3'; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go index ea402be77d..6ca53ac621 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyleMixed1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import { v2 } from './module2'; import { v3 } from "./module3"; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_notForClassicResolution_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_notForClassicResolution_test.go index 8f345f3a49..28987429d2 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_notForClassicResolution_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportIndex_notForClassicResolution_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportIndex_notForClassicResolution(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @moduleResolution: classic // @Filename: /a/index.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go index c192ad7931..910ee7dbaa 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportRootDirs0(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: a/f1.ts [|foo/*0*/();|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go index c92b250137..f3baf33c4a 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportTypeRoots1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: a/f1.ts [|foo/*0*/();|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go index d6e2f78696..38ad76631d 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixOptionalImport0(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: a/f1.ts [|import * as ns from "./foo"; diff --git a/internal/fourslash/tests/gen/importNameCodeFixOptionalImport1_test.go b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport1_test.go index 13d417324c..a086546674 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixOptionalImport1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixOptionalImport1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: a/f1.ts [|foo/*0*/();|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal0_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal0_test.go index 8e3c2320fe..117fb890cb 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixUMDGlobal0(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: false // @Module: es2015 diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal1_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal1_test.go index 5415a73022..b52bd9657b 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobal1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixUMDGlobal1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: false // @Module: esnext diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalJavaScript_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalJavaScript_test.go index 1c2e874232..7fadc60437 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalJavaScript_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalJavaScript_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixUMDGlobalJavaScript(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @AllowSyntheticDefaultImports: false // @Module: commonjs diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact0_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact0_test.go index c2edb835c2..97a304325c 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixUMDGlobalReact0(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @jsx: react // @allowSyntheticDefaultImports: false diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go index 29d083e101..a4772340ee 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixUMDGlobalReact1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @jsx: react // @allowSyntheticDefaultImports: false diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact2_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact2_test.go index a3fcec0d45..4302412c8d 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixUMDGlobalReact2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @jsx: react // @jsxFactory: factory diff --git a/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go index 7bc55cb9ae..57d7645b43 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_HeaderComment1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const foo = 0; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go index 36b33f05fe..8c159de368 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_HeaderComment2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const foo = 0; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go b/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go index 4b0885f69d..92b14c6521 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_avoidRelativeNodeModules(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a/index.d.ts // @Symlink: /b/node_modules/a/index.d.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFix_defaultExport_test.go b/internal/fourslash/tests/gen/importNameCodeFix_defaultExport_test.go index 1103364f95..5c1f1252e3 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_defaultExport_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_defaultExport_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_defaultExport(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: esnext // @allowJs: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_dollar_test.go b/internal/fourslash/tests/gen/importNameCodeFix_dollar_test.go index caf72c0c6a..0b52076265 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_dollar_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_dollar_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_dollar(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: esnext // @moduleResolution: bundler diff --git a/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go b/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go index 819c94f71c..23586e5527 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_fileWithNoTrailingNewline(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const foo = 0; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go index 058e1a75f8..195caa8c72 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @module: es2015 diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go index 1a09b188c4..e1e2c7cd19 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @module: es2015 diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType3_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType3_test.go index 379f454072..abb40aa078 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType3_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType3_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType3(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @module: es2015 diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go index 3fadc0f617..616fe3f572 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType4(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @preserveValueImports: true // @isolatedModules: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType5_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType5_test.go index 77383c5a10..e35bdb4cb7 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType5_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType5_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType5(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: es2015 // @Filename: /exports.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType6_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType6_test.go index f1b02172d6..775fc58e70 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType6_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType6_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType6(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: es2015 // @esModuleInterop: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go index 3f5d77e92a..6c13fc69e0 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType7(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: es2015 // @Filename: /exports.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go index f239ddfd14..50d43c8152 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType8(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: es2015 // @verbatimModuleSyntax: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType_test.go index 2b9a735b83..a0db33f11e 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @allowJs: true // @checkJs: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go index 655a57f416..0f5ff35b9a 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_jsx1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @jsx: react // @Filename: /node_modules/react/index.d.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFix_jsxOpeningTagImportDefault_test.go b/internal/fourslash/tests/gen/importNameCodeFix_jsxOpeningTagImportDefault_test.go index c7b35cf57f..91aeb29425 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_jsxOpeningTagImportDefault_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_jsxOpeningTagImportDefault_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_jsxOpeningTagImportDefault(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: commonjs // @jsx: react-jsx diff --git a/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go index ff7d259f51..0f1ec18977 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_order2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const _aB: number; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_order_test.go b/internal/fourslash/tests/gen/importNameCodeFix_order_test.go index e24829a31b..ea6b469266 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_order_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_order_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_order(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const foo: number; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go index 2d91a8fd41..9967048402 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_pnpm1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/tsconfig.json { "compilerOptions": { "module": "commonjs" } } diff --git a/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go b/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go index 06168a5bfc..7c66bd3dc6 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_preferBaseUrl(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "baseUrl": "./src" } } diff --git a/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go b/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go index 8a99b77559..c5b775e568 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_reExportDefault(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /user.ts foo; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_reExport_test.go b/internal/fourslash/tests/gen/importNameCodeFix_reExport_test.go index 0822abc790..f895975f15 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_reExport_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_reExport_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_reExport(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export default function foo(): void {} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment1_test.go index 5fd83300b8..e828e39af6 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_shorthandPropertyAssignment1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const a = 1; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment2_test.go index 9fbaef01d9..0020bc1031 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_shorthandPropertyAssignment2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_shorthandPropertyAssignment2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts const a = 1; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_sortByDistance_test.go b/internal/fourslash/tests/gen/importNameCodeFix_sortByDistance_test.go index 394c1f9236..f03212e595 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_sortByDistance_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_sortByDistance_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_sortByDistance(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: commonjs // @Filename: /src/admin/utils/db/db.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go b/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go index ca04ad52c6..8c3dbe4a11 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_symlink(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @moduleResolution: bundler // @noLib: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go b/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go index 07f720b6e5..20f332b4bd 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_trailingComma(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: index.ts import { diff --git a/internal/fourslash/tests/gen/importNameCodeFix_typeOnly_test.go b/internal/fourslash/tests/gen/importNameCodeFix_typeOnly_test.go index c0ab3d1b70..c81ef37ec3 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_typeOnly_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_typeOnly_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_typeOnly(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: esnext // @verbatimModuleSyntax: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_typeUsedAsValue_test.go b/internal/fourslash/tests/gen/importNameCodeFix_typeUsedAsValue_test.go index 53d2931c4f..c44a172826 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_typeUsedAsValue_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_typeUsedAsValue_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_typeUsedAsValue(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export class ReadonlyArray {} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go b/internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go index 3af50482e0..5000eff555 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_withJson(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const a = 'a'; diff --git a/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go b/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go index 0803a88deb..9c86a023e2 100644 --- a/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go +++ b/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go @@ -9,7 +9,7 @@ import ( func TestModuleNodeNextAutoImport2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "module": "nodenext" } } diff --git a/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go b/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go index 79a3a1c638..0f9ba1e8ef 100644 --- a/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go +++ b/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go @@ -9,7 +9,7 @@ import ( func TestModuleNodeNextAutoImport3(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "module": "nodenext" } } From 51b6ac8c033559dcfbc86b9ba127dec9352ba73b Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 20:19:22 -0800 Subject: [PATCH 06/48] redo --- internal/checker/exports.go | 8 + internal/ls/codeactions.go | 246 ++--- internal/ls/codeactions_importfixes.go | 1206 ++++++++++++++++++++++++ 3 files changed, 1302 insertions(+), 158 deletions(-) create mode 100644 internal/ls/codeactions_importfixes.go diff --git a/internal/checker/exports.go b/internal/checker/exports.go index dc61a4a547..9fd8b979ab 100644 --- a/internal/checker/exports.go +++ b/internal/checker/exports.go @@ -170,3 +170,11 @@ func (c *Checker) GetIndexSignaturesAtLocation(node *ast.Node) []*ast.Node { func (c *Checker) GetResolvedSymbol(node *ast.Node) *ast.Symbol { return c.getResolvedSymbol(node) } + +func (c *Checker) GetJsxNamespace(location *ast.Node) string { + return c.getJsxNamespace(location) +} + +func (c *Checker) ResolveName(name string, location *ast.Node, meaning ast.SymbolFlags, excludeGlobals bool) *ast.Symbol { + return c.resolveName(location, name, meaning, nil, true, excludeGlobals) +} diff --git a/internal/ls/codeactions.go b/internal/ls/codeactions.go index 26b500ffa1..4cf6ed27dc 100644 --- a/internal/ls/codeactions.go +++ b/internal/ls/codeactions.go @@ -2,195 +2,125 @@ package ls import ( "context" - "fmt" + "slices" "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/diagnostics" + "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/lsp/lsproto" ) -// Import-related diagnostic codes that can be fixed with auto-import -var importFixDiagnosticCodes = map[int32]struct{}{ - diagnostics.Cannot_find_name_0.Code(): {}, - diagnostics.Cannot_find_name_0_Did_you_mean_1.Code(): {}, - diagnostics.Cannot_find_namespace_0.Code(): {}, - diagnostics.Module_0_has_no_exported_member_1.Code(): {}, - diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations.Code(): {}, +// CodeFixProvider represents a provider for a specific type of code fix +type CodeFixProvider struct { + ErrorCodes []int32 + GetCodeActions func(ctx context.Context, fixContext *CodeFixContext) []CodeAction + FixIds []string + GetAllCodeActions func(ctx context.Context, fixContext *CodeFixContext) *CombinedCodeActions } -// ProvideCodeActions returns code actions for the given range and context -func (l *LanguageService) ProvideCodeActions(ctx context.Context, params *lsproto.CodeActionParams) (lsproto.CodeActionResponse, error) { - program, file := l.getProgramAndFile(params.TextDocument.Uri) - - var actions []lsproto.CommandOrCodeAction +// CodeFixContext contains the context needed to generate code fixes +type CodeFixContext struct { + SourceFile *ast.SourceFile + Span core.TextRange + ErrorCode int32 + Program *compiler.Program + Checker *checker.Checker + LS *LanguageService + Diagnostic *lsproto.Diagnostic + Params *lsproto.CodeActionParams +} - // Process diagnostics in the context to generate quick fixes - if params.Context != nil && params.Context.Diagnostics != nil { - for _, diag := range params.Context.Diagnostics { - // Check if this is an import-related diagnostic - if diag.Code.Integer != nil { - if _, isImportDiag := importFixDiagnosticCodes[*diag.Code.Integer]; isImportDiag { - importActions := l.getImportCodeActionsForDiagnostic(ctx, program, file, diag, params) - actions = append(actions, importActions...) - } - } - } - } +// CodeAction represents a single code action fix +type CodeAction struct { + Description string + Changes []*lsproto.TextEdit +} - if len(actions) == 0 { - return lsproto.CommandOrCodeActionArrayOrNull{CommandOrCodeActionArray: &[]lsproto.CommandOrCodeAction{}}, nil - } +// CombinedCodeActions represents combined code actions for fix-all scenarios +type CombinedCodeActions struct { + Description string + Changes []*lsproto.TextEdit +} - return lsproto.CommandOrCodeActionArrayOrNull{CommandOrCodeActionArray: &actions}, nil +// codeFixProviders is the list of all registered code fix providers +var codeFixProviders = []*CodeFixProvider{ + ImportFixProvider, + // Add more code fix providers here as they are implemented } -// getImportCodeActionsForDiagnostic generates auto-import code actions for a diagnostic -func (l *LanguageService) getImportCodeActionsForDiagnostic( - ctx context.Context, - program *compiler.Program, - file *ast.SourceFile, - diag *lsproto.Diagnostic, - params *lsproto.CodeActionParams, -) []lsproto.CommandOrCodeAction { +// ProvideCodeActions returns code actions for the given range and context +func (l *LanguageService) ProvideCodeActions(ctx context.Context, params *lsproto.CodeActionParams) (lsproto.CodeActionResponse, error) { + program, file := l.getProgramAndFile(params.TextDocument.Uri) + // Get the type checker ch, done := program.GetTypeCheckerForFile(ctx, file) if done != nil { defer done() } - // Get the position from the diagnostic - position := l.converters.LineAndCharacterToPosition(file, diag.Range.Start) - - // Get the token at the diagnostic position - token := astnav.GetTokenAtPosition(file, int(position)) - if token == nil { - return nil - } - - // Token should be an identifier - if !ast.IsIdentifier(token) { - return nil - } - - // Extract the symbol name from the identifier - symbolName := token.Text() - if symbolName == "" { - return nil - } - - // Get the meaning from the token location to filter exports properly - meaning := getMeaningFromLocation(token) - - // Search for all exports matching this symbol name - exportInfos := l.searchExportInfosForCodeAction(ctx, ch, file, symbolName, meaning) - if len(exportInfos) == 0 { - return nil - } - - // Get all import fixes for the symbol, which will be sorted by preference - isValidTypeOnlyUseSite := ast.IsValidTypeOnlyAliasUseSite(token) - useRequire := getShouldUseRequire(file, program) - _, fixes := l.getImportFixes(ch, exportInfos, &diag.Range.Start, &isValidTypeOnlyUseSite, &useRequire, file, false) - var actions []lsproto.CommandOrCodeAction - // Limit to top 3 import suggestions to avoid overwhelming the user - maxActions := 3 - for i, fix := range fixes { - if i >= maxActions { - break - } + // Process diagnostics in the context to generate quick fixes + if params.Context != nil && params.Context.Diagnostics != nil { + for _, diag := range params.Context.Diagnostics { + if diag.Code.Integer == nil { + continue + } - // Create the code action using the fix - internalAction := l.codeActionForFix(ctx, file, symbolName, fix, false) + errorCode := *diag.Code.Integer - // Convert internal code action to LSP CodeAction - if len(internalAction.changes) > 0 { - kind := lsproto.CodeActionKindQuickFix - title := fmt.Sprintf("Import %s from \"%s\"", symbolName, fix.moduleSpecifier) + // Check all code fix providers + for _, provider := range codeFixProviders { + if !containsErrorCode(provider.ErrorCodes, errorCode) { + continue + } - changes := map[lsproto.DocumentUri][]*lsproto.TextEdit{ - params.TextDocument.Uri: internalAction.changes, - } - diagnostics := []*lsproto.Diagnostic{diag} - codeAction := &lsproto.CodeAction{ - Title: title, - Kind: &kind, - Edit: &lsproto.WorkspaceEdit{ - Changes: &changes, - }, - Diagnostics: &diagnostics, + // Create context for the provider + position := l.converters.LineAndCharacterToPosition(file, diag.Range.Start) + endPosition := l.converters.LineAndCharacterToPosition(file, diag.Range.End) + fixContext := &CodeFixContext{ + SourceFile: file, + Span: core.NewTextRange(int(position), int(endPosition)), + ErrorCode: errorCode, + Program: program, + Checker: ch, + LS: l, + Diagnostic: diag, + Params: params, + } + + // Get code actions from the provider + providerActions := provider.GetCodeActions(ctx, fixContext) + for _, action := range providerActions { + actions = append(actions, convertToLSPCodeAction(&action, diag, params.TextDocument.Uri)) + } } - actions = append(actions, lsproto.CommandOrCodeAction{CodeAction: codeAction}) } } - return actions + return lsproto.CommandOrCodeActionArrayOrNull{CommandOrCodeActionArray: &actions}, nil } -// searchExportInfosForCodeAction searches for exports that match the given symbol name -// This follows the same pattern as TypeScript's getExportInfos in importFixes.ts -func (l *LanguageService) searchExportInfosForCodeAction( - ctx context.Context, - ch *checker.Checker, - importingFile *ast.SourceFile, - symbolName string, - meaning ast.SemanticMeaning, -) []*SymbolExportInfo { - var results []*SymbolExportInfo - moduleCount := 0 - - // Iterate through all available modules to find exports matching the symbol name - forEachExternalModuleToImportFrom( - ch, - l.GetProgram(), - func(moduleSymbol *ast.Symbol, moduleFile *ast.SourceFile, ch *checker.Checker, isFromPackageJson bool) { - if moduleCount = moduleCount + 1; moduleCount%100 == 0 && ctx.Err() != nil { - return - } - - moduleFileName := "" - if moduleFile != nil { - moduleFileName = moduleFile.FileName() - } - - // Check if the module has an export with the exact symbol name - exportedSymbol := ch.TryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol) - if exportedSymbol != nil && isImportableSymbol(exportedSymbol, ch) { - // Filter by semantic meaning to match what the token location expects - if symbolFlagsHaveMeaning(exportedSymbol.Flags, meaning) { - results = append(results, &SymbolExportInfo{ - symbol: exportedSymbol, - moduleSymbol: moduleSymbol, - moduleFileName: moduleFileName, - exportKind: ExportKindNamed, - targetFlags: ch.SkipAlias(exportedSymbol).Flags, - isFromPackageJson: isFromPackageJson, - }) - } - } +// containsErrorCode checks if the error code is in the list +func containsErrorCode(codes []int32, code int32) bool { + return slices.Contains(codes, code) +} - // Also check default exports - defaultInfo := getDefaultLikeExportInfo(moduleSymbol, ch) - if defaultInfo != nil && isImportableSymbol(defaultInfo.exportingModuleSymbol, ch) { - // Check if the default export's name matches and has the right meaning - if defaultInfo.exportingModuleSymbol.Name == symbolName && - symbolFlagsHaveMeaning(defaultInfo.exportingModuleSymbol.Flags, meaning) { - results = append(results, &SymbolExportInfo{ - symbol: defaultInfo.exportingModuleSymbol, - moduleSymbol: moduleSymbol, - moduleFileName: moduleFileName, - exportKind: defaultInfo.exportKind, - targetFlags: ch.SkipAlias(defaultInfo.exportingModuleSymbol).Flags, - isFromPackageJson: isFromPackageJson, - }) - } - } +// convertToLSPCodeAction converts an internal CodeAction to an LSP CodeAction +func convertToLSPCodeAction(action *CodeAction, diag *lsproto.Diagnostic, uri lsproto.DocumentUri) lsproto.CommandOrCodeAction { + kind := lsproto.CodeActionKindQuickFix + changes := map[lsproto.DocumentUri][]*lsproto.TextEdit{ + uri: action.Changes, + } + diagnostics := []*lsproto.Diagnostic{diag} + + return lsproto.CommandOrCodeAction{ + CodeAction: &lsproto.CodeAction{ + Title: action.Description, + Kind: &kind, + Edit: &lsproto.WorkspaceEdit{Changes: &changes}, + Diagnostics: &diagnostics, }, - ) - - return results + } } diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go new file mode 100644 index 0000000000..06ae606e62 --- /dev/null +++ b/internal/ls/codeactions_importfixes.go @@ -0,0 +1,1206 @@ +package ls + +import ( + "cmp" + "context" + "fmt" + "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/collections" + "github.com/microsoft/typescript-go/internal/compiler" + "github.com/microsoft/typescript-go/internal/core" + "github.com/microsoft/typescript-go/internal/diagnostics" + "github.com/microsoft/typescript-go/internal/ls/change" + "github.com/microsoft/typescript-go/internal/ls/organizeimports" + "github.com/microsoft/typescript-go/internal/lsp/lsproto" + "github.com/microsoft/typescript-go/internal/modulespecifiers" + "github.com/microsoft/typescript-go/internal/outputpaths" + "github.com/microsoft/typescript-go/internal/scanner" + "github.com/microsoft/typescript-go/internal/tspath" +) + +// Import fix diagnostic codes (from importFixes.ts errorCodes) +var importFixErrorCodes = []int32{ + diagnostics.Cannot_find_name_0.Code(), + diagnostics.Cannot_find_name_0_Did_you_mean_1.Code(), + diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.Code(), + diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0.Code(), + diagnostics.Cannot_find_namespace_0.Code(), + diagnostics.X_0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.Code(), + diagnostics.X_0_only_refers_to_a_type_but_is_being_used_as_a_value_here.Code(), + diagnostics.No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer.Code(), + diagnostics.X_0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type.Code(), + diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery.Code(), + diagnostics.Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_1_or_later.Code(), + diagnostics.Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_include_dom.Code(), + diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig.Code(), + diagnostics.Cannot_find_name_0_Did_you_mean_to_write_this_in_an_async_function.Code(), + diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig.Code(), + diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha.Code(), + diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode.Code(), + diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig.Code(), + diagnostics.Cannot_find_namespace_0_Did_you_mean_1.Code(), + diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements.Code(), + diagnostics.This_JSX_tag_requires_0_to_be_in_scope_but_it_could_not_be_found.Code(), +} + +const ( + importFixID = "fixMissingImport" +) + +// ImportFixProvider is the CodeFixProvider for import-related fixes (registerCodeFix in importFixes.ts) +var ImportFixProvider = &CodeFixProvider{ + ErrorCodes: importFixErrorCodes, + GetCodeActions: getImportCodeActions, + FixIds: []string{importFixID}, +} + +// fixInfo represents information about a single fix (from importFixes.ts) +type fixInfo struct { + fix *ImportFix + symbolName string + errorIdentifierText string + isJsxNamespaceFix bool +} + +// getImportCodeActions generates import code actions (from registerCodeFix getCodeActions in importFixes.ts) +func getImportCodeActions(ctx context.Context, fixContext *CodeFixContext) []CodeAction { + info := getFixInfos(ctx, fixContext, fixContext.ErrorCode, fixContext.Span.Pos(), true /* useAutoImportProvider */) + if len(info) == 0 { + return nil + } + + var actions []CodeAction + for _, fixInfo := range info { + action := codeActionForFix(ctx, fixContext, fixInfo) + if action != nil { + actions = append(actions, *action) + } + } + return actions +} + +// getFixInfos gets all fix information for the given context (from importFixes.ts) +func getFixInfos(ctx context.Context, fixContext *CodeFixContext, errorCode int32, pos int, useAutoImportProvider bool) []*fixInfo { + symbolToken := astnav.GetTokenAtPosition(fixContext.SourceFile, pos) + + var info []*fixInfo + + if errorCode == diagnostics.X_0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.Code() { + info = getFixesInfoForUMDImport(ctx, fixContext, symbolToken) + } else if !ast.IsIdentifier(symbolToken) { + return nil + } else if errorCode == diagnostics.X_0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type.Code() { + // Handle type-only import promotion + ch, done := fixContext.Program.GetTypeChecker(ctx) + defer done() + compilerOptions := fixContext.Program.Options() + symbolNames := getSymbolNamesToImport(fixContext.SourceFile, ch, symbolToken, compilerOptions) + if len(symbolNames) != 1 { + panic("Expected exactly one symbol name for type-only import promotion") + } + symbolName := symbolNames[0] + fix := getTypeOnlyPromotionFix(ctx, fixContext.SourceFile, symbolToken, symbolName, fixContext.Program) + if fix != nil { + return []*fixInfo{{fix: fix, symbolName: symbolName, errorIdentifierText: symbolToken.Text()}} + } + return nil + } else { + info = getFixesInfoForNonUMDImport(ctx, fixContext, symbolToken, useAutoImportProvider) + } + + // Sort fixes by preference + return sortFixInfo(info, fixContext) +} + +// getFixesInfoForUMDImport gets fixes for UMD imports (from importFixes.ts) +func getFixesInfoForUMDImport(ctx context.Context, fixContext *CodeFixContext, token *ast.Node) []*fixInfo { + ch, done := fixContext.Program.GetTypeChecker(ctx) + defer done() + + umdSymbol := getUmdSymbol(token, ch) + if umdSymbol == nil { + return nil + } + + symbol := ch.GetAliasedSymbol(umdSymbol) + symbolName := umdSymbol.Name + exportInfo := []*SymbolExportInfo{{ + symbol: umdSymbol, + moduleSymbol: symbol, + moduleFileName: "", + exportKind: ExportKindUMD, + targetFlags: symbol.Flags, + isFromPackageJson: false, + }} + + useRequire := shouldUseRequire(fixContext.SourceFile, fixContext.Program) + // `usagePosition` is undefined because `token` may not actually be a usage of the symbol we're importing. + // For example, we might need to import `React` in order to use an arbitrary JSX tag. We could send a position + // for other UMD imports, but `usagePosition` is currently only used to insert a namespace qualification + // before a named import, like converting `writeFile` to `fs.writeFile` (whether `fs` is already imported or + // not), and this function will only be called for UMD symbols, which are necessarily an `export =`, not a + // named export. + fixes := getImportFixes( + ctx, + exportInfo, + nil, // usagePosition undefined for UMD + false, + useRequire, + fixContext.Program, + fixContext.SourceFile, + fixContext.LS, + ) + + var result []*fixInfo + for _, fix := range fixes.fixes { + errorIdentifierText := "" + if ast.IsIdentifier(token) { + errorIdentifierText = token.Text() + } + result = append(result, &fixInfo{ + fix: fix, + symbolName: symbolName, + errorIdentifierText: errorIdentifierText, + }) + } + return result +} + +// getUmdSymbol tries to get the UMD symbol from a token (from importFixes.ts) +func getUmdSymbol(token *ast.Node, ch *checker.Checker) *ast.Symbol { + // try the identifier to see if it is the umd symbol + var umdSymbol *ast.Symbol + if ast.IsIdentifier(token) { + umdSymbol = ch.GetResolvedSymbol(token) + } + if isUMDExportSymbol(umdSymbol) { + return umdSymbol + } + + // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`. + parent := token.Parent + if (ast.IsJsxOpeningLikeElement(parent) && parent.AsJsxOpeningElement().TagName == token) || + ast.IsJsxOpeningFragment(parent) { + var location *ast.Node + if ast.IsJsxOpeningLikeElement(parent) { + location = token + } else { + location = parent + } + jsxNamespace := ch.GetJsxNamespace(parent) + parentSymbol := ch.ResolveName(jsxNamespace, location, ast.SymbolFlagsValue, false /* excludeGlobals */) + if isUMDExportSymbol(parentSymbol) { + return parentSymbol + } + } + return nil +} + +// isUMDExportSymbol checks if a symbol is a UMD export (from checker/symbolaccessibility.go) +func isUMDExportSymbol(symbol *ast.Symbol) bool { + return symbol != nil && len(symbol.Declarations) > 0 && + symbol.Declarations[0] != nil && + ast.IsNamespaceExportDeclaration(symbol.Declarations[0]) +} + +// getFixesInfoForNonUMDImport gets fixes for non-UMD imports (from importFixes.ts) +func getFixesInfoForNonUMDImport(ctx context.Context, fixContext *CodeFixContext, symbolToken *ast.Node, useAutoImportProvider bool) []*fixInfo { + ch, done := fixContext.Program.GetTypeChecker(ctx) + defer done() + compilerOptions := fixContext.Program.Options() + + symbolNames := getSymbolNamesToImport(fixContext.SourceFile, ch, symbolToken, compilerOptions) + var allInfo []*fixInfo + + for _, symbolName := range symbolNames { + // "default" is a keyword and not a legal identifier for the import + if symbolName == "default" { + continue + } + + isValidTypeOnlyUseSite := ast.IsValidTypeOnlyAliasUseSite(symbolToken) + useRequire := shouldUseRequire(fixContext.SourceFile, fixContext.Program) + exportInfos := getExportInfos( + ctx, + symbolName, + isJSXTagName(symbolToken), + getMeaningFromLocation(symbolToken), + fixContext.SourceFile, + fixContext.Program, + useAutoImportProvider, + fixContext.LS, + ) + + for exportInfoList := range exportInfos.Values() { + for _, exportInfo := range exportInfoList { + usagePos := scanner.GetTokenPosOfNode(symbolToken, fixContext.SourceFile, false) + fixes := getImportFixes( + ctx, + []*SymbolExportInfo{exportInfo}, + &usagePos, + isValidTypeOnlyUseSite, + useRequire, + fixContext.Program, + fixContext.SourceFile, + fixContext.LS, + ) + + for _, fix := range fixes.fixes { + allInfo = append(allInfo, &fixInfo{ + fix: fix, + symbolName: symbolName, + errorIdentifierText: symbolToken.Text(), + isJsxNamespaceFix: symbolName != symbolToken.Text(), + }) + } + } + } + } + + return allInfo +} + +// getTypeOnlyPromotionFix gets a fix for promoting a type-only import (from importFixes.ts) +func getTypeOnlyPromotionFix(ctx context.Context, sourceFile *ast.SourceFile, symbolToken *ast.Node, symbolName string, program *compiler.Program) *ImportFix { + ch, done := program.GetTypeChecker(ctx) + defer done() + + // Get the symbol at the token location + symbol := ch.ResolveName(symbolName, symbolToken, ast.SymbolFlagsValue, true /* excludeGlobals */) + if symbol == nil { + return nil + } + + // Get the type-only alias declaration + typeOnlyAliasDeclaration := ch.GetTypeOnlyAliasDeclaration(symbol) + if typeOnlyAliasDeclaration == nil || ast.GetSourceFileOfNode(typeOnlyAliasDeclaration) != sourceFile { + return nil + } + + return &ImportFix{ + kind: ImportFixKindPromoteTypeOnly, + typeOnlyAliasDeclaration: typeOnlyAliasDeclaration, + } +} + +// getSymbolNamesToImport gets the symbol names to import (from importFixes.ts) +func getSymbolNamesToImport(sourceFile *ast.SourceFile, ch *checker.Checker, symbolToken *ast.Node, compilerOptions *core.CompilerOptions) []string { + parent := symbolToken.Parent + if (ast.IsJsxOpeningLikeElement(parent) || ast.IsJsxClosingElement(parent)) && + parent.AsJsxOpeningElement().TagName == symbolToken && + jsxModeNeedsExplicitImport(compilerOptions.Jsx) { + jsxNamespace := ch.GetJsxNamespace(sourceFile.AsNode()) + if needsJsxNamespaceFix(jsxNamespace, symbolToken, ch) { + needsComponentNameFix := !scanner.IsIntrinsicJsxName(symbolToken.Text()) && + ch.ResolveName(symbolToken.Text(), symbolToken, ast.SymbolFlagsValue, false /* excludeGlobals */) == nil + if needsComponentNameFix { + return []string{symbolToken.Text(), jsxNamespace} + } + return []string{jsxNamespace} + } + } + return []string{symbolToken.Text()} +} + +// needsJsxNamespaceFix checks if JSX namespace fix is needed (from importFixes.ts) +func needsJsxNamespaceFix(jsxNamespace string, symbolToken *ast.Node, ch *checker.Checker) bool { + if scanner.IsIntrinsicJsxName(symbolToken.Text()) { + return true + } + namespaceSymbol := ch.ResolveName(jsxNamespace, symbolToken, ast.SymbolFlagsValue, true /* excludeGlobals */) + if namespaceSymbol == nil { + return true + } + // Check if all declarations are type-only + if slices.ContainsFunc(namespaceSymbol.Declarations, ast.IsTypeOnlyImportOrExportDeclaration) { + return (namespaceSymbol.Flags & ast.SymbolFlagsValue) == 0 + } + return false +} + +// jsxModeNeedsExplicitImport checks if JSX mode needs explicit import (from importFixes.ts) +func jsxModeNeedsExplicitImport(jsx core.JsxEmit) bool { + return jsx == core.JsxEmitReact || jsx == core.JsxEmitReactNative +} + +// getExportInfos searches for exports (from importFixes.ts) +func getExportInfos( + ctx context.Context, + symbolName string, + isJsxTagName bool, + currentTokenMeaning ast.SemanticMeaning, + fromFile *ast.SourceFile, + program *compiler.Program, + useAutoImportProvider bool, + ls *LanguageService, +) *collections.MultiMap[ast.SymbolId, *SymbolExportInfo] { + // For each original symbol, keep all re-exports of that symbol together + // Maps symbol id to info for modules providing that symbol (original export + re-exports) + originalSymbolToExportInfos := &collections.MultiMap[ast.SymbolId, *SymbolExportInfo]{} + + ch, done := program.GetTypeChecker(ctx) + defer done() + + packageJsonFilter := ls.createPackageJsonImportFilter(fromFile) + + // Helper to add a symbol to the results map + addSymbol := func(moduleSymbol *ast.Symbol, toFile *ast.SourceFile, exportedSymbol *ast.Symbol, exportKind ExportKind, isFromPackageJson bool) { + if !ls.isImportable(fromFile, toFile, moduleSymbol, packageJsonFilter) { + return + } + + // Get unique ID for the exported symbol + symbolID := ast.GetSymbolId(exportedSymbol) + + originalSymbolToExportInfos.Add(symbolID, &SymbolExportInfo{ + symbol: exportedSymbol, + moduleSymbol: moduleSymbol, + moduleFileName: core.IfElse(toFile != nil, toFile.FileName(), ""), + exportKind: exportKind, + targetFlags: ch.SkipAlias(exportedSymbol).Flags, + isFromPackageJson: isFromPackageJson, + }) + } + + // Iterate through all external modules + forEachExternalModuleToImportFrom( + ch, + program, + func(moduleSymbol *ast.Symbol, sourceFile *ast.SourceFile, checker *checker.Checker, isFromPackageJson bool) { + // Check for cancellation + if ctx.Err() != nil { + return + } + + compilerOptions := program.Options() + + // Check default export + defaultInfo := getDefaultLikeExportInfo(moduleSymbol, checker) + if defaultInfo != nil { + if symbolFlagsHaveMeaning(defaultInfo.exportingModuleSymbol.Flags, currentTokenMeaning) { + // For JSX tags, we need to check if the capitalized name matches + scriptTarget := compilerOptions.GetEmitScriptTarget() + matchesName := forEachNameOfDefaultExport(defaultInfo.exportingModuleSymbol, checker, scriptTarget, func(name, capitalizedName string) string { + actualName := name + if isJsxTagName && capitalizedName != "" { + actualName = capitalizedName + } + if actualName == symbolName { + return actualName + } + return "" + }) + if matchesName != "" { + addSymbol(moduleSymbol, sourceFile, defaultInfo.exportingModuleSymbol, defaultInfo.exportKind, isFromPackageJson) + } + } + } + + // Check for named export with identical name + exportSymbol := checker.TryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol) + if exportSymbol != nil && symbolFlagsHaveMeaning(exportSymbol.Flags, currentTokenMeaning) { + addSymbol(moduleSymbol, sourceFile, exportSymbol, ExportKindNamed, isFromPackageJson) + } + }, + ) + + return originalSymbolToExportInfos +} + +// symbolFlagsHaveMeaning already exists in utilities.go + +// getImportFixes gets import fixes for export infos (from importFixes.ts getImportFixes) +type importFixesResult struct { + fixes []*ImportFix + computedWithoutCacheCount int +} + +func getImportFixes( + ctx context.Context, + exportInfos []*SymbolExportInfo, + usagePosition *int, + isValidTypeOnlyUseSite bool, + useRequire bool, + program *compiler.Program, + sourceFile *ast.SourceFile, + ls *LanguageService, +) *importFixesResult { + ch, done := program.GetTypeChecker(ctx) + defer done() + + // Create import map of existing imports + importMap := createExistingImportMap(sourceFile, program, ch) + + // Get existing imports that could be extended + var existingImports []*FixAddToExistingImportInfo + for _, exportInfo := range exportInfos { + existingForExport := importMap.getImportsForExportInfo(exportInfo) + existingImports = append(existingImports, existingForExport...) + } + + // Try to use existing namespace import + var useNamespace *ImportFix + if usagePosition != nil { + // Convert text position to LSP position + line, character := scanner.GetECMALineAndCharacterOfPosition(sourceFile, *usagePosition) + useNamespace = tryUseExistingNamespaceImport(existingImports, lsproto.Position{ + Line: uint32(line), + Character: uint32(character), + }) + } + + // Try to add to existing import + addToExisting := tryAddToExistingImport(existingImports, &isValidTypeOnlyUseSite, ch, program.Options()) + + if addToExisting != nil { + // Don't bother providing an action to add a new import if we can add to an existing one. + fixes := []*ImportFix{} + if useNamespace != nil { + fixes = append(fixes, useNamespace) + } + fixes = append(fixes, addToExisting) + return &importFixesResult{ + fixes: fixes, + computedWithoutCacheCount: 0, + } + } + + // Get fixes for adding new imports using the existing implementation + var usagePos *lsproto.Position + if usagePosition != nil { + line, character := scanner.GetECMALineAndCharacterOfPosition(sourceFile, *usagePosition) + usagePos = &lsproto.Position{Line: uint32(line), Character: uint32(character)} + } + + // Call getFixesForAddImport which has full module specifier caching support + newImportFixes := ls.getFixesForAddImport( + ch, + exportInfos, + existingImports, + sourceFile, + usagePos, + isValidTypeOnlyUseSite, + useRequire, + false, // fromCacheOnly + ) + + fixes := []*ImportFix{} + if useNamespace != nil { + fixes = append(fixes, useNamespace) + } + fixes = append(fixes, newImportFixes...) + + return &importFixesResult{ + fixes: fixes, + computedWithoutCacheCount: 0, + } +} + +// shouldUseRequire determines if require should be used (from importFixes.ts) +func shouldUseRequire(sourceFile *ast.SourceFile, program *compiler.Program) bool { + // Delegate to the existing implementation in autoimports.go + return getShouldUseRequire(sourceFile, program) +} + +// codeActionForFix creates a code action for a fix (from importFixes.ts codeActionForFix) +func codeActionForFix(ctx context.Context, fixContext *CodeFixContext, info *fixInfo) *CodeAction { + // Create a tracker with format options and converters from LanguageService + tracker := change.NewTracker(ctx, fixContext.Program.Options(), fixContext.LS.FormatOptions(), fixContext.LS.converters) + + description := codeActionForFixWorker( + ctx, + tracker, + fixContext.SourceFile, + info.symbolName, + info.fix, + info.symbolName != info.errorIdentifierText, + fixContext.Program, + fixContext.LS, + ) + + if description == "" { + return nil + } + + // Convert changes to LSP edits + changes := tracker.GetChanges() + var edits []*lsproto.TextEdit + for _, fileChanges := range changes { + edits = append(edits, fileChanges...) + } + + return &CodeAction{ + Description: description, + Changes: edits, + } +} + +// codeActionForFixWorker generates changes for a fix (from importFixes.ts codeActionForFixWorker) +func codeActionForFixWorker( + ctx context.Context, + changes *change.Tracker, + sourceFile *ast.SourceFile, + symbolName string, + fix *ImportFix, + includeSymbolNameInDescription bool, + program *compiler.Program, + ls *LanguageService, +) string { + switch fix.kind { + case ImportFixKindUseNamespace: + addNamespaceQualifier(changes, sourceFile, fix.qualification()) + return diagnostics.FormatMessage(diagnostics.Change_0_to_1, symbolName, fmt.Sprintf("%s.%s", *fix.namespacePrefix, symbolName)).Message() + + case ImportFixKindJsdocTypeImport: + // Insert import() type annotation at usage position + if fix.usagePosition == nil { + return "" + } + quotePreference := getQuotePreference(sourceFile, ls.UserPreferences()) + quoteChar := "\"" + if quotePreference == quotePreferenceSingle { + quoteChar = "'" + } + importTypePrefix := fmt.Sprintf("import(%s%s%s).", quoteChar, fix.moduleSpecifier, quoteChar) + + changes.InsertText(sourceFile, *fix.usagePosition, importTypePrefix) + + return diagnostics.FormatMessage(diagnostics.Change_0_to_1, symbolName, importTypePrefix+symbolName).Message() + + case ImportFixKindAddToExisting: + // Call doAddExistingFix from autoimportfixes.go + var defaultImport *Import + var namedImports []*Import + + if fix.importKind == ImportKindDefault { + defaultImport = &Import{ + name: symbolName, + addAsTypeOnly: fix.addAsTypeOnly, + } + } else if fix.importKind == ImportKindNamed { + namedImports = []*Import{ + { + name: symbolName, + addAsTypeOnly: fix.addAsTypeOnly, + propertyName: fix.propertyName, + }, + } + } + + ls.doAddExistingFix( + changes, + sourceFile, + fix.importClauseOrBindingPattern, + defaultImport, + namedImports, + ) + + moduleSpecifierWithoutQuotes := strings.Trim(fix.moduleSpecifier, "\"'") + if includeSymbolNameInDescription { + return diagnostics.FormatMessage(diagnostics.Import_0_from_1, symbolName, moduleSpecifierWithoutQuotes).Message() + } + return diagnostics.FormatMessage(diagnostics.Update_import_from_0, moduleSpecifierWithoutQuotes).Message() + + case ImportFixKindAddNew: + // Generate new import statement + var defaultImport *Import + var namedImports []*Import + var namespaceLikeImport *Import + + if fix.importKind == ImportKindDefault { + defaultImport = &Import{ + name: symbolName, + addAsTypeOnly: fix.addAsTypeOnly, + } + } else if fix.importKind == ImportKindNamed { + namedImports = []*Import{ + { + name: symbolName, + addAsTypeOnly: fix.addAsTypeOnly, + propertyName: fix.propertyName, + }, + } + } else if fix.importKind == ImportKindNamespace || fix.importKind == ImportKindCommonJS { + // For namespace/CommonJS imports, use qualification if available + name := symbolName + if fix.qualification() != nil { + name = fix.qualification().namespacePrefix + } + namespaceLikeImport = &Import{ + name: name, + kind: fix.importKind, + addAsTypeOnly: fix.addAsTypeOnly, + } + } + + // Create the import declarations + var statements []*ast.Statement + if fix.useRequire { + statements = getNewRequires(changes, fix.moduleSpecifier, defaultImport, namedImports, namespaceLikeImport, program.Options()) + } else { + quotePreference := getQuotePreference(sourceFile, ls.UserPreferences()) + statements = ls.getNewImports(changes, fix.moduleSpecifier, quotePreference, defaultImport, namedImports, namespaceLikeImport, program.Options()) + } + + // Insert the import statements + changes.InsertAtTopOfFile(sourceFile, statements, true) + + // Add namespace qualification if needed + if fix.qualification() != nil { + addNamespaceQualifier(changes, sourceFile, fix.qualification()) + } + + if includeSymbolNameInDescription { + return diagnostics.FormatMessage(diagnostics.Import_0_from_1, symbolName, fix.moduleSpecifier).Message() + } + return diagnostics.FormatMessage(diagnostics.Add_import_from_0, fix.moduleSpecifier).Message() + + case ImportFixKindPromoteTypeOnly: + // Promote type-only import to regular import + promotedDeclaration := promoteFromTypeOnly(changes, fix.typeOnlyAliasDeclaration, program, sourceFile, ls) + + // Use the promoted declaration to get the module specifier for better diagnostics + if promotedDeclaration.Kind == ast.KindImportSpecifier { + // ImportSpecifier: get module specifier from parent.parent (ImportClause.parent = ImportDeclaration) + moduleSpec := getModuleSpecifierFromDeclaration(promotedDeclaration.Parent.Parent) + return diagnostics.FormatMessage(diagnostics.Remove_type_from_import_of_0_from_1, symbolName, moduleSpec).Message() + } + // ImportClause or ImportEqualsDeclaration: get module specifier directly + moduleSpec := getModuleSpecifierFromDeclaration(promotedDeclaration) + return diagnostics.FormatMessage(diagnostics.Remove_type_from_import_declaration_from_0, moduleSpec).Message() + + default: + return "" + } +} + +// getMeaningFromLocation already exists in utilities.go + +// isJSXTagName checks if a node is a JSX tag name +func isJSXTagName(node *ast.Node) bool { + parent := node.Parent + if parent == nil { + return false + } + if ast.IsJsxOpeningElement(parent) || ast.IsJsxClosingElement(parent) { + return parent.AsJsxOpeningElement().TagName == node + } + return false +} + +// getModuleSpecifierFromDeclaration gets the module specifier string from a declaration +func getModuleSpecifierFromDeclaration(decl *ast.Declaration) string { + var moduleSpec *ast.Node + + switch decl.Kind { + case ast.KindImportDeclaration: + moduleSpec = decl.AsImportDeclaration().ModuleSpecifier + case ast.KindImportEqualsDeclaration: + importEq := decl.AsImportEqualsDeclaration() + if importEq.ModuleReference != nil && importEq.ModuleReference.Kind == ast.KindExternalModuleReference { + moduleSpec = importEq.ModuleReference.AsExternalModuleReference().Expression + } + case ast.KindImportSpecifier: + // Walk up to find the import declaration + if clause := getImportClauseOfSpecifier(decl.AsImportSpecifier()); clause != nil { + if clause.Parent != nil && clause.Parent.Kind == ast.KindImportDeclaration { + moduleSpec = clause.Parent.AsImportDeclaration().ModuleSpecifier + } + } + case ast.KindImportClause: + if decl.Parent != nil && decl.Parent.Kind == ast.KindImportDeclaration { + moduleSpec = decl.Parent.AsImportDeclaration().ModuleSpecifier + } + case ast.KindNamespaceImport: + if decl.Parent != nil && decl.Parent.Kind == ast.KindImportClause { + if decl.Parent.Parent != nil && decl.Parent.Parent.Kind == ast.KindImportDeclaration { + moduleSpec = decl.Parent.Parent.AsImportDeclaration().ModuleSpecifier + } + } + } + + if moduleSpec != nil && ast.IsStringLiteral(moduleSpec) { + return moduleSpec.AsStringLiteral().Text + } + return "" +} + +// getImportClauseOfSpecifier gets the import clause containing a specifier +func getImportClauseOfSpecifier(spec *ast.ImportSpecifier) *ast.ImportClause { + if spec.Parent != nil && spec.Parent.Kind == ast.KindNamedImports { + if spec.Parent.Parent != nil && spec.Parent.Parent.Kind == ast.KindImportClause { + return spec.Parent.Parent.AsImportClause() + } + } + return nil +} + +// sortFixInfo sorts fixes by preference (from importFixes.ts sortFixInfo) +func sortFixInfo(fixes []*fixInfo, fixContext *CodeFixContext) []*fixInfo { + if len(fixes) == 0 { + return fixes + } + + // Create a copy to avoid modifying the original + sorted := make([]*fixInfo, len(fixes)) + copy(sorted, fixes) + + // Create package.json filter for import filtering + packageJsonFilter := fixContext.LS.createPackageJsonImportFilter(fixContext.SourceFile) + + // Sort by: + // 1. JSX namespace fixes last + // 2. Fix kind (UseNamespace and AddToExisting preferred) + // 3. Module specifier comparison + slices.SortFunc(sorted, func(a, b *fixInfo) int { + // JSX namespace fixes should come last + if cmp := core.CompareBooleans(a.isJsxNamespaceFix, b.isJsxNamespaceFix); cmp != 0 { + return cmp + } + + // Compare fix kinds (lower is better) + if cmp := cmp.Compare(int(a.fix.kind), int(b.fix.kind)); cmp != 0 { + return cmp + } + + // Compare module specifiers + return compareModuleSpecifiers(a.fix, b.fix, fixContext.SourceFile, fixContext.Program, packageJsonFilter, fixContext.LS) + }) + + return sorted +} + +// compareModuleSpecifiers compares two import fixes by their module specifiers (from importFixes.ts) +func compareModuleSpecifiers( + a, b *ImportFix, + sourceFile *ast.SourceFile, + program *compiler.Program, + packageJsonFilter *packageJsonImportFilter, + ls *LanguageService, +) int { + // For UseNamespace and AddToExisting, no further comparison needed + if a.kind == ImportFixKindUseNamespace || a.kind == ImportFixKindAddToExisting { + return 0 + } + if b.kind == ImportFixKindUseNamespace || b.kind == ImportFixKindAddToExisting { + return 0 + } + + // Compare package.json filtering - prefer imports allowed by package.json + if cmp := core.CompareBooleans( + b.moduleSpecifierKind != modulespecifiers.ResultKindNodeModules || packageJsonFilter.allowsImportingSpecifier(b.moduleSpecifier), + a.moduleSpecifierKind != modulespecifiers.ResultKindNodeModules || packageJsonFilter.allowsImportingSpecifier(a.moduleSpecifier), + ); cmp != 0 { + return cmp + } + + // Compare relativity based on user preferences + preferences := ls.UserPreferences() + switch preferences.ImportModuleSpecifierPreference { + case modulespecifiers.ImportModuleSpecifierPreferenceNonRelative, modulespecifiers.ImportModuleSpecifierPreferenceProjectRelative: + if cmp := core.CompareBooleans( + a.moduleSpecifierKind == modulespecifiers.ResultKindRelative, + b.moduleSpecifierKind == modulespecifiers.ResultKindRelative, + ); cmp != 0 { + return cmp + } + } + + // Compare node: prefix - prefer based on shouldUseUriStyleNodeCoreModules + if cmp := compareNodeCoreModuleSpecifiers(a.moduleSpecifier, b.moduleSpecifier, sourceFile, program); cmp != 0 { + return cmp + } + + // Compare re-export detection - avoid potential import cycles from barrel re-exports + toPath := func(fileName string) tspath.Path { + // Simple conversion - in real implementation this would use proper path resolution + return tspath.Path(fileName) + } + aIsReExport := isFixPossiblyReExportingImportingFile(a, sourceFile.Path(), toPath) + bIsReExport := isFixPossiblyReExportingImportingFile(b, sourceFile.Path(), toPath) + if cmp := core.CompareBooleans(aIsReExport, bIsReExport); cmp != 0 { + return cmp + } + + // Compare number of directory separators - prefer shorter paths + if cmp := tspath.CompareNumberOfDirectorySeparators(a.moduleSpecifier, b.moduleSpecifier); cmp != 0 { + return cmp + } + + // Final tiebreaker: lexicographic comparison + return strings.Compare(a.moduleSpecifier, b.moduleSpecifier) +} + +// promoteFromTypeOnly promotes a type-only import to a regular import (from importFixes.ts) +func promoteFromTypeOnly( + changes *change.Tracker, + aliasDeclaration *ast.Declaration, + program *compiler.Program, + sourceFile *ast.SourceFile, + ls *LanguageService, +) *ast.Declaration { + compilerOptions := program.Options() + // See comment in `doAddExistingFix` on constant with the same name. + convertExistingToTypeOnly := compilerOptions.VerbatimModuleSyntax + + switch aliasDeclaration.Kind { + case ast.KindImportSpecifier: + spec := aliasDeclaration.AsImportSpecifier() + if spec.IsTypeOnly { + // TODO: TypeScript creates a new specifier with isTypeOnly=false, computes insertion index, + // and if different from current position, deletes and re-inserts at new position. + // We just delete the type keyword which may result in incorrectly ordered imports. + // Also, TypeScript uses changes.deleteRange with getTokenPosOfNode for more precise range, + // we use a simpler approach. + + // If there are multiple specifiers, we might need to move this one + if spec.Parent != nil && spec.Parent.Kind == ast.KindNamedImports { + namedImports := spec.Parent.AsNamedImports() + if len(namedImports.Elements.Nodes) > 1 { + // For now, just remove the 'type' keyword from this specifier + // Full implementation would handle reordering + deleteTypeKeywordFromSpecifier(changes, sourceFile, spec) + } else { + // Single specifier - just remove the 'type' keyword + deleteTypeKeywordFromSpecifier(changes, sourceFile, spec) + } + } + return aliasDeclaration + } else { + // The parent import clause is type-only + if spec.Parent == nil || spec.Parent.Kind != ast.KindNamedImports { + panic("ImportSpecifier parent must be NamedImports") + } + if spec.Parent.Parent == nil || spec.Parent.Parent.Kind != ast.KindImportClause { + panic("NamedImports parent must be ImportClause") + } + promoteImportClause(changes, spec.Parent.Parent.AsImportClause(), program, sourceFile, ls, convertExistingToTypeOnly, aliasDeclaration) + return spec.Parent.Parent + } + + case ast.KindImportClause: + promoteImportClause(changes, aliasDeclaration.AsImportClause(), program, sourceFile, ls, convertExistingToTypeOnly, aliasDeclaration) + return aliasDeclaration + + case ast.KindNamespaceImport: + // Promote the parent import clause + if aliasDeclaration.Parent == nil || aliasDeclaration.Parent.Kind != ast.KindImportClause { + panic("NamespaceImport parent must be ImportClause") + } + promoteImportClause(changes, aliasDeclaration.Parent.AsImportClause(), program, sourceFile, ls, convertExistingToTypeOnly, aliasDeclaration) + return aliasDeclaration.Parent + + case ast.KindImportEqualsDeclaration: + // Remove the 'type' keyword (which is the second child: 'import' 'type' name '=' ...) + deleteTypeKeywordFromImportEquals(changes, sourceFile, aliasDeclaration.AsImportEqualsDeclaration()) + return aliasDeclaration + default: + panic(fmt.Sprintf("Unexpected alias declaration kind: %v", aliasDeclaration.Kind)) + } +} + +// promoteImportClause removes the type keyword from an import clause +func promoteImportClause( + changes *change.Tracker, + importClause *ast.ImportClause, + program *compiler.Program, + sourceFile *ast.SourceFile, + ls *LanguageService, + convertExistingToTypeOnly core.Tristate, + aliasDeclaration *ast.Declaration, +) { + // Delete the 'type' keyword + if importClause.PhaseModifier == ast.KindTypeKeyword { + deleteTypeKeywordFromImportClause(changes, sourceFile, importClause) + } + + // Handle .ts extension conversion to .js if necessary + compilerOptions := program.Options() + if compilerOptions.AllowImportingTsExtensions.IsFalse() { + moduleSpecifier := tryGetModuleSpecifierFromDeclaration(importClause.Parent) + if moduleSpecifier != nil { + resolvedModule := program.GetResolvedModuleFromModuleSpecifier(sourceFile, moduleSpecifier) + if resolvedModule != nil && resolvedModule.ResolvedUsingTsExtension { + moduleText := moduleSpecifier.AsStringLiteral().Text + changedExtension := tspath.ChangeExtension( + moduleText, + outputpaths.GetOutputExtension(moduleText, compilerOptions.Jsx), + ) + // Replace the module specifier with the new extension + // We need to update the string literal, keeping the quotes + replaceStringLiteral(changes, sourceFile, moduleSpecifier, changedExtension) + } + } + } + + // Handle verbatimModuleSyntax conversion + // If convertExistingToTypeOnly is true, we need to add 'type' to other specifiers + // in the same import declaration + if convertExistingToTypeOnly.IsTrue() { + namedImports := importClause.NamedBindings + if namedImports != nil && namedImports.Kind == ast.KindNamedImports { + namedImportsData := namedImports.AsNamedImports() + if len(namedImportsData.Elements.Nodes) > 1 { + // Check if the list is sorted and if we need to reorder + _, isSorted := organizeimports.GetNamedImportSpecifierComparerWithDetection( + importClause.Parent, + sourceFile, + ls.UserPreferences(), + ) + + // If the alias declaration is an ImportSpecifier and the list is sorted, + // move it to index 0 (since it will be the only non-type-only import) + if isSorted.IsFalse() == false && // isSorted !== false + aliasDeclaration != nil && + aliasDeclaration.Kind == ast.KindImportSpecifier { + // Find the index of the alias declaration + aliasIndex := -1 + for i, element := range namedImportsData.Elements.Nodes { + if element == aliasDeclaration { + aliasIndex = i + break + } + } + // If not already at index 0, move it there + if aliasIndex > 0 { + // Delete the specifier from its current position + deleteNode(changes, sourceFile, aliasDeclaration, namedImportsData.Elements.Nodes) + // Insert it at index 0 + changes.InsertImportSpecifierAtIndex(sourceFile, aliasDeclaration, namedImports, 0) + } + } + + // Add 'type' keyword to all other import specifiers that aren't already type-only + for _, element := range namedImportsData.Elements.Nodes { + spec := element.AsImportSpecifier() + // Skip the specifier being promoted (if aliasDeclaration is an ImportSpecifier) + if aliasDeclaration != nil && aliasDeclaration.Kind == ast.KindImportSpecifier { + if element == aliasDeclaration { + continue + } + } + // Skip if already type-only + if !spec.IsTypeOnly { + insertTypeModifierBefore(changes, sourceFile, element) + } + } + } + } + } +} + +// deleteTypeKeywordFromImportClause deletes the 'type' keyword from an import clause +func deleteTypeKeywordFromImportClause(changes *change.Tracker, sourceFile *ast.SourceFile, importClause *ast.ImportClause) { + // The type keyword is at the start of the import clause + // import type { foo } from "bar" + // ^^^^^ - this keyword + + // Find the position of the 'type' keyword and the space after it + clauseStart := importClause.Pos() + + // The 'type' keyword should be the first token in the import clause + // We want to delete "type " (including the trailing space) + typeKeywordEnd := clauseStart + 4 // length of "type" + + // Skip whitespace after 'type' to find the actual end position + text := sourceFile.Text() + endPos := typeKeywordEnd + for endPos < len(text) && (text[endPos] == ' ' || text[endPos] == '\t') { + endPos++ + } + + // Convert text positions to LSP positions + startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, clauseStart) + endLine, endChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, endPos) + + changes.ReplaceRangeWithText(sourceFile, lsproto.Range{ + Start: lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, + End: lsproto.Position{Line: uint32(endLine), Character: uint32(endChar)}, + }, "") +} + +// deleteTypeKeywordFromSpecifier deletes the 'type' keyword from an import specifier +func deleteTypeKeywordFromSpecifier(changes *change.Tracker, sourceFile *ast.SourceFile, spec *ast.ImportSpecifier) { + // import { type foo } from "bar" + // ^^^^^ - this keyword and space after + + specStart := spec.Pos() + + // The 'type' keyword is at the start of the specifier + // We want to delete "type " (including the trailing space) + typeKeywordEnd := specStart + 4 // length of "type" + + // Skip whitespace after 'type' + text := sourceFile.Text() + endPos := typeKeywordEnd + for endPos < len(text) && (text[endPos] == ' ' || text[endPos] == '\t') { + endPos++ + } + + // Convert text positions to LSP positions + startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, specStart) + endLine, endChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, endPos) + + changes.ReplaceRangeWithText(sourceFile, lsproto.Range{ + Start: lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, + End: lsproto.Position{Line: uint32(endLine), Character: uint32(endChar)}, + }, "") +} + +// deleteTypeKeywordFromImportEquals deletes the 'type' keyword from an import equals declaration +func deleteTypeKeywordFromImportEquals(changes *change.Tracker, sourceFile *ast.SourceFile, decl *ast.ImportEqualsDeclaration) { + // import type Foo = require("bar") + // ^^^^^ - this keyword and space after + + // The 'type' keyword comes after 'import' and before the name + // We need to find it by looking at the text + declStart := decl.Pos() + text := sourceFile.Text() + + // Skip 'import' keyword and whitespace + pos := declStart + 6 // length of "import" + for pos < len(text) && (text[pos] == ' ' || text[pos] == '\t') { + pos++ + } + + // Now we should be at 'type' + typeStart := pos + typeEnd := pos + 4 // length of "type" + + // Skip whitespace after 'type' + for typeEnd < len(text) && (text[typeEnd] == ' ' || text[typeEnd] == '\t') { + typeEnd++ + } + + // Convert text positions to LSP positions + startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, typeStart) + endLine, endChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, typeEnd) + + changes.ReplaceRangeWithText(sourceFile, lsproto.Range{ + Start: lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, + End: lsproto.Position{Line: uint32(endLine), Character: uint32(endChar)}, + }, "") +} + +// tryGetModuleSpecifierFromDeclaration tries to get the module specifier from a declaration (from utilities.ts) +func tryGetModuleSpecifierFromDeclaration(node *ast.Node) *ast.Node { + if node == nil { + return nil + } + + switch node.Kind { + case ast.KindImportDeclaration: + importDecl := node.AsImportDeclaration() + if ast.IsStringLiteral(importDecl.ModuleSpecifier) { + return importDecl.ModuleSpecifier + } + case ast.KindImportEqualsDeclaration: + importEqDecl := node.AsImportEqualsDeclaration() + if importEqDecl.ModuleReference != nil && importEqDecl.ModuleReference.Kind == ast.KindExternalModuleReference { + extModRef := importEqDecl.ModuleReference.AsExternalModuleReference() + if extModRef.Expression != nil && ast.IsStringLiteral(extModRef.Expression) { + return extModRef.Expression + } + } + } + return nil +} + +// replaceStringLiteral replaces a string literal with a new text value (from importFixes.ts) +func replaceStringLiteral(changes *change.Tracker, sourceFile *ast.SourceFile, stringLiteral *ast.Node, newText string) { + // Get the position of the string literal content (excluding quotes) + literalStart := stringLiteral.Pos() + literalEnd := stringLiteral.End() + + // Convert text positions to LSP positions + startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, literalStart) + endLine, endChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, literalEnd) + + // Determine the quote character used + text := sourceFile.Text() + quoteChar := text[literalStart] + + // Create the new string literal with quotes + newLiteral := string(quoteChar) + newText + string(quoteChar) + + changes.ReplaceRangeWithText(sourceFile, lsproto.Range{ + Start: lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, + End: lsproto.Position{Line: uint32(endLine), Character: uint32(endChar)}, + }, newLiteral) +} + +// insertTypeModifierBefore inserts the 'type' keyword before an import specifier (from importFixes.ts) +func insertTypeModifierBefore(changes *change.Tracker, sourceFile *ast.SourceFile, specifier *ast.Node) { + // Insert "type " before the specifier + // import { foo } => import { type foo } + specStart := specifier.Pos() + + // Convert text position to LSP position + startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, specStart) + + // Insert "type " at the beginning of the specifier + changes.InsertText(sourceFile, lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, "type ") +} + +// deleteNode deletes a node from a list (from importFixes.ts) +func deleteNode(changes *change.Tracker, sourceFile *ast.SourceFile, node *ast.Node, containingList []*ast.Node) { + // Find the node in the list to determine if we need to delete a comma + nodeIndex := -1 + for i, n := range containingList { + if n == node { + nodeIndex = i + break + } + } + + if nodeIndex == -1 { + return // Node not found in list + } + + // Determine the range to delete + start := node.Pos() + end := node.End() + + // If this is not the last element, we need to include the comma after it + if nodeIndex < len(containingList)-1 { + // Find and include the comma after this element + text := sourceFile.Text() + pos := end + // Skip whitespace to find the comma + for pos < len(text) && (text[pos] == ' ' || text[pos] == '\t' || text[pos] == '\n' || text[pos] == '\r') { + pos++ + } + if pos < len(text) && text[pos] == ',' { + end = pos + 1 + // Also skip trailing whitespace after comma + for end < len(text) && (text[end] == ' ' || text[end] == '\t') { + end++ + } + } + } else if nodeIndex > 0 { + // This is the last element - include the comma before it + text := sourceFile.Text() + pos := start - 1 + // Skip whitespace backwards to find the comma + for pos >= 0 && (text[pos] == ' ' || text[pos] == '\t' || text[pos] == '\n' || text[pos] == '\r') { + pos-- + } + if pos >= 0 && text[pos] == ',' { + start = pos + } + } + + // Convert text positions to LSP positions + startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, start) + endLine, endChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, end) + + changes.ReplaceRangeWithText(sourceFile, lsproto.Range{ + Start: lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, + End: lsproto.Position{Line: uint32(endLine), Character: uint32(endChar)}, + }, "") +} From b240edbbdb2267214d87b6535a7ec56bbc425115 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 20:30:59 -0800 Subject: [PATCH 07/48] Fix crash --- internal/ls/codeactions_importfixes.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 06ae606e62..f7e66486c3 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -357,10 +357,15 @@ func getExportInfos( // Get unique ID for the exported symbol symbolID := ast.GetSymbolId(exportedSymbol) + moduleFileName := "" + if toFile != nil { + moduleFileName = toFile.FileName() + } + originalSymbolToExportInfos.Add(symbolID, &SymbolExportInfo{ symbol: exportedSymbol, moduleSymbol: moduleSymbol, - moduleFileName: core.IfElse(toFile != nil, toFile.FileName(), ""), + moduleFileName: moduleFileName, exportKind: exportKind, targetFlags: ch.SkipAlias(exportedSymbol).Flags, isFromPackageJson: isFromPackageJson, From 04613145e7fa17371baa666fa92b349562860272 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 20:40:29 -0800 Subject: [PATCH 08/48] Skip some fourslash tests --- internal/fourslash/fourslash.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index 07dcb21a7a..269ff3d63f 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -147,6 +147,23 @@ func NewFourslash(t *testing.T, capabilities *lsproto.ClientCapabilities, conten } harnessutil.SetCompilerOptionsFromTestConfig(t, testData.GlobalOptions, compilerOptions, rootDir) + // Skip tests with deprecated/removed compiler options + if compilerOptions.BaseUrl != "" { + t.Skipf("Test uses deprecated 'baseUrl' option") + } + if compilerOptions.OutFile != "" { + t.Skipf("Test uses deprecated 'outFile' option") + } + if compilerOptions.Module == core.ModuleKindAMD { + t.Skipf("Test uses deprecated 'module: AMD' option") + } + if compilerOptions.Module == core.ModuleKindSystem { + t.Skipf("Test uses deprecated 'module: System' option") + } + if compilerOptions.Module == core.ModuleKindUMD { + t.Skipf("Test uses deprecated 'module: UMD' option") + } + inputReader, inputWriter := newLSPPipe() outputReader, outputWriter := newLSPPipe() fs := bundled.WrapFS(vfstest.FromMap(testfs, true /*useCaseSensitiveFileNames*/)) From 09a03e83c736dae158af4d1db7eca4a518ae01a2 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 20:51:34 -0800 Subject: [PATCH 09/48] Fix more --- internal/ls/codeactions_importfixes.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index f7e66486c3..982abf2e61 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -387,7 +387,10 @@ func getExportInfos( // Check default export defaultInfo := getDefaultLikeExportInfo(moduleSymbol, checker) if defaultInfo != nil { - if symbolFlagsHaveMeaning(defaultInfo.exportingModuleSymbol.Flags, currentTokenMeaning) { + // Resolve alias to get the actual symbol flags + resolvedSymbol := checker.SkipAlias(defaultInfo.exportingModuleSymbol) + resolvedFlags := resolvedSymbol.Flags + if symbolFlagsHaveMeaning(resolvedFlags, currentTokenMeaning) { // For JSX tags, we need to check if the capitalized name matches scriptTarget := compilerOptions.GetEmitScriptTarget() matchesName := forEachNameOfDefaultExport(defaultInfo.exportingModuleSymbol, checker, scriptTarget, func(name, capitalizedName string) string { From 4415f672a636ead60ffdab970774a80e7b5856fe Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 20:53:44 -0800 Subject: [PATCH 10/48] Fix more --- internal/fourslash/fourslash.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index 269ff3d63f..65f81d1423 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -163,6 +163,9 @@ func NewFourslash(t *testing.T, capabilities *lsproto.ClientCapabilities, conten if compilerOptions.Module == core.ModuleKindUMD { t.Skipf("Test uses deprecated 'module: UMD' option") } + if compilerOptions.ModuleResolution == core.ModuleResolutionKindClassic { + t.Skipf("Test uses deprecated 'moduleResolution: Classic' option") + } inputReader, inputWriter := newLSPPipe() outputReader, outputWriter := newLSPPipe() From 04fd6f827fa16474fb13031173a4573fc35ec777 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 21:08:59 -0800 Subject: [PATCH 11/48] Fix more --- internal/checker/exports.go | 4 +++ internal/ls/codeactions_importfixes.go | 38 ++++++++++---------------- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/internal/checker/exports.go b/internal/checker/exports.go index 9fd8b979ab..da6d28979a 100644 --- a/internal/checker/exports.go +++ b/internal/checker/exports.go @@ -178,3 +178,7 @@ func (c *Checker) GetJsxNamespace(location *ast.Node) string { func (c *Checker) ResolveName(name string, location *ast.Node, meaning ast.SymbolFlags, excludeGlobals bool) *ast.Symbol { return c.resolveName(location, name, meaning, nil, true, excludeGlobals) } + +func (c *Checker) GetSymbolFlags(symbol *ast.Symbol) ast.SymbolFlags { + return c.getSymbolFlags(symbol) +} diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 982abf2e61..42d3bd0772 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -386,32 +386,22 @@ func getExportInfos( // Check default export defaultInfo := getDefaultLikeExportInfo(moduleSymbol, checker) - if defaultInfo != nil { - // Resolve alias to get the actual symbol flags - resolvedSymbol := checker.SkipAlias(defaultInfo.exportingModuleSymbol) - resolvedFlags := resolvedSymbol.Flags - if symbolFlagsHaveMeaning(resolvedFlags, currentTokenMeaning) { - // For JSX tags, we need to check if the capitalized name matches - scriptTarget := compilerOptions.GetEmitScriptTarget() - matchesName := forEachNameOfDefaultExport(defaultInfo.exportingModuleSymbol, checker, scriptTarget, func(name, capitalizedName string) string { - actualName := name - if isJsxTagName && capitalizedName != "" { - actualName = capitalizedName - } - if actualName == symbolName { - return actualName - } - return "" - }) - if matchesName != "" { - addSymbol(moduleSymbol, sourceFile, defaultInfo.exportingModuleSymbol, defaultInfo.exportKind, isFromPackageJson) + if defaultInfo != nil && + symbolFlagsHaveMeaning(checker.GetSymbolFlags(defaultInfo.exportingModuleSymbol), currentTokenMeaning) && + forEachNameOfDefaultExport(defaultInfo.exportingModuleSymbol, checker, compilerOptions.GetEmitScriptTarget(), func(name, capitalizedName string) string { + actualName := name + if isJsxTagName && capitalizedName != "" { + actualName = capitalizedName } - } - } - - // Check for named export with identical name + if actualName == symbolName { + return actualName + } + return "" + }) != "" { + addSymbol(moduleSymbol, sourceFile, defaultInfo.exportingModuleSymbol, defaultInfo.exportKind, isFromPackageJson) + } // Check for named export with identical name exportSymbol := checker.TryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol) - if exportSymbol != nil && symbolFlagsHaveMeaning(exportSymbol.Flags, currentTokenMeaning) { + if exportSymbol != nil && symbolFlagsHaveMeaning(checker.GetSymbolFlags(exportSymbol), currentTokenMeaning) { addSymbol(moduleSymbol, sourceFile, exportSymbol, ExportKindNamed, isFromPackageJson) } }, From 8b4438b1b7ba56b221a3edbfed0106621b0d8b4f Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 21:20:48 -0800 Subject: [PATCH 12/48] Silence some failing --- internal/fourslash/_scripts/failingTests.txt | 121 +++++++++++------- .../gen/autoImportNodeNextJSRequire_test.go | 2 +- .../autoImportSortCaseSensitivity1_test.go | 2 +- .../tests/gen/autoImportTypeImport1_test.go | 2 +- .../tests/gen/autoImportTypeImport2_test.go | 2 +- .../tests/gen/autoImportTypeImport3_test.go | 2 +- .../tests/gen/autoImportTypeImport4_test.go | 2 +- .../gen/autoImportTypeOnlyPreferred2_test.go | 2 +- .../importNameCodeFixExistingImport10_test.go | 2 +- .../importNameCodeFixExistingImport11_test.go | 2 +- .../importNameCodeFixExistingImport2_test.go | 2 +- .../importNameCodeFixExistingImport3_test.go | 2 +- .../importNameCodeFixExistingImport8_test.go | 2 +- .../importNameCodeFixExistingImport9_test.go | 2 +- ...rtNameCodeFixExistingImportEquals0_test.go | 2 +- ...mportNameCodeFixIndentedIdentifier_test.go | 2 +- ...importNameCodeFixNewImportAmbient1_test.go | 2 +- ...importNameCodeFixNewImportAmbient3_test.go | 2 +- ...mportExportEqualsCommonJSInteropOn_test.go | 2 +- ...ameCodeFixNewImportFileQuoteStyle0_test.go | 2 +- ...ameCodeFixNewImportFileQuoteStyle1_test.go | 2 +- ...ameCodeFixNewImportFileQuoteStyle2_test.go | 2 +- ...deFixNewImportFileQuoteStyleMixed0_test.go | 2 +- ...deFixNewImportFileQuoteStyleMixed1_test.go | 2 +- .../importNameCodeFixUMDGlobalReact1_test.go | 2 +- .../importNameCodeFix_HeaderComment1_test.go | 2 +- .../importNameCodeFix_HeaderComment2_test.go | 2 +- ...eCodeFix_fileWithNoTrailingNewline_test.go | 2 +- .../gen/importNameCodeFix_importType1_test.go | 2 +- .../gen/importNameCodeFix_importType2_test.go | 2 +- .../gen/importNameCodeFix_importType7_test.go | 2 +- .../gen/importNameCodeFix_jsCJSvsESM3_test.go | 2 +- .../gen/importNameCodeFix_order2_test.go | 2 +- .../tests/gen/importNameCodeFix_order_test.go | 2 +- .../importNameCodeFix_trailingComma_test.go | 2 +- .../gen/importNameCodeFix_withJson_test.go | 2 +- 36 files changed, 113 insertions(+), 78 deletions(-) diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt index 4152b6c5f7..7a2d079a5e 100644 --- a/internal/fourslash/_scripts/failingTests.txt +++ b/internal/fourslash/_scripts/failingTests.txt @@ -10,6 +10,7 @@ TestAutoImportCompletionExportListAugmentation2 TestAutoImportCompletionExportListAugmentation3 TestAutoImportCompletionExportListAugmentation4 TestAutoImportFileExcludePatterns3 +TestAutoImportNodeNextJSRequire TestAutoImportPathsAliasesAndBarrels TestAutoImportProvider_exportMap1 TestAutoImportProvider_exportMap2 @@ -25,6 +26,12 @@ TestAutoImportProvider_namespaceSameNameAsIntrinsic TestAutoImportProvider_wildcardExports1 TestAutoImportProvider_wildcardExports2 TestAutoImportProvider_wildcardExports3 +TestAutoImportSortCaseSensitivity1 +TestAutoImportTypeImport1 +TestAutoImportTypeImport2 +TestAutoImportTypeImport3 +TestAutoImportTypeImport4 +TestAutoImportTypeOnlyPreferred2 TestAutoImportVerbatimTypeOnly1 TestBestCommonTypeObjectLiterals TestBestCommonTypeObjectLiterals1 @@ -45,6 +52,16 @@ TestCompletionForComputedStringProperties TestCompletionForMetaProperty TestCompletionForObjectProperty TestCompletionForStringLiteral +TestCompletionForStringLiteral_details +TestCompletionForStringLiteral_quotePreference +TestCompletionForStringLiteral_quotePreference1 +TestCompletionForStringLiteral_quotePreference2 +TestCompletionForStringLiteral_quotePreference3 +TestCompletionForStringLiteral_quotePreference4 +TestCompletionForStringLiteral_quotePreference5 +TestCompletionForStringLiteral_quotePreference6 +TestCompletionForStringLiteral_quotePreference7 +TestCompletionForStringLiteral_quotePreference8 TestCompletionForStringLiteral4 TestCompletionForStringLiteralExport TestCompletionForStringLiteralImport1 @@ -67,16 +84,6 @@ TestCompletionForStringLiteralRelativeImport4 TestCompletionForStringLiteralRelativeImport6 TestCompletionForStringLiteralRelativeImportAllowJSTrue TestCompletionForStringLiteralWithDynamicImport -TestCompletionForStringLiteral_details -TestCompletionForStringLiteral_quotePreference -TestCompletionForStringLiteral_quotePreference1 -TestCompletionForStringLiteral_quotePreference2 -TestCompletionForStringLiteral_quotePreference3 -TestCompletionForStringLiteral_quotePreference4 -TestCompletionForStringLiteral_quotePreference5 -TestCompletionForStringLiteral_quotePreference6 -TestCompletionForStringLiteral_quotePreference7 -TestCompletionForStringLiteral_quotePreference8 TestCompletionImportMeta TestCompletionImportMetaWithGlobalDeclaration TestCompletionImportModuleSpecifierEndingDts @@ -114,16 +121,16 @@ TestCompletionListInUnclosedTaggedTemplate02 TestCompletionListInUnclosedTemplate01 TestCompletionListInUnclosedTemplate02 TestCompletionListInvalidMemberNames -TestCompletionListInvalidMemberNames2 TestCompletionListInvalidMemberNames_escapeQuote TestCompletionListInvalidMemberNames_startWithSpace TestCompletionListInvalidMemberNames_withExistingIdentifier +TestCompletionListInvalidMemberNames2 TestCompletionListOfGenericSymbol TestCompletionListOnAliases +TestCompletionListsStringLiteralTypeAsIndexedAccessTypeObject TestCompletionListStringParenthesizedExpression TestCompletionListStringParenthesizedType TestCompletionListWithoutVariableinitializer -TestCompletionListsStringLiteralTypeAsIndexedAccessTypeObject TestCompletionNoAutoInsertQuestionDotForThis TestCompletionNoAutoInsertQuestionDotForTypeParameter TestCompletionNoAutoInsertQuestionDotWithUserPreferencesOff @@ -135,7 +142,6 @@ TestCompletionOfAwaitPromise6 TestCompletionOfAwaitPromise7 TestCompletionOfInterfaceAndVar TestCompletionPreferredSuggestions1 -TestCompletionWithConditionalOperatorMissingColon TestCompletionsAfterJSDoc TestCompletionsBeforeRestArg1 TestCompletionsClassMemberImportTypeNodeParameter1 @@ -145,7 +151,6 @@ TestCompletionsClassMemberImportTypeNodeParameter4 TestCompletionsElementAccessNumeric TestCompletionsExportImport TestCompletionsGenericTypeWithMultipleBases1 -TestCompletionsImportOrExportSpecifier TestCompletionsImport_default_alreadyExistedWithRename TestCompletionsImport_default_anonymous TestCompletionsImport_default_symbolName @@ -167,14 +172,15 @@ TestCompletionsImport_named_namespaceImportExists TestCompletionsImport_noSemicolons TestCompletionsImport_packageJsonImportsPreference TestCompletionsImport_quoteStyle -TestCompletionsImport_reExportDefault2 TestCompletionsImport_reExport_wrongName +TestCompletionsImport_reExportDefault2 TestCompletionsImport_require_addToExisting TestCompletionsImport_typeOnly TestCompletionsImport_umdDefaultNoCrash1 TestCompletionsImport_uriStyleNodeCoreModules2 TestCompletionsImport_weirdDefaultSynthesis TestCompletionsImport_windowsPathsProjectRelative +TestCompletionsImportOrExportSpecifier TestCompletionsInExport TestCompletionsInExport_moduleBlock TestCompletionsInRequire @@ -199,13 +205,13 @@ TestCompletionsOverridingMethod4 TestCompletionsOverridingMethod9 TestCompletionsOverridingMethodCrash1 TestCompletionsOverridingProperties1 -TestCompletionsPathsJsonModule -TestCompletionsPathsRelativeJsonModule TestCompletionsPaths_importType TestCompletionsPaths_kinds TestCompletionsPaths_pathMapping TestCompletionsPaths_pathMapping_nonTrailingWildcard1 TestCompletionsPaths_pathMapping_parentDirectory +TestCompletionsPathsJsonModule +TestCompletionsPathsRelativeJsonModule TestCompletionsRecommended_namespace TestCompletionsRecommended_union TestCompletionsRedeclareModuleAsGlobal @@ -213,9 +219,10 @@ TestCompletionsStringsWithTriggerCharacter TestCompletionsSymbolMembers TestCompletionsTriggerCharacter TestCompletionsTuple -TestCompletionsUniqueSymbol1 TestCompletionsUniqueSymbol_import +TestCompletionsUniqueSymbol1 TestCompletionsWithDeprecatedTag10 +TestCompletionWithConditionalOperatorMissingColon TestConstEnumQuickInfoAndCompletionList TestConstQuickInfoAndCompletionList TestContextuallyTypedFunctionExpressionGeneric1 @@ -226,8 +233,8 @@ TestExportDefaultFunction TestFindAllRefsModuleDotExports TestFindReferencesBindingPatternInJsdocNoCrash1 TestFindReferencesBindingPatternInJsdocNoCrash2 -TestGenericCombinatorWithConstraints1 TestGenericCombinators3 +TestGenericCombinatorWithConstraints1 TestGenericFunctionWithGenericParams1 TestGenericInterfacesWithConstraints1 TestGenericTypeWithMultipleBases1MultiFile @@ -251,25 +258,53 @@ TestGetJavaScriptQuickInfo8 TestGetJavaScriptSyntacticDiagnostics24 TestGetOccurrencesIfElseBroken TestHoverOverComment +TestImportCompletions_importsMap1 +TestImportCompletions_importsMap2 +TestImportCompletions_importsMap3 +TestImportCompletions_importsMap4 +TestImportCompletions_importsMap5 TestImportCompletionsPackageJsonExportsSpecifierEndsInTs TestImportCompletionsPackageJsonExportsTrailingSlash1 +TestImportCompletionsPackageJsonImports_ts TestImportCompletionsPackageJsonImportsConditions1 TestImportCompletionsPackageJsonImportsLength1 TestImportCompletionsPackageJsonImportsLength2 TestImportCompletionsPackageJsonImportsPattern -TestImportCompletionsPackageJsonImportsPattern2 TestImportCompletionsPackageJsonImportsPattern_capsInPath1 TestImportCompletionsPackageJsonImportsPattern_capsInPath2 TestImportCompletionsPackageJsonImportsPattern_js_ts TestImportCompletionsPackageJsonImportsPattern_ts TestImportCompletionsPackageJsonImportsPattern_ts_ts -TestImportCompletionsPackageJsonImports_ts -TestImportCompletions_importsMap1 -TestImportCompletions_importsMap2 -TestImportCompletions_importsMap3 -TestImportCompletions_importsMap4 -TestImportCompletions_importsMap5 +TestImportCompletionsPackageJsonImportsPattern2 +TestImportNameCodeFix_fileWithNoTrailingNewline +TestImportNameCodeFix_HeaderComment1 +TestImportNameCodeFix_HeaderComment2 +TestImportNameCodeFix_importType1 +TestImportNameCodeFix_importType2 +TestImportNameCodeFix_importType7 +TestImportNameCodeFix_jsCJSvsESM3 +TestImportNameCodeFix_order +TestImportNameCodeFix_order2 +TestImportNameCodeFix_trailingComma +TestImportNameCodeFix_withJson +TestImportNameCodeFixExistingImport10 +TestImportNameCodeFixExistingImport11 +TestImportNameCodeFixExistingImport2 +TestImportNameCodeFixExistingImport3 +TestImportNameCodeFixExistingImport8 +TestImportNameCodeFixExistingImport9 +TestImportNameCodeFixExistingImportEquals0 TestImportNameCodeFixExportAsDefault +TestImportNameCodeFixIndentedIdentifier +TestImportNameCodeFixNewImportAmbient1 +TestImportNameCodeFixNewImportAmbient3 +TestImportNameCodeFixNewImportExportEqualsCommonJSInteropOn +TestImportNameCodeFixNewImportFileQuoteStyle0 +TestImportNameCodeFixNewImportFileQuoteStyle1 +TestImportNameCodeFixNewImportFileQuoteStyle2 +TestImportNameCodeFixNewImportFileQuoteStyleMixed0 +TestImportNameCodeFixNewImportFileQuoteStyleMixed1 +TestImportNameCodeFixUMDGlobalReact1 TestImportTypeCompletions1 TestImportTypeCompletions3 TestImportTypeCompletions4 @@ -285,6 +320,7 @@ TestJavascriptModules20 TestJavascriptModules21 TestJavascriptModulesTypeImport TestJsDocAugments +TestJsdocCallbackTag TestJsDocExtends TestJsDocFunctionSignatures10 TestJsDocFunctionSignatures11 @@ -294,6 +330,9 @@ TestJsDocFunctionSignatures7 TestJsDocFunctionSignatures8 TestJsDocGenerics2 TestJsDocInheritDoc +TestJsdocLink2 +TestJsdocLink3 +TestJsdocLink6 TestJsDocPropertyDescription1 TestJsDocPropertyDescription10 TestJsDocPropertyDescription11 @@ -308,19 +347,15 @@ TestJsDocPropertyDescription8 TestJsDocPropertyDescription9 TestJsDocServices TestJsDocTagsWithHyphen -TestJsFileImportNoTypes2 -TestJsQuickInfoGenerallyAcceptableSize -TestJsRequireQuickInfo -TestJsdocCallbackTag -TestJsdocLink2 -TestJsdocLink3 -TestJsdocLink6 TestJsdocTemplatePrototypeCompletions TestJsdocThrowsTagCompletion TestJsdocTypedefTag TestJsdocTypedefTag2 TestJsdocTypedefTagNamespace TestJsdocTypedefTagServices +TestJsFileImportNoTypes2 +TestJsQuickInfoGenerallyAcceptableSize +TestJsRequireQuickInfo TestLetQuickInfoAndCompletionList TestLocalFunction TestMemberListInReopenedEnum @@ -328,9 +363,9 @@ TestMemberListInWithBlock TestMemberListOfExportedClass TestMemberListOnContextualThis TestNgProxy1 +TestNodeModulesImportCompletions1 TestNoQuickInfoForLabel TestNoQuickInfoInWhitespace -TestNodeModulesImportCompletions1 TestNumericPropertyNames TestOverloadQuickInfo TestParameterWithDestructuring @@ -384,12 +419,14 @@ TestPathCompletionsTypesVersionsWildcard4 TestPathCompletionsTypesVersionsWildcard5 TestPathCompletionsTypesVersionsWildcard6 TestProtoVarVisibleWithOuterScopeUnderscoreProto +TestQuickInfo_notInsideComment +TestQuickinfo01 TestQuickInfoAlias TestQuickInfoAssertionNodeNotReusedWhenTypeNotEquivalent1 TestQuickInfoBindingPatternInJsdocNoCrash1 TestQuickInfoClassKeyword -TestQuickInfoContextualTyping TestQuickInfoContextuallyTypedSignatureOptionalParameterFromIntersection1 +TestQuickInfoContextualTyping TestQuickInfoDisplayPartsIife TestQuickInfoElementAccessDeclaration TestQuickInfoForConstTypeReference @@ -402,13 +439,15 @@ TestQuickInfoForGenericTaggedTemplateExpression TestQuickInfoForGetterAndSetter TestQuickInfoForIndexerResultWithConstraint TestQuickInfoForNamedTupleMember +TestQuickinfoForNamespaceMergeWithClassConstrainedToSelf TestQuickInfoForObjectBindingElementPropertyName04 TestQuickInfoForShorthandProperty TestQuickInfoForSyntaxErrorNoError +TestQuickInfoForTypeofParameter TestQuickInfoForTypeParameterInTypeAlias1 TestQuickInfoForTypeParameterInTypeAlias2 -TestQuickInfoForTypeofParameter TestQuickInfoForUMDModuleAlias +TestQuickinfoForUnionProperty TestQuickInfoFromContextualType TestQuickInfoFunctionKeyword TestQuickInfoGenerics @@ -420,10 +459,10 @@ TestQuickInfoInWithBlock TestQuickInfoJSDocBackticks TestQuickInfoJSDocFunctionNew TestQuickInfoJSDocFunctionThis -TestQuickInfoJSExport TestQuickInfoJsDocGetterSetterNoCrash1 TestQuickInfoJsDocNonDiscriminatedUnionSharedProp TestQuickInfoJsdocTypedefMissingType +TestQuickInfoJSExport TestQuickInfoMappedSpreadTypes TestQuickInfoMappedType TestQuickInfoMappedTypeMethods @@ -468,6 +507,7 @@ TestQuickInfoOnUndefined TestQuickInfoOnVarInArrowExpression TestQuickInfoPrivateIdentifierInTypeReferenceNoCrash1 TestQuickInfoPropertyTag +TestQuickInforForSucessiveInferencesIsNotAny TestQuickInfoSignatureOptionalParameterFromUnion1 TestQuickInfoSignatureRestParameterFromUnion1 TestQuickInfoSignatureRestParameterFromUnion2 @@ -480,14 +520,9 @@ TestQuickInfoTypeAliasDefinedInDifferentFile TestQuickInfoTypeError TestQuickInfoTypeOfThisInStatics TestQuickInfoTypeOnlyNamespaceAndClass -TestQuickInfoUnionOfNamespaces TestQuickInfoUnion_discriminated +TestQuickInfoUnionOfNamespaces TestQuickInfoWidenedTypes -TestQuickInfo_notInsideComment -TestQuickInforForSucessiveInferencesIsNotAny -TestQuickinfo01 -TestQuickinfoForNamespaceMergeWithClassConstrainedToSelf -TestQuickinfoForUnionProperty TestQuickinfoWrongComment TestRecursiveInternalModuleImport TestReferencesForStatementKeywords diff --git a/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go b/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go index 823a6add81..0afe25bc07 100644 --- a/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go +++ b/internal/fourslash/tests/gen/autoImportNodeNextJSRequire_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportNodeNextJSRequire(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: node18 // @allowJs: true diff --git a/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go b/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go index 3c2e74a682..020cfb9d4e 100644 --- a/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go +++ b/internal/fourslash/tests/gen/autoImportSortCaseSensitivity1_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportSortCaseSensitivity1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /exports1.ts export const a = 0; diff --git a/internal/fourslash/tests/gen/autoImportTypeImport1_test.go b/internal/fourslash/tests/gen/autoImportTypeImport1_test.go index e9da922dd9..7fc9f0a982 100644 --- a/internal/fourslash/tests/gen/autoImportTypeImport1_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeImport1_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeImport1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/autoImportTypeImport2_test.go b/internal/fourslash/tests/gen/autoImportTypeImport2_test.go index 571315406c..202dfc0dd1 100644 --- a/internal/fourslash/tests/gen/autoImportTypeImport2_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeImport2_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeImport2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/autoImportTypeImport3_test.go b/internal/fourslash/tests/gen/autoImportTypeImport3_test.go index 67432c61fd..20dd8d97fd 100644 --- a/internal/fourslash/tests/gen/autoImportTypeImport3_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeImport3_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeImport3(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/autoImportTypeImport4_test.go b/internal/fourslash/tests/gen/autoImportTypeImport4_test.go index 33ccd2d46d..ae19d60f17 100644 --- a/internal/fourslash/tests/gen/autoImportTypeImport4_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeImport4_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeImport4(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go b/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go index 857cd76d56..c79ec30ad6 100644 --- a/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go +++ b/internal/fourslash/tests/gen/autoImportTypeOnlyPreferred2_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportTypeOnlyPreferred2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /node_modules/react/index.d.ts export interface ComponentType {} diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go index b42825386b..836756a4f6 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport10_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport10(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import [|{ v1, diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go index dfb88bffd3..da6b393b5b 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport11_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport11(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import [|{ v1, v2, diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport2_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport2_test.go index 0602242203..ed6204784c 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import * as ns from "./module"; // Comment diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport3_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport3_test.go index 041f86f0e2..3d97848208 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport3_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport3_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport3(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import d, * as ns from "./module" ; f1/*0*/();|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go index 4daee97cc0..0ae3edc2e4 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport8_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport8(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import [|{v1, v2, v3,}|] from "./module"; v4/*0*/(); diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go index cde3b9619e..71964dca5f 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport9_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport9(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import [|{ v1 diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go index 99c363b38e..0cf8875bb5 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImportEquals0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImportEquals0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import ns = require("ambient-module"); var x = v1/*0*/ + 5;|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixIndentedIdentifier_test.go b/internal/fourslash/tests/gen/importNameCodeFixIndentedIdentifier_test.go index b5c0e91aec..5785b37c45 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixIndentedIdentifier_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixIndentedIdentifier_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixIndentedIdentifier(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts [|import * as b from "./b"; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go index 3e8b1ed313..22892b732c 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAmbient1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import d from "other-ambient-module"; import * as ns from "yet-another-ambient-module"; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go index edf25cbed7..d20e88242d 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportAmbient3_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportAmbient3(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `let a = "I am a non-trivial statement that appears before imports"; import d from "other-ambient-module" diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsCommonJSInteropOn_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsCommonJSInteropOn_test.go index b058fb5b34..2fa4d4c865 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsCommonJSInteropOn_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsCommonJSInteropOn_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportExportEqualsCommonJSInteropOn(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Module: commonjs // @EsModuleInterop: true diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go index a8d873a59c..40922da0e1 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyle0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import { v2 } from './module2'; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go index 242da68c11..04cdc80d4b 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyle1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import { v2 } from "./module2"; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go index 7f071b8907..464fae8baa 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyle2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyle2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import m2 = require('./module2'); diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go index f46ecf26da..5be114b185 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyleMixed0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import { v2 } from "./module2"; import { v3 } from './module3'; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go index 6ca53ac621..ea402be77d 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFileQuoteStyleMixed1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFileQuoteStyleMixed1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import { v2 } from './module2'; import { v3 } from "./module3"; diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go index a4772340ee..29d083e101 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixUMDGlobalReact1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @jsx: react // @allowSyntheticDefaultImports: false diff --git a/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go index 57d7645b43..7bc55cb9ae 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_HeaderComment1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const foo = 0; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go index 8c159de368..36b33f05fe 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_HeaderComment2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_HeaderComment2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const foo = 0; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go b/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go index 23586e5527..819c94f71c 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_fileWithNoTrailingNewline_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_fileWithNoTrailingNewline(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const foo = 0; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go index 195caa8c72..058e1a75f8 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @module: es2015 diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go index e1e2c7cd19..1a09b188c4 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @module: es2015 diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go index 6c13fc69e0..3f5d77e92a 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType7_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType7(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: es2015 // @Filename: /exports.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM3_test.go b/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM3_test.go index 7006d6b90a..99ab3b76b6 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM3_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM3_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_jsCJSvsESM3(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @allowJs: true // @checkJs: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go b/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go index 0f1ec18977..ff7d259f51 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_order2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_order2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const _aB: number; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_order_test.go b/internal/fourslash/tests/gen/importNameCodeFix_order_test.go index ea6b469266..e24829a31b 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_order_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_order_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_order(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const foo: number; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go b/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go index 20f332b4bd..07f720b6e5 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_trailingComma_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_trailingComma(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: index.ts import { diff --git a/internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go b/internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go index 5000eff555..3af50482e0 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_withJson_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_withJson(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export const a = 'a'; From 7aad58eaa975d3e00d0a7028476a7384b4582496 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 21:37:08 -0800 Subject: [PATCH 13/48] Fix more --- internal/ast/utilities.go | 12 ++++++++++++ internal/checker/checker.go | 4 ++-- internal/checker/utilities.go | 12 ------------ internal/ls/codeactions_importfixes.go | 6 +++--- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/internal/ast/utilities.go b/internal/ast/utilities.go index b1eb903d43..e064aafa8e 100644 --- a/internal/ast/utilities.go +++ b/internal/ast/utilities.go @@ -3930,3 +3930,15 @@ func GetFirstConstructorWithBody(node *Node) *Node { } return nil } + +func GetTagNameOfNode(node *Node) *Node { + switch node.Kind { + case KindJsxOpeningElement: + return node.AsJsxOpeningElement().TagName + case KindJsxClosingElement: + return node.AsJsxClosingElement().TagName + case KindJsxSelfClosingElement: + return node.AsJsxSelfClosingElement().TagName + } + panic("Unhandled case in GetTagNameOfNode") +} diff --git a/internal/checker/checker.go b/internal/checker/checker.go index 8cd1623765..465360d39b 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -2859,7 +2859,7 @@ func (c *Checker) getDeprecatedSuggestionNode(node *ast.Node) *ast.Node { case ast.KindTaggedTemplateExpression: return c.getDeprecatedSuggestionNode(node.AsTaggedTemplateExpression().Tag) case ast.KindJsxOpeningElement, ast.KindJsxSelfClosingElement: - return c.getDeprecatedSuggestionNode(getTagNameOfNode(node)) + return c.getDeprecatedSuggestionNode(ast.GetTagNameOfNode(node)) case ast.KindElementAccessExpression: return node.AsElementAccessExpression().ArgumentExpression case ast.KindPropertyAccessExpression: @@ -30351,7 +30351,7 @@ func (c *Checker) hasContextualTypeWithNoGenericTypes(node *ast.Node, checkMode // If check mode has `CheckMode.RestBindingElement`, we skip binding pattern contextual types, // as we want the type of a rest element to be generic when possible. if (ast.IsIdentifier(node) || ast.IsPropertyAccessExpression(node) || ast.IsElementAccessExpression(node)) && - !((ast.IsJsxOpeningElement(node.Parent) || ast.IsJsxSelfClosingElement(node.Parent)) && getTagNameOfNode(node.Parent) == node) { + !((ast.IsJsxOpeningElement(node.Parent) || ast.IsJsxSelfClosingElement(node.Parent)) && ast.GetTagNameOfNode(node.Parent) == node) { contextualType := c.getContextualType(node, core.IfElse(checkMode&CheckModeRestBindingElement != 0, ContextFlagsSkipBindingPatterns, ContextFlagsNone)) if contextualType != nil { return !c.isGenericType(contextualType) diff --git a/internal/checker/utilities.go b/internal/checker/utilities.go index 617e2f80b7..087a3e211a 100644 --- a/internal/checker/utilities.go +++ b/internal/checker/utilities.go @@ -1097,18 +1097,6 @@ func isNonNullAccess(node *ast.Node) bool { return ast.IsAccessExpression(node) && ast.IsNonNullExpression(node.Expression()) } -func getTagNameOfNode(node *ast.Node) *ast.Node { - switch node.Kind { - case ast.KindJsxOpeningElement: - return node.AsJsxOpeningElement().TagName - case ast.KindJsxClosingElement: - return node.AsJsxClosingElement().TagName - case ast.KindJsxSelfClosingElement: - return node.AsJsxSelfClosingElement().TagName - } - panic("Unhandled case in getTagNameOfNode") -} - func getBindingElementPropertyName(node *ast.Node) *ast.Node { name := node.AsBindingElement().PropertyName if name != nil { diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 42d3bd0772..ecc2a209c9 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -292,7 +292,7 @@ func getTypeOnlyPromotionFix(ctx context.Context, sourceFile *ast.SourceFile, sy func getSymbolNamesToImport(sourceFile *ast.SourceFile, ch *checker.Checker, symbolToken *ast.Node, compilerOptions *core.CompilerOptions) []string { parent := symbolToken.Parent if (ast.IsJsxOpeningLikeElement(parent) || ast.IsJsxClosingElement(parent)) && - parent.AsJsxOpeningElement().TagName == symbolToken && + ast.GetTagNameOfNode(parent) == symbolToken && jsxModeNeedsExplicitImport(compilerOptions.Jsx) { jsxNamespace := ch.GetJsxNamespace(sourceFile.AsNode()) if needsJsxNamespaceFix(jsxNamespace, symbolToken, ch) { @@ -685,8 +685,8 @@ func isJSXTagName(node *ast.Node) bool { if parent == nil { return false } - if ast.IsJsxOpeningElement(parent) || ast.IsJsxClosingElement(parent) { - return parent.AsJsxOpeningElement().TagName == node + if ast.IsJsxOpeningLikeElement(parent) || ast.IsJsxClosingElement(parent) { + return ast.GetTagNameOfNode(parent) == node } return false } From f05de71636b01668d527a573524cd21aa8652ec0 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 21:39:54 -0800 Subject: [PATCH 14/48] fix again --- internal/ls/codeactions_importfixes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index ecc2a209c9..13fe86b75e 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -184,7 +184,7 @@ func getUmdSymbol(token *ast.Node, ch *checker.Checker) *ast.Symbol { // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`. parent := token.Parent - if (ast.IsJsxOpeningLikeElement(parent) && parent.AsJsxOpeningElement().TagName == token) || + if (ast.IsJsxOpeningLikeElement(parent) && ast.GetTagNameOfNode(parent) == token) || ast.IsJsxOpeningFragment(parent) { var location *ast.Node if ast.IsJsxOpeningLikeElement(parent) { From 4c75fb148f75a3c7e79462c938c549f91088b92d Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 21:44:54 -0800 Subject: [PATCH 15/48] fix another crash --- internal/ast/utilities.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/internal/ast/utilities.go b/internal/ast/utilities.go index e064aafa8e..8a09a01fb6 100644 --- a/internal/ast/utilities.go +++ b/internal/ast/utilities.go @@ -1414,9 +1414,17 @@ func GetNameOfDeclaration(declaration *Node) *Node { func GetImportClauseOfDeclaration(declaration *Declaration) *ImportClause { switch declaration.Kind { case KindImportDeclaration: - return declaration.AsImportDeclaration().ImportClause.AsImportClause() + importDecl := declaration.AsImportDeclaration() + if importDecl.ImportClause == nil { + return nil + } + return importDecl.ImportClause.AsImportClause() case KindJSDocImportTag: - return declaration.AsJSDocImportTag().ImportClause.AsImportClause() + jsDocImport := declaration.AsJSDocImportTag() + if jsDocImport.ImportClause == nil { + return nil + } + return jsDocImport.ImportClause.AsImportClause() } return nil } From 073d6accaeb8c0e93d1c44347f393d2f7ad8c291 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 21:47:47 -0800 Subject: [PATCH 16/48] Skip some more specifier tests --- internal/fourslash/_scripts/failingTests.txt | 13 +++++++++++++ .../gen/importNameCodeFixExistingImport5_test.go | 2 +- .../gen/importNameCodeFixNewImportBaseUrl0_test.go | 2 +- .../gen/importNameCodeFixNewImportBaseUrl1_test.go | 2 +- .../gen/importNameCodeFixNewImportBaseUrl2_test.go | 2 +- .../gen/importNameCodeFixNewImportFile2_test.go | 2 +- .../gen/importNameCodeFixNewImportRootDirs0_test.go | 2 +- .../importNameCodeFixNewImportTypeRoots1_test.go | 2 +- ...portNameCodeFix_avoidRelativeNodeModules_test.go | 2 +- .../tests/gen/importNameCodeFix_jsx1_test.go | 2 +- .../gen/importNameCodeFix_preferBaseUrl_test.go | 2 +- .../gen/importNameCodeFix_reExportDefault_test.go | 2 +- .../tests/gen/moduleNodeNextAutoImport2_test.go | 2 +- .../tests/gen/moduleNodeNextAutoImport3_test.go | 2 +- 14 files changed, 26 insertions(+), 13 deletions(-) diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt index 7a2d079a5e..33eb8f2605 100644 --- a/internal/fourslash/_scripts/failingTests.txt +++ b/internal/fourslash/_scripts/failingTests.txt @@ -558,3 +558,16 @@ TestTsxQuickInfo5 TestTsxQuickInfo6 TestTsxQuickInfo7 TestTypeOperatorNodeBuilding +TestImportNameCodeFix_jsx1 +TestImportNameCodeFix_reExportDefault +TestImportNameCodeFix_preferBaseUrl +TestImportNameCodeFixExistingImport5 +TestImportNameCodeFixNewImportBaseUrl1 +TestImportNameCodeFixNewImportBaseUrl0 +TestImportNameCodeFixNewImportBaseUrl2 +TestImportNameCodeFixNewImportFile2 +TestImportNameCodeFixNewImportTypeRoots1 +TestImportNameCodeFixNewImportRootDirs0 +TestImportNameCodeFix_avoidRelativeNodeModules +TestModuleNodeNextAutoImport2 +TestModuleNodeNextAutoImport3 diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go index 31610760a8..707bf1903b 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport5(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import "./module"; f1/*0*/();|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go index 526c1daebe..dd4b002813 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportBaseUrl0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|f1/*0*/();|] // @Filename: tsconfig.json diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go index 6053cd87f2..a3ce15ee9c 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportBaseUrl1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go index d08006e545..0796d349b6 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportBaseUrl2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportBaseUrl2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go index 1312e65b50..a1e91b616c 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportFile2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportFile2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|f1/*0*/();|] // @Filename: ../../other_dir/module.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go index 910ee7dbaa..c192ad7931 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportRootDirs0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportRootDirs0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: a/f1.ts [|foo/*0*/();|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go index f3baf33c4a..c92b250137 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportTypeRoots1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportTypeRoots1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: a/f1.ts [|foo/*0*/();|] diff --git a/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go b/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go index 92b14c6521..4b0885f69d 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_avoidRelativeNodeModules_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_avoidRelativeNodeModules(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a/index.d.ts // @Symlink: /b/node_modules/a/index.d.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go index 0f5ff35b9a..655a57f416 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_jsx1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_jsx1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @jsx: react // @Filename: /node_modules/react/index.d.ts diff --git a/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go b/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go index 7c66bd3dc6..06168a5bfc 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_preferBaseUrl_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_preferBaseUrl(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "baseUrl": "./src" } } diff --git a/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go b/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go index c5b775e568..8a99b77559 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_reExportDefault(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /user.ts foo; diff --git a/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go b/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go index 9c86a023e2..0803a88deb 100644 --- a/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go +++ b/internal/fourslash/tests/gen/moduleNodeNextAutoImport2_test.go @@ -9,7 +9,7 @@ import ( func TestModuleNodeNextAutoImport2(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "module": "nodenext" } } diff --git a/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go b/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go index 0f9ba1e8ef..79a3a1c638 100644 --- a/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go +++ b/internal/fourslash/tests/gen/moduleNodeNextAutoImport3_test.go @@ -9,7 +9,7 @@ import ( func TestModuleNodeNextAutoImport3(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "module": "nodenext" } } From e30e8528b20114075ced9bc0577025537d04781a Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 21:49:41 -0800 Subject: [PATCH 17/48] Skip more --- internal/fourslash/_scripts/failingTests.txt | 8 ++++++++ .../gen/autoImportCrossProject_symlinks_stripSrc_test.go | 2 +- .../gen/autoImportCrossProject_symlinks_toDist_test.go | 2 +- .../gen/autoImportCrossProject_symlinks_toSrc_test.go | 2 +- internal/fourslash/tests/gen/autoImportPnpm_test.go | 2 +- internal/fourslash/tests/gen/autoImportProvider4_test.go | 2 +- .../fourslash/tests/gen/autoImportProvider_pnpm_test.go | 2 +- .../tests/gen/autoImportSymlinkCaseSensitive_test.go | 2 +- .../tests/gen/importFixesGlobalTypingsCache_test.go | 2 +- 9 files changed, 16 insertions(+), 8 deletions(-) diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt index 33eb8f2605..8ecb6cf018 100644 --- a/internal/fourslash/_scripts/failingTests.txt +++ b/internal/fourslash/_scripts/failingTests.txt @@ -571,3 +571,11 @@ TestImportNameCodeFixNewImportRootDirs0 TestImportNameCodeFix_avoidRelativeNodeModules TestModuleNodeNextAutoImport2 TestModuleNodeNextAutoImport3 +TestAutoImportCrossProject_symlinks_toDist +TestAutoImportProvider_pnpm +TestAutoImportCrossProject_symlinks_stripSrc +TestAutoImportSymlinkCaseSensitive +TestAutoImportCrossProject_symlinks_toSrc +TestAutoImportProvider4 +TestAutoImportPnpm +TestImportFixesGlobalTypingsCache diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go index b7358d23e9..e369963053 100644 --- a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go +++ b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_stripSrc_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportCrossProject_symlinks_stripSrc(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json { "name": "app", "dependencies": { "dep": "*" } } diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go index d7be784d54..b577b3b28d 100644 --- a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go +++ b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toDist_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportCrossProject_symlinks_toDist(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json { "name": "app", "dependencies": { "dep": "*" } } diff --git a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go index 2da97bbd63..17ae9884b0 100644 --- a/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go +++ b/internal/fourslash/tests/gen/autoImportCrossProject_symlinks_toSrc_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportCrossProject_symlinks_toSrc(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json { "name": "app", "dependencies": { "dep": "*" } } diff --git a/internal/fourslash/tests/gen/autoImportPnpm_test.go b/internal/fourslash/tests/gen/autoImportPnpm_test.go index dac4cd2cc0..1f05b32afc 100644 --- a/internal/fourslash/tests/gen/autoImportPnpm_test.go +++ b/internal/fourslash/tests/gen/autoImportPnpm_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportPnpm(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "module": "commonjs" } } diff --git a/internal/fourslash/tests/gen/autoImportProvider4_test.go b/internal/fourslash/tests/gen/autoImportProvider4_test.go index ebb026c217..44dcb137e8 100644 --- a/internal/fourslash/tests/gen/autoImportProvider4_test.go +++ b/internal/fourslash/tests/gen/autoImportProvider4_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportProvider4(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/a/package.json { "dependencies": { "b": "*" } } diff --git a/internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go b/internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go index 9f7d4698f6..d2b4646c72 100644 --- a/internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go +++ b/internal/fourslash/tests/gen/autoImportProvider_pnpm_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportProvider_pnpm(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/tsconfig.json { "compilerOptions": { "module": "commonjs" } } diff --git a/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go b/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go index 3ff780778d..e8553396d2 100644 --- a/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go +++ b/internal/fourslash/tests/gen/autoImportSymlinkCaseSensitive_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportSymlinkCaseSensitive(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /tsconfig.json { "compilerOptions": { "module": "commonjs" } } diff --git a/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go b/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go index 20d5b30843..b0393b485a 100644 --- a/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go +++ b/internal/fourslash/tests/gen/importFixesGlobalTypingsCache_test.go @@ -9,7 +9,7 @@ import ( func TestImportFixesGlobalTypingsCache(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /project/tsconfig.json { "compilerOptions": { "allowJs": true, "checkJs": true } } From b2e526df636b8128e7592e111c7ed66ca01d21c8 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 21:58:12 -0800 Subject: [PATCH 18/48] Fix bad type removal --- internal/ls/codeactions_importfixes.go | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 13fe86b75e..693ae9b7bb 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -994,26 +994,33 @@ func promoteImportClause( // deleteTypeKeywordFromImportClause deletes the 'type' keyword from an import clause func deleteTypeKeywordFromImportClause(changes *change.Tracker, sourceFile *ast.SourceFile, importClause *ast.ImportClause) { - // The type keyword is at the start of the import clause + // The type keyword is the first token in the import clause // import type { foo } from "bar" // ^^^^^ - this keyword + // We need to find and delete "type " (including trailing space) - // Find the position of the 'type' keyword and the space after it - clauseStart := importClause.Pos() + // The import clause starts at the position of the "type" keyword + // Use the scanner to get the token at that position + scan := scanner.GetScannerForSourceFile(sourceFile, importClause.Pos()) + token := scan.Token() - // The 'type' keyword should be the first token in the import clause - // We want to delete "type " (including the trailing space) - typeKeywordEnd := clauseStart + 4 // length of "type" + if token != ast.KindTypeKeyword { + panic(fmt.Sprintf("Expected type keyword at import clause start, got %v at pos %d", token, importClause.Pos())) + } + + // Use TokenStart (not TokenFullStart) to avoid including leading whitespace + typeStart := scan.TokenStart() + typeEnd := scan.TokenEnd() - // Skip whitespace after 'type' to find the actual end position + // Skip whitespace after 'type' to include it in the deletion text := sourceFile.Text() - endPos := typeKeywordEnd + endPos := typeEnd for endPos < len(text) && (text[endPos] == ' ' || text[endPos] == '\t') { endPos++ } // Convert text positions to LSP positions - startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, clauseStart) + startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, typeStart) endLine, endChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, endPos) changes.ReplaceRangeWithText(sourceFile, lsproto.Range{ From fecddf8c27c4c0d6119fb427b71a4126566f9530 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 23:08:27 -0800 Subject: [PATCH 19/48] hm --- internal/ls/codeactions_importfixes.go | 69 +++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 693ae9b7bb..3820564cec 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -646,7 +646,7 @@ func codeActionForFixWorker( } // Insert the import statements - changes.InsertAtTopOfFile(sourceFile, statements, true) + insertImports(changes, sourceFile, statements, program, ls) // Add namespace qualification if needed if fix.qualification() != nil { @@ -1209,3 +1209,70 @@ func deleteNode(changes *change.Tracker, sourceFile *ast.SourceFile, node *ast.N End: lsproto.Position{Line: uint32(endLine), Character: uint32(endChar)}, }, "") } + +// insertImports inserts new import statements in the correct position relative to existing imports +// (from utilities.ts insertImports) +func insertImports( + changes *change.Tracker, + sourceFile *ast.SourceFile, + imports []*ast.Statement, + program *compiler.Program, + ls *LanguageService, +) { + if len(imports) == 0 { + return + } + + // Find existing import statements + var existingImportStatements []*ast.Statement + for _, stmt := range sourceFile.Statements.Nodes { + if ast.IsAnyImportSyntax(stmt) || ast.IsRequireVariableStatement(stmt) { + existingImportStatements = append(existingImportStatements, stmt) + } + } + + // If no existing imports, insert at top of file + if len(existingImportStatements) == 0 { + changes.InsertAtTopOfFile(sourceFile, imports, true /* blankLineBetween */) + return + } + + // Get comparer and check if imports are sorted + comparer, isSorted := organizeimports.GetOrganizeImportsStringComparerWithDetection( + existingImportStatements, + ls.UserPreferences(), + ) + + // Sort the new imports + sortedNewImports := make([]*ast.Statement, len(imports)) + copy(sortedNewImports, imports) + slices.SortFunc(sortedNewImports, func(a, b *ast.Statement) int { + return organizeimports.CompareImportsOrRequireStatements(a, b, comparer) + }) + + // If existing imports are sorted, insert each new import in the correct position + if isSorted { + for _, newImport := range sortedNewImports { + insertionIndex := organizeimports.GetImportDeclarationInsertIndex( + existingImportStatements, + newImport, + func(a, b *ast.Statement) int { + return organizeimports.CompareImportsOrRequireStatements(a, b, comparer) + }, + ) + + if insertionIndex == 0 { + // Insert before the first import + changes.InsertNodeBefore(sourceFile, existingImportStatements[0], newImport, false /* blankLineBetween */) + } else { + // Insert after the previous import + prevImport := existingImportStatements[insertionIndex-1] + changes.InsertNodeAfter(sourceFile, prevImport, newImport) + } + } + } else { + // Imports are not sorted, insert after the last existing import + lastImport := existingImportStatements[len(existingImportStatements)-1] + changes.InsertNodesAfter(sourceFile, lastImport, sortedNewImports) + } +} From 24f10160b7d27e1c2309f25adbb5e4180d347c0c Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 23:34:23 -0800 Subject: [PATCH 20/48] Work around --- internal/ls/autoimportfixes.go | 114 +++++++++++++++++++++++++-------- internal/ls/change/tracker.go | 6 +- 2 files changed, 91 insertions(+), 29 deletions(-) diff --git a/internal/ls/autoimportfixes.go b/internal/ls/autoimportfixes.go index 82a7ddaced..06fc5f07a8 100644 --- a/internal/ls/autoimportfixes.go +++ b/internal/ls/autoimportfixes.go @@ -10,6 +10,8 @@ import ( "github.com/microsoft/typescript-go/internal/ls/change" "github.com/microsoft/typescript-go/internal/ls/lsutil" "github.com/microsoft/typescript-go/internal/ls/organizeimports" + "github.com/microsoft/typescript-go/internal/lsp/lsproto" + "github.com/microsoft/typescript-go/internal/scanner" "github.com/microsoft/typescript-go/internal/stringutil" ) @@ -116,23 +118,33 @@ func (ls *LanguageService) doAddExistingFix( // ); // if len(existingSpecifiers) > 0 && isSorted != core.TSFalse { - // The sorting preference computed earlier may or may not have validated that these particular - // import specifiers are sorted. If they aren't, `getImportSpecifierInsertionIndex` will return - // nonsense. So if there are existing specifiers, even if we know the sorting preference, we - // need to ensure that the existing specifiers are sorted according to the preference in order - // to do a sorted insertion. - // if we're promoting the clause from type-only, we need to transform the existing imports before attempting to insert the new named imports - // transformedExistingSpecifiers := existingSpecifiers - // if promoteFromTypeOnly && existingSpecifiers { - // transformedExistingSpecifiers = ct.NodeFactory.updateNamedImports( - // importClause.NamedBindings.AsNamedImports(), - // core.SameMap(existingSpecifiers, func(e *ast.ImportSpecifier) *ast.ImportSpecifier { - // return ct.NodeFactory.updateImportSpecifier(e, /*isTypeOnly*/ true, e.propertyName, e.name) - // }), - // ).elements - // } + // The sorting preference computed earlier may or may not have validated that these particular + // import specifiers are sorted. If they aren't, `getImportSpecifierInsertionIndex` will return + // nonsense. So if there are existing specifiers, even if we know the sorting preference, we + // need to ensure that the existing specifiers are sorted according to the preference in order + // to do a sorted insertion. + + // If we're promoting the clause from type-only, we need to transform the existing imports + // before attempting to insert the new named imports (for comparison purposes only) + specsToCompareAgainst := existingSpecifiers + if promoteFromTypeOnly && len(existingSpecifiers) > 0 { + specsToCompareAgainst = core.Map(existingSpecifiers, func(e *ast.Node) *ast.Node { + spec := e.AsImportSpecifier() + var propertyName *ast.Node + if spec.PropertyName != nil { + propertyName = spec.PropertyName + } + syntheticSpec := ct.NodeFactory.NewImportSpecifier( + true, // isTypeOnly + propertyName, + spec.Name(), + ) + return syntheticSpec + }) + } + for _, spec := range newSpecifiers { - insertionIndex := organizeimports.GetImportSpecifierInsertionIndex(existingSpecifiers, spec, specifierComparer) + insertionIndex := organizeimports.GetImportSpecifierInsertionIndex(specsToCompareAgainst, spec, specifierComparer) ct.InsertImportSpecifierAtIndex(sourceFile, spec, importClause.NamedBindings, insertionIndex) } } else if len(existingSpecifiers) > 0 && isSorted.IsTrue() { @@ -168,18 +180,19 @@ func (ls *LanguageService) doAddExistingFix( } if promoteFromTypeOnly { - // !!! promote type-only imports not implemented - - // ct.delete(sourceFile, getTypeKeywordOfTypeOnlyImport(clause, sourceFile)); - // if (existingSpecifiers) { - // // We used to convert existing specifiers to type-only only if compiler options indicated that - // // would be meaningful (see the `importNameElisionDisabled` utility function), but user - // // feedback indicated a preference for preserving the type-onlyness of existing specifiers - // // regardless of whether it would make a difference in emit. - // for _, specifier := range existingSpecifiers { - // ct.insertModifierBefore(sourceFile, SyntaxKind.TypeKeyword, specifier); - // } - // } + // Delete the 'type' keyword from the import clause + deleteTypeKeywordOfImportClause(ct, sourceFile, importClause) + + // Add 'type' modifier to existing specifiers (not newly added ones) + // We preserve the type-onlyness of existing specifiers regardless of whether + // it would make a difference in emit (user preference). + if len(existingSpecifiers) > 0 { + for _, specifier := range existingSpecifiers { + if !specifier.AsImportSpecifier().IsTypeOnly { + insertTypeModifierBefore(ct, sourceFile, specifier) + } + } + } } default: panic("Unsupported clause kind: " + clause.Kind.String() + "for doAddExistingFix") @@ -343,3 +356,48 @@ func needsTypeOnly(addAsTypeOnly AddAsTypeOnly) bool { func shouldUseTypeOnly(addAsTypeOnly AddAsTypeOnly, preferences *lsutil.UserPreferences) bool { return needsTypeOnly(addAsTypeOnly) || addAsTypeOnly != AddAsTypeOnlyNotAllowed && preferences.PreferTypeOnlyAutoImports } + +// deleteTypeKeywordOfImportClause deletes the 'type' keyword from an import clause. +// +// This is a workaround for the fact that the change tracker doesn't yet have a Delete method. +// In TypeScript, this would be: changes.delete(sourceFile, getTypeKeywordOfTypeOnlyImport(clause, sourceFile)) +// where getTypeKeywordOfTypeOnlyImport returns the first child token (the 'type' keyword). +// TODO: Implement change.Tracker.Delete() to handle node deletion with proper list/comma handling. +func deleteTypeKeywordOfImportClause(ct *change.Tracker, sourceFile *ast.SourceFile, importClause *ast.ImportClause) { + // import type { foo } from "bar" + // ^^^^^ - this keyword + // We need to find and delete "type " (including trailing space) + + if !importClause.IsTypeOnly() { + return // Nothing to delete + } + + // Use the scanner to get the token at the import clause position + scan := scanner.GetScannerForSourceFile(sourceFile, importClause.Pos()) + token := scan.Token() + + if token != ast.KindTypeKeyword { + // Not a type keyword at this position, nothing to delete + return + } + + // Use TokenStart (not TokenFullStart) to avoid including leading whitespace + typeStart := scan.TokenStart() + typeEnd := scan.TokenEnd() + + // Skip whitespace after 'type' to include it in the deletion + text := sourceFile.Text() + endPos := typeEnd + for endPos < len(text) && (text[endPos] == ' ' || text[endPos] == '\t') { + endPos++ + } + + // Convert text positions to LSP positions + startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, typeStart) + endLine, endChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, endPos) + + ct.ReplaceRangeWithText(sourceFile, lsproto.Range{ + Start: lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, + End: lsproto.Position{Line: uint32(endLine), Character: uint32(endChar)}, + }, "") +} diff --git a/internal/ls/change/tracker.go b/internal/ls/change/tracker.go index 5d88f40a7b..c7866af585 100644 --- a/internal/ls/change/tracker.go +++ b/internal/ls/change/tracker.go @@ -287,7 +287,11 @@ func (t *Tracker) InsertImportSpecifierAtIndex(sourceFile *ast.SourceFile, newSp namedImportsNode := namedImports.AsNamedImports() elements := namedImportsNode.Elements.Nodes - if index > 0 && len(elements) > index { + if index >= len(elements) { + // Insert at the end (after the last element) + t.InsertNodeInListAfter(sourceFile, elements[len(elements)-1], newSpecifier, elements) + } else if index > 0 { + // Insert after the element at index-1 t.InsertNodeInListAfter(sourceFile, elements[index-1], newSpecifier, elements) } else { // Insert before the first element From fe7e17dca467f35bc52b2e499ee3ea2c39c58c9f Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 10 Nov 2025 23:56:04 -0800 Subject: [PATCH 21/48] some more --- internal/astnav/tokens.go | 57 ++++++ internal/ls/autoimportfixes.go | 50 +----- internal/ls/change/delete.go | 265 ++++++++++++++++++++++++++++ internal/ls/change/tracker.go | 85 ++++++++- internal/ls/lsutil/importhelpers.go | 19 ++ 5 files changed, 424 insertions(+), 52 deletions(-) create mode 100644 internal/ls/change/delete.go create mode 100644 internal/ls/lsutil/importhelpers.go diff --git a/internal/astnav/tokens.go b/internal/astnav/tokens.go index 27ad1ebdf6..85fa79801e 100644 --- a/internal/astnav/tokens.go +++ b/internal/astnav/tokens.go @@ -672,3 +672,60 @@ func shouldSkipChild(node *ast.Node) bool { ast.IsJSDocLinkLike(node) || ast.IsJSDocTag(node) } + +// FindChildOfKind searches for a child node or token of the specified kind within a containing node. +// This function scans through both AST nodes and intervening tokens to find the first match. +func FindChildOfKind(containingNode *ast.Node, kind ast.Kind, sourceFile *ast.SourceFile) *ast.Node { + lastNodePos := containingNode.Pos() + scan := scanner.GetScannerForSourceFile(sourceFile, lastNodePos) + + var foundChild *ast.Node + visitNode := func(node *ast.Node) bool { + if node == nil || node.Flags&ast.NodeFlagsReparsed != 0 { + return false + } + // Look for child in preceding tokens. + startPos := lastNodePos + for startPos < node.Pos() { + tokenKind := scan.Token() + tokenFullStart := scan.TokenFullStart() + tokenEnd := scan.TokenEnd() + token := sourceFile.GetOrCreateToken(tokenKind, tokenFullStart, tokenEnd, containingNode) + if tokenKind == kind { + foundChild = token + return true + } + startPos = tokenEnd + scan.Scan() + } + if node.Kind == kind { + foundChild = node + return true + } + + lastNodePos = node.End() + scan.ResetPos(lastNodePos) + return false + } + + ast.ForEachChildAndJSDoc(containingNode, sourceFile, visitNode) + + if foundChild != nil { + return foundChild + } + + // Look for child in trailing tokens. + startPos := lastNodePos + for startPos < containingNode.End() { + tokenKind := scan.Token() + tokenFullStart := scan.TokenFullStart() + tokenEnd := scan.TokenEnd() + token := sourceFile.GetOrCreateToken(tokenKind, tokenFullStart, tokenEnd, containingNode) + if tokenKind == kind { + return token + } + startPos = tokenEnd + scan.Scan() + } + return nil +} diff --git a/internal/ls/autoimportfixes.go b/internal/ls/autoimportfixes.go index 06fc5f07a8..9c9d010d27 100644 --- a/internal/ls/autoimportfixes.go +++ b/internal/ls/autoimportfixes.go @@ -10,8 +10,6 @@ import ( "github.com/microsoft/typescript-go/internal/ls/change" "github.com/microsoft/typescript-go/internal/ls/lsutil" "github.com/microsoft/typescript-go/internal/ls/organizeimports" - "github.com/microsoft/typescript-go/internal/lsp/lsproto" - "github.com/microsoft/typescript-go/internal/scanner" "github.com/microsoft/typescript-go/internal/stringutil" ) @@ -181,7 +179,8 @@ func (ls *LanguageService) doAddExistingFix( if promoteFromTypeOnly { // Delete the 'type' keyword from the import clause - deleteTypeKeywordOfImportClause(ct, sourceFile, importClause) + typeKeyword := lsutil.GetTypeKeywordOfTypeOnlyImport(importClause, sourceFile) + ct.Delete(sourceFile, typeKeyword) // Add 'type' modifier to existing specifiers (not newly added ones) // We preserve the type-onlyness of existing specifiers regardless of whether @@ -356,48 +355,3 @@ func needsTypeOnly(addAsTypeOnly AddAsTypeOnly) bool { func shouldUseTypeOnly(addAsTypeOnly AddAsTypeOnly, preferences *lsutil.UserPreferences) bool { return needsTypeOnly(addAsTypeOnly) || addAsTypeOnly != AddAsTypeOnlyNotAllowed && preferences.PreferTypeOnlyAutoImports } - -// deleteTypeKeywordOfImportClause deletes the 'type' keyword from an import clause. -// -// This is a workaround for the fact that the change tracker doesn't yet have a Delete method. -// In TypeScript, this would be: changes.delete(sourceFile, getTypeKeywordOfTypeOnlyImport(clause, sourceFile)) -// where getTypeKeywordOfTypeOnlyImport returns the first child token (the 'type' keyword). -// TODO: Implement change.Tracker.Delete() to handle node deletion with proper list/comma handling. -func deleteTypeKeywordOfImportClause(ct *change.Tracker, sourceFile *ast.SourceFile, importClause *ast.ImportClause) { - // import type { foo } from "bar" - // ^^^^^ - this keyword - // We need to find and delete "type " (including trailing space) - - if !importClause.IsTypeOnly() { - return // Nothing to delete - } - - // Use the scanner to get the token at the import clause position - scan := scanner.GetScannerForSourceFile(sourceFile, importClause.Pos()) - token := scan.Token() - - if token != ast.KindTypeKeyword { - // Not a type keyword at this position, nothing to delete - return - } - - // Use TokenStart (not TokenFullStart) to avoid including leading whitespace - typeStart := scan.TokenStart() - typeEnd := scan.TokenEnd() - - // Skip whitespace after 'type' to include it in the deletion - text := sourceFile.Text() - endPos := typeEnd - for endPos < len(text) && (text[endPos] == ' ' || text[endPos] == '\t') { - endPos++ - } - - // Convert text positions to LSP positions - startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, typeStart) - endLine, endChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, endPos) - - ct.ReplaceRangeWithText(sourceFile, lsproto.Range{ - Start: lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, - End: lsproto.Position{Line: uint32(endLine), Character: uint32(endChar)}, - }, "") -} diff --git a/internal/ls/change/delete.go b/internal/ls/change/delete.go new file mode 100644 index 0000000000..bae312089b --- /dev/null +++ b/internal/ls/change/delete.go @@ -0,0 +1,265 @@ +package change + +import ( + "slices" + + "github.com/microsoft/typescript-go/internal/ast" + "github.com/microsoft/typescript-go/internal/astnav" + "github.com/microsoft/typescript-go/internal/core" + "github.com/microsoft/typescript-go/internal/debug" + "github.com/microsoft/typescript-go/internal/format" + "github.com/microsoft/typescript-go/internal/lsp/lsproto" + "github.com/microsoft/typescript-go/internal/scanner" + "github.com/microsoft/typescript-go/internal/stringutil" +) + +// deleteDeclaration deletes a node with smart handling for different node types. +// This handles special cases like import specifiers in lists, parameters, etc. +func deleteDeclaration(t *Tracker, deletedNodesInLists map[*ast.Node]bool, sourceFile *ast.SourceFile, node *ast.Node) { + switch node.Kind { + case ast.KindParameter: + oldFunction := node.Parent + if oldFunction.Kind == ast.KindArrowFunction && + len(oldFunction.AsArrowFunction().Parameters.Nodes) == 1 && + astnav.FindChildOfKind(oldFunction, ast.KindOpenParenToken, sourceFile) == nil { + // Lambdas with exactly one parameter are special because, after removal, there + // must be an empty parameter list (i.e. `()`) and this won't necessarily be the + // case if the parameter is simply removed (e.g. in `x => 1`). + t.ReplaceRangeWithText(sourceFile, t.getAdjustedRange(sourceFile, node, node, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude), "()") + } else { + deleteNodeInList(t, deletedNodesInLists, sourceFile, node) + } + + case ast.KindImportDeclaration, ast.KindImportEqualsDeclaration: + imports := sourceFile.Imports() + isFirstImport := len(imports) > 0 && node == imports[0].Parent || + node == core.Find(sourceFile.Statements.Nodes, func(s *ast.Node) bool { return ast.IsAnyImportSyntax(s) }) + // For first import, leave header comment in place, otherwise only delete JSDoc comments + leadingTrivia := leadingTriviaOptionStartLine + if isFirstImport { + leadingTrivia = leadingTriviaOptionExclude + } else if hasJSDocNodes(node) { + leadingTrivia = leadingTriviaOptionJSDoc + } + deleteNode(t, sourceFile, node, leadingTrivia, trailingTriviaOptionInclude) + + case ast.KindBindingElement: + pattern := node.Parent + preserveComma := pattern.Kind == ast.KindArrayBindingPattern && + node != pattern.AsBindingPattern().Elements.Nodes[len(pattern.AsBindingPattern().Elements.Nodes)-1] + if preserveComma { + deleteNode(t, sourceFile, node, leadingTriviaOptionIncludeAll, trailingTriviaOptionExclude) + } else { + deleteNodeInList(t, deletedNodesInLists, sourceFile, node) + } + + case ast.KindVariableDeclaration: + deleteVariableDeclaration(t, deletedNodesInLists, sourceFile, node) + + case ast.KindTypeParameter: + deleteNodeInList(t, deletedNodesInLists, sourceFile, node) + + case ast.KindImportSpecifier: + namedImports := node.Parent + if len(namedImports.AsNamedImports().Elements.Nodes) == 1 { + deleteImportBinding(t, sourceFile, namedImports) + } else { + deleteNodeInList(t, deletedNodesInLists, sourceFile, node) + } + + case ast.KindNamespaceImport: + deleteImportBinding(t, sourceFile, node) + + case ast.KindSemicolonToken: + deleteNode(t, sourceFile, node, leadingTriviaOptionIncludeAll, trailingTriviaOptionExclude) + + case ast.KindFunctionKeyword: + deleteNode(t, sourceFile, node, leadingTriviaOptionExclude, trailingTriviaOptionInclude) + + case ast.KindClassDeclaration, ast.KindFunctionDeclaration: + leadingTrivia := leadingTriviaOptionStartLine + if hasJSDocNodes(node) { + leadingTrivia = leadingTriviaOptionJSDoc + } + deleteNode(t, sourceFile, node, leadingTrivia, trailingTriviaOptionInclude) + + default: + if node.Parent == nil { + // a misbehaving client can reach here with the SourceFile node + deleteNode(t, sourceFile, node, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + } else if node.Parent.Kind == ast.KindImportClause && node.Parent.AsImportClause().Name() == node { + deleteDefaultImport(t, sourceFile, node.Parent) + } else if node.Parent.Kind == ast.KindCallExpression && slices.Contains(node.Parent.AsCallExpression().Arguments.Nodes, node) { + deleteNodeInList(t, deletedNodesInLists, sourceFile, node) + } else { + deleteNode(t, sourceFile, node, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + } + } +} + +func deleteDefaultImport(t *Tracker, sourceFile *ast.SourceFile, importClause *ast.Node) { + clause := importClause.AsImportClause() + if clause.NamedBindings == nil { + // Delete the whole import + deleteNode(t, sourceFile, importClause.Parent, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + } else { + // import |d,| * as ns from './file' + name := clause.Name() + start := astnav.GetStartOfNode(name, sourceFile, false) + nextToken := astnav.GetTokenAtPosition(sourceFile, name.End()) + if nextToken != nil && nextToken.Kind == ast.KindCommaToken { + // shift first non-whitespace position after comma to the start position of the node + end := scanner.SkipTriviaEx(sourceFile.Text(), nextToken.End(), &scanner.SkipTriviaOptions{StopAfterLineBreak: false, StopAtComments: true}) + startPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(start)) + endPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(end)) + t.ReplaceRangeWithText(sourceFile, lsproto.Range{Start: startPos, End: endPos}, "") + } else { + deleteNode(t, sourceFile, name, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + } + } +} + +func deleteImportBinding(t *Tracker, sourceFile *ast.SourceFile, node *ast.Node) { + importClause := node.Parent.AsImportClause() + if importClause.Name() != nil { + // Delete named imports while preserving the default import + // import d|, * as ns| from './file' + // import d|, { a }| from './file' + previousToken := astnav.GetTokenAtPosition(sourceFile, node.Pos()-1) + debug.Assert(previousToken != nil, "previousToken should not be nil") + startPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(astnav.GetStartOfNode(previousToken, sourceFile, false))) + endPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(node.End())) + t.ReplaceRangeWithText(sourceFile, lsproto.Range{Start: startPos, End: endPos}, "") + } else { + // Delete the entire import declaration + // |import * as ns from './file'| + // |import { a } from './file'| + importDecl := ast.FindAncestorKind(node, ast.KindImportDeclaration) + debug.Assert(importDecl != nil, "importDecl should not be nil") + deleteNode(t, sourceFile, importDecl, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + } +} + +func deleteVariableDeclaration(t *Tracker, deletedNodesInLists map[*ast.Node]bool, sourceFile *ast.SourceFile, node *ast.Node) { + parent := node.Parent + + if parent.Kind == ast.KindCatchClause { + // TODO: There's currently no unused diagnostic for this, could be a suggestion + openParen := astnav.FindChildOfKind(parent, ast.KindOpenParenToken, sourceFile) + closeParen := astnav.FindChildOfKind(parent, ast.KindCloseParenToken, sourceFile) + debug.Assert(openParen != nil && closeParen != nil, "catch clause should have parens") + t.DeleteNodeRange(sourceFile, openParen, closeParen, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + return + } + + if len(parent.AsVariableDeclarationList().Declarations.Nodes) != 1 { + deleteNodeInList(t, deletedNodesInLists, sourceFile, node) + return + } + + gp := parent.Parent + switch gp.Kind { + case ast.KindForOfStatement, ast.KindForInStatement: + t.ReplaceNode(sourceFile, node, t.NodeFactory.NewObjectLiteralExpression(t.NodeFactory.NewNodeList([]*ast.Node{}), false), nil) + + case ast.KindForStatement: + deleteNode(t, sourceFile, parent, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + + case ast.KindVariableStatement: + leadingTrivia := leadingTriviaOptionStartLine + if hasJSDocNodes(gp) { + leadingTrivia = leadingTriviaOptionJSDoc + } + deleteNode(t, sourceFile, gp, leadingTrivia, trailingTriviaOptionInclude) + + default: + debug.Fail("Unexpected grandparent kind: " + gp.Kind.String()) + } +} + +// deleteNode deletes a node with the specified trivia options. +// Warning: This deletes comments too. +func deleteNode(t *Tracker, sourceFile *ast.SourceFile, node *ast.Node, leadingTrivia leadingTriviaOption, trailingTrivia trailingTriviaOption) { + startPosition := t.getAdjustedStartPosition(sourceFile, node, leadingTrivia, false) + endPosition := t.getAdjustedEndPosition(sourceFile, node, trailingTrivia) + startPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(startPosition)) + endPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(endPosition)) + t.ReplaceRangeWithText(sourceFile, lsproto.Range{Start: startPos, End: endPos}, "") +} + +func deleteNodeInList(t *Tracker, deletedNodesInLists map[*ast.Node]bool, sourceFile *ast.SourceFile, node *ast.Node) { + containingList := format.GetContainingList(node, sourceFile) + debug.Assert(containingList != nil, "containingList should not be nil") + index := slices.Index(containingList.Nodes, node) + debug.Assert(index != -1, "node should be in containing list") + + if len(containingList.Nodes) == 1 { + deleteNode(t, sourceFile, node, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + return + } + + // Note: We will only delete a comma *after* a node. This will leave a trailing comma if we delete the last node. + // That's handled in the end by finishTrailingCommaAfterDeletingNodesInList. + debug.Assert(!deletedNodesInLists[node], "Deleting a node twice") + deletedNodesInLists[node] = true + + startPos := t.startPositionToDeleteNodeInList(sourceFile, node) + var endPos int + if index == len(containingList.Nodes)-1 { + endPos = t.getAdjustedEndPosition(sourceFile, node, trailingTriviaOptionInclude) + } else { + prevNode := (*ast.Node)(nil) + if index > 0 { + prevNode = containingList.Nodes[index-1] + } + endPos = t.endPositionToDeleteNodeInList(sourceFile, node, prevNode, containingList.Nodes[index+1]) + } + + startLSPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(startPos)) + endLSPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(endPos)) + t.ReplaceRangeWithText(sourceFile, lsproto.Range{Start: startLSPos, End: endLSPos}, "") +} + +// startPositionToDeleteNodeInList finds the first non-whitespace position in the leading trivia of the node +func (t *Tracker) startPositionToDeleteNodeInList(sourceFile *ast.SourceFile, node *ast.Node) int { + start := t.getAdjustedStartPosition(sourceFile, node, leadingTriviaOptionIncludeAll, false) + return scanner.SkipTriviaEx(sourceFile.Text(), start, &scanner.SkipTriviaOptions{StopAfterLineBreak: false, StopAtComments: true}) +} + +func (t *Tracker) endPositionToDeleteNodeInList(sourceFile *ast.SourceFile, node *ast.Node, prevNode *ast.Node, nextNode *ast.Node) int { + end := t.startPositionToDeleteNodeInList(sourceFile, nextNode) + if prevNode == nil || positionsAreOnSameLine(t.getAdjustedEndPosition(sourceFile, node, trailingTriviaOptionInclude), end, sourceFile) { + return end + } + token := astnav.FindPrecedingToken(sourceFile, astnav.GetStartOfNode(nextNode, sourceFile, false)) + if isSeparator(node, token) { + prevToken := astnav.FindPrecedingToken(sourceFile, astnav.GetStartOfNode(node, sourceFile, false)) + if isSeparator(prevNode, prevToken) { + pos := scanner.SkipTriviaEx(sourceFile.Text(), token.End(), &scanner.SkipTriviaOptions{StopAfterLineBreak: true, StopAtComments: true}) + if positionsAreOnSameLine(astnav.GetStartOfNode(prevToken, sourceFile, false), astnav.GetStartOfNode(token, sourceFile, false), sourceFile) { + if pos > 0 && stringutil.IsLineBreak(rune(sourceFile.Text()[pos-1])) { + return pos - 1 + } + return pos + } + if stringutil.IsLineBreak(rune(sourceFile.Text()[pos])) { + return pos + } + } + } + return end +} + +func positionsAreOnSameLine(pos1, pos2 int, sourceFile *ast.SourceFile) bool { + return format.GetLineStartPositionForPosition(pos1, sourceFile) == format.GetLineStartPositionForPosition(pos2, sourceFile) +} + +// hasJSDocNodes checks if a node has JSDoc comments +func hasJSDocNodes(node *ast.Node) bool { + if node == nil { + return false + } + // nil is ok for JSDoc - it will return empty slice if not available + jsdocs := node.JSDoc(nil) + return len(jsdocs) > 0 +} diff --git a/internal/ls/change/tracker.go b/internal/ls/change/tracker.go index c7866af585..d5d16e29dc 100644 --- a/internal/ls/change/tracker.go +++ b/internal/ls/change/tracker.go @@ -82,13 +82,19 @@ type Tracker struct { *printer.EmitContext *ast.NodeFactory - changes *collections.MultiMap[*ast.SourceFile, *trackerEdit] + changes *collections.MultiMap[*ast.SourceFile, *trackerEdit] + deletedNodes []deletedNode // created during call to getChanges writer *printer.ChangeTrackerWriter // printer } +type deletedNode struct { + sourceFile *ast.SourceFile + node *ast.Node +} + func NewTracker(ctx context.Context, compilerOptions *core.CompilerOptions, formatOptions *format.FormatCodeSettings, converters *lsconv.Converters) *Tracker { emitContext := printer.NewEmitContext() newLine := compilerOptions.NewLine.GetNewLineCharacter() @@ -104,10 +110,10 @@ func NewTracker(ctx context.Context, compilerOptions *core.CompilerOptions, form } } -// !!! address strada note -// - Note: after calling this, the TextChanges object must be discarded! +// GetChanges returns the accumulated text edits. +// Note: after calling this, the Tracker object must be discarded! func (t *Tracker) GetChanges() map[string][]*lsproto.TextEdit { - // !!! finishDeleteDeclarations + t.finishDeleteDeclarations() // !!! finishClassesWithNodesInsertedAtStart changes := t.getTextChangesFromChanges() // !!! changes for new files @@ -169,6 +175,73 @@ func (t *Tracker) InsertNodeBefore(sourceFile *ast.SourceFile, before *ast.Node, t.InsertNodeAt(sourceFile, core.TextPos(t.getAdjustedStartPosition(sourceFile, before, leadingTriviaOptionNone, false)), newNode, t.getOptionsForInsertNodeBefore(before, newNode, blankLineBetween)) } +// Delete queues a node for deletion with smart handling of list items, imports, etc. +// The actual deletion happens in finishDeleteDeclarations during GetChanges. +func (t *Tracker) Delete(sourceFile *ast.SourceFile, node *ast.Node) { + t.deletedNodes = append(t.deletedNodes, deletedNode{sourceFile: sourceFile, node: node}) +} + +// DeleteNode deletes a node immediately with specified trivia options. +// Stop! Consider using Delete instead, which has logic for deleting nodes from delimited lists. +func (t *Tracker) DeleteNode(sourceFile *ast.SourceFile, node *ast.Node, leadingTrivia leadingTriviaOption, trailingTrivia trailingTriviaOption) { + rng := t.getAdjustedRange(sourceFile, node, node, leadingTrivia, trailingTrivia) + t.ReplaceRangeWithText(sourceFile, rng, "") +} + +// DeleteNodeRange deletes a range of nodes with specified trivia options. +func (t *Tracker) DeleteNodeRange(sourceFile *ast.SourceFile, startNode *ast.Node, endNode *ast.Node, leadingTrivia leadingTriviaOption, trailingTrivia trailingTriviaOption) { + startPosition := t.getAdjustedStartPosition(sourceFile, startNode, leadingTrivia, false) + endPosition := t.getAdjustedEndPosition(sourceFile, endNode, trailingTrivia) + startPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(startPosition)) + endPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(endPosition)) + t.ReplaceRangeWithText(sourceFile, lsproto.Range{Start: startPos, End: endPos}, "") +} + +// finishDeleteDeclarations processes all queued deletions with smart handling for lists and trailing commas. +func (t *Tracker) finishDeleteDeclarations() { + deletedNodesInLists := make(map[*ast.Node]bool) + + for _, deleted := range t.deletedNodes { + // Skip if this node is contained within another deleted node + isContained := false + for _, other := range t.deletedNodes { + if other.sourceFile == deleted.sourceFile && other.node != deleted.node && + rangeContainsRangeExclusive(other.node, deleted.node) { + isContained = true + break + } + } + if isContained { + continue + } + + deleteDeclaration(t, deletedNodesInLists, deleted.sourceFile, deleted.node) + } + + // Handle trailing commas for last elements in lists + for node := range deletedNodesInLists { + sourceFile := ast.GetSourceFileOfNode(node) + list := format.GetContainingList(node, sourceFile) + if list == nil || node != list.Nodes[len(list.Nodes)-1] { + continue + } + + lastNonDeletedIndex := -1 + for i := len(list.Nodes) - 2; i >= 0; i-- { + if !deletedNodesInLists[list.Nodes[i]] { + lastNonDeletedIndex = i + break + } + } + + if lastNonDeletedIndex != -1 { + startPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(list.Nodes[lastNonDeletedIndex].End())) + endPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(t.startPositionToDeleteNodeInList(sourceFile, list.Nodes[lastNonDeletedIndex+1]))) + t.ReplaceRangeWithText(sourceFile, lsproto.Range{Start: startPos, End: endPos}, "") + } + } +} + func (t *Tracker) endPosForInsertNodeAfter(sourceFile *ast.SourceFile, after *ast.Node, newNode *ast.Node) core.TextPos { if (needSemicolonBetween(after, newNode)) && (rune(sourceFile.Text()[after.End()-1]) != ';') { // check if previous statement ends with semicolon @@ -391,6 +464,10 @@ func ptrTo[T any](v T) *T { return &v } +func rangeContainsRangeExclusive(outer *ast.Node, inner *ast.Node) bool { + return outer.Pos() < inner.Pos() && inner.End() < outer.End() +} + func isSeparator(node *ast.Node, candidate *ast.Node) bool { return candidate != nil && node.Parent != nil && (candidate.Kind == ast.KindCommaToken || (candidate.Kind == ast.KindSemicolonToken && node.Parent.Kind == ast.KindObjectLiteralExpression)) } diff --git a/internal/ls/lsutil/importhelpers.go b/internal/ls/lsutil/importhelpers.go new file mode 100644 index 0000000000..c4cec30384 --- /dev/null +++ b/internal/ls/lsutil/importhelpers.go @@ -0,0 +1,19 @@ +package lsutil + +import ( + "github.com/microsoft/typescript-go/internal/ast" + "github.com/microsoft/typescript-go/internal/astnav" + "github.com/microsoft/typescript-go/internal/debug" +) + +// GetTypeKeywordOfTypeOnlyImport returns the 'type' keyword token from a type-only import clause. +// This is equivalent to TypeScript's getTypeKeywordOfTypeOnlyImport helper. +func GetTypeKeywordOfTypeOnlyImport(importClause *ast.ImportClause, sourceFile *ast.SourceFile) *ast.Node { + debug.Assert(importClause.IsTypeOnly(), "import clause must be type-only") + // The first child of a type-only import clause is the 'type' keyword + // import type { foo } from './bar' + // ^^^^ + typeKeyword := astnav.FindChildOfKind(importClause.AsNode(), ast.KindTypeKeyword, sourceFile) + debug.Assert(typeKeyword != nil, "type-only import clause should have a type keyword") + return typeKeyword +} From 23cbb42b5c9444446e4a75e15d87f975088422f0 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 00:06:21 -0800 Subject: [PATCH 22/48] some more --- internal/ls/autoimportfixes.go | 2 +- internal/ls/change/delete.go | 57 +++++++++++++++++-------------- internal/ls/change/tracker.go | 47 ++++++++++++++----------- internal/ls/change/trackerimpl.go | 26 +++++++------- 4 files changed, 72 insertions(+), 60 deletions(-) diff --git a/internal/ls/autoimportfixes.go b/internal/ls/autoimportfixes.go index 9c9d010d27..c68ddc5b11 100644 --- a/internal/ls/autoimportfixes.go +++ b/internal/ls/autoimportfixes.go @@ -188,7 +188,7 @@ func (ls *LanguageService) doAddExistingFix( if len(existingSpecifiers) > 0 { for _, specifier := range existingSpecifiers { if !specifier.AsImportSpecifier().IsTypeOnly { - insertTypeModifierBefore(ct, sourceFile, specifier) + ct.InsertModifierBefore(sourceFile, ast.KindTypeKeyword, specifier) } } } diff --git a/internal/ls/change/delete.go b/internal/ls/change/delete.go index bae312089b..a001cdbcdc 100644 --- a/internal/ls/change/delete.go +++ b/internal/ls/change/delete.go @@ -25,7 +25,7 @@ func deleteDeclaration(t *Tracker, deletedNodesInLists map[*ast.Node]bool, sourc // Lambdas with exactly one parameter are special because, after removal, there // must be an empty parameter list (i.e. `()`) and this won't necessarily be the // case if the parameter is simply removed (e.g. in `x => 1`). - t.ReplaceRangeWithText(sourceFile, t.getAdjustedRange(sourceFile, node, node, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude), "()") + t.ReplaceRangeWithText(sourceFile, t.getAdjustedRange(sourceFile, node, node, LeadingTriviaOptionIncludeAll, TrailingTriviaOptionInclude), "()") } else { deleteNodeInList(t, deletedNodesInLists, sourceFile, node) } @@ -35,20 +35,20 @@ func deleteDeclaration(t *Tracker, deletedNodesInLists map[*ast.Node]bool, sourc isFirstImport := len(imports) > 0 && node == imports[0].Parent || node == core.Find(sourceFile.Statements.Nodes, func(s *ast.Node) bool { return ast.IsAnyImportSyntax(s) }) // For first import, leave header comment in place, otherwise only delete JSDoc comments - leadingTrivia := leadingTriviaOptionStartLine + leadingTrivia := LeadingTriviaOptionStartLine if isFirstImport { - leadingTrivia = leadingTriviaOptionExclude + leadingTrivia = LeadingTriviaOptionExclude } else if hasJSDocNodes(node) { - leadingTrivia = leadingTriviaOptionJSDoc + leadingTrivia = LeadingTriviaOptionJSDoc } - deleteNode(t, sourceFile, node, leadingTrivia, trailingTriviaOptionInclude) + deleteNode(t, sourceFile, node, leadingTrivia, TrailingTriviaOptionInclude) case ast.KindBindingElement: pattern := node.Parent preserveComma := pattern.Kind == ast.KindArrayBindingPattern && node != pattern.AsBindingPattern().Elements.Nodes[len(pattern.AsBindingPattern().Elements.Nodes)-1] if preserveComma { - deleteNode(t, sourceFile, node, leadingTriviaOptionIncludeAll, trailingTriviaOptionExclude) + deleteNode(t, sourceFile, node, LeadingTriviaOptionIncludeAll, TrailingTriviaOptionExclude) } else { deleteNodeInList(t, deletedNodesInLists, sourceFile, node) } @@ -71,28 +71,33 @@ func deleteDeclaration(t *Tracker, deletedNodesInLists map[*ast.Node]bool, sourc deleteImportBinding(t, sourceFile, node) case ast.KindSemicolonToken: - deleteNode(t, sourceFile, node, leadingTriviaOptionIncludeAll, trailingTriviaOptionExclude) + deleteNode(t, sourceFile, node, LeadingTriviaOptionIncludeAll, TrailingTriviaOptionExclude) + + case ast.KindTypeKeyword: + // For type keyword in import clauses, we need to delete the keyword and any trailing space + // The trailing space is part of the next token's leading trivia, so we include it + deleteNode(t, sourceFile, node, LeadingTriviaOptionExclude, TrailingTriviaOptionInclude) case ast.KindFunctionKeyword: - deleteNode(t, sourceFile, node, leadingTriviaOptionExclude, trailingTriviaOptionInclude) + deleteNode(t, sourceFile, node, LeadingTriviaOptionExclude, TrailingTriviaOptionInclude) case ast.KindClassDeclaration, ast.KindFunctionDeclaration: - leadingTrivia := leadingTriviaOptionStartLine + leadingTrivia := LeadingTriviaOptionStartLine if hasJSDocNodes(node) { - leadingTrivia = leadingTriviaOptionJSDoc + leadingTrivia = LeadingTriviaOptionJSDoc } - deleteNode(t, sourceFile, node, leadingTrivia, trailingTriviaOptionInclude) + deleteNode(t, sourceFile, node, leadingTrivia, TrailingTriviaOptionInclude) default: if node.Parent == nil { // a misbehaving client can reach here with the SourceFile node - deleteNode(t, sourceFile, node, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + deleteNode(t, sourceFile, node, LeadingTriviaOptionIncludeAll, TrailingTriviaOptionInclude) } else if node.Parent.Kind == ast.KindImportClause && node.Parent.AsImportClause().Name() == node { deleteDefaultImport(t, sourceFile, node.Parent) } else if node.Parent.Kind == ast.KindCallExpression && slices.Contains(node.Parent.AsCallExpression().Arguments.Nodes, node) { deleteNodeInList(t, deletedNodesInLists, sourceFile, node) } else { - deleteNode(t, sourceFile, node, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + deleteNode(t, sourceFile, node, LeadingTriviaOptionIncludeAll, TrailingTriviaOptionInclude) } } } @@ -101,7 +106,7 @@ func deleteDefaultImport(t *Tracker, sourceFile *ast.SourceFile, importClause *a clause := importClause.AsImportClause() if clause.NamedBindings == nil { // Delete the whole import - deleteNode(t, sourceFile, importClause.Parent, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + deleteNode(t, sourceFile, importClause.Parent, LeadingTriviaOptionIncludeAll, TrailingTriviaOptionInclude) } else { // import |d,| * as ns from './file' name := clause.Name() @@ -114,7 +119,7 @@ func deleteDefaultImport(t *Tracker, sourceFile *ast.SourceFile, importClause *a endPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(end)) t.ReplaceRangeWithText(sourceFile, lsproto.Range{Start: startPos, End: endPos}, "") } else { - deleteNode(t, sourceFile, name, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + deleteNode(t, sourceFile, name, LeadingTriviaOptionIncludeAll, TrailingTriviaOptionInclude) } } } @@ -136,7 +141,7 @@ func deleteImportBinding(t *Tracker, sourceFile *ast.SourceFile, node *ast.Node) // |import { a } from './file'| importDecl := ast.FindAncestorKind(node, ast.KindImportDeclaration) debug.Assert(importDecl != nil, "importDecl should not be nil") - deleteNode(t, sourceFile, importDecl, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + deleteNode(t, sourceFile, importDecl, LeadingTriviaOptionIncludeAll, TrailingTriviaOptionInclude) } } @@ -148,7 +153,7 @@ func deleteVariableDeclaration(t *Tracker, deletedNodesInLists map[*ast.Node]boo openParen := astnav.FindChildOfKind(parent, ast.KindOpenParenToken, sourceFile) closeParen := astnav.FindChildOfKind(parent, ast.KindCloseParenToken, sourceFile) debug.Assert(openParen != nil && closeParen != nil, "catch clause should have parens") - t.DeleteNodeRange(sourceFile, openParen, closeParen, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + t.DeleteNodeRange(sourceFile, openParen, closeParen, LeadingTriviaOptionIncludeAll, TrailingTriviaOptionInclude) return } @@ -163,14 +168,14 @@ func deleteVariableDeclaration(t *Tracker, deletedNodesInLists map[*ast.Node]boo t.ReplaceNode(sourceFile, node, t.NodeFactory.NewObjectLiteralExpression(t.NodeFactory.NewNodeList([]*ast.Node{}), false), nil) case ast.KindForStatement: - deleteNode(t, sourceFile, parent, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + deleteNode(t, sourceFile, parent, LeadingTriviaOptionIncludeAll, TrailingTriviaOptionInclude) case ast.KindVariableStatement: - leadingTrivia := leadingTriviaOptionStartLine + leadingTrivia := LeadingTriviaOptionStartLine if hasJSDocNodes(gp) { - leadingTrivia = leadingTriviaOptionJSDoc + leadingTrivia = LeadingTriviaOptionJSDoc } - deleteNode(t, sourceFile, gp, leadingTrivia, trailingTriviaOptionInclude) + deleteNode(t, sourceFile, gp, leadingTrivia, TrailingTriviaOptionInclude) default: debug.Fail("Unexpected grandparent kind: " + gp.Kind.String()) @@ -179,7 +184,7 @@ func deleteVariableDeclaration(t *Tracker, deletedNodesInLists map[*ast.Node]boo // deleteNode deletes a node with the specified trivia options. // Warning: This deletes comments too. -func deleteNode(t *Tracker, sourceFile *ast.SourceFile, node *ast.Node, leadingTrivia leadingTriviaOption, trailingTrivia trailingTriviaOption) { +func deleteNode(t *Tracker, sourceFile *ast.SourceFile, node *ast.Node, leadingTrivia LeadingTriviaOption, trailingTrivia TrailingTriviaOption) { startPosition := t.getAdjustedStartPosition(sourceFile, node, leadingTrivia, false) endPosition := t.getAdjustedEndPosition(sourceFile, node, trailingTrivia) startPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(startPosition)) @@ -194,7 +199,7 @@ func deleteNodeInList(t *Tracker, deletedNodesInLists map[*ast.Node]bool, source debug.Assert(index != -1, "node should be in containing list") if len(containingList.Nodes) == 1 { - deleteNode(t, sourceFile, node, leadingTriviaOptionIncludeAll, trailingTriviaOptionInclude) + deleteNode(t, sourceFile, node, LeadingTriviaOptionIncludeAll, TrailingTriviaOptionInclude) return } @@ -206,7 +211,7 @@ func deleteNodeInList(t *Tracker, deletedNodesInLists map[*ast.Node]bool, source startPos := t.startPositionToDeleteNodeInList(sourceFile, node) var endPos int if index == len(containingList.Nodes)-1 { - endPos = t.getAdjustedEndPosition(sourceFile, node, trailingTriviaOptionInclude) + endPos = t.getAdjustedEndPosition(sourceFile, node, TrailingTriviaOptionInclude) } else { prevNode := (*ast.Node)(nil) if index > 0 { @@ -222,13 +227,13 @@ func deleteNodeInList(t *Tracker, deletedNodesInLists map[*ast.Node]bool, source // startPositionToDeleteNodeInList finds the first non-whitespace position in the leading trivia of the node func (t *Tracker) startPositionToDeleteNodeInList(sourceFile *ast.SourceFile, node *ast.Node) int { - start := t.getAdjustedStartPosition(sourceFile, node, leadingTriviaOptionIncludeAll, false) + start := t.getAdjustedStartPosition(sourceFile, node, LeadingTriviaOptionIncludeAll, false) return scanner.SkipTriviaEx(sourceFile.Text(), start, &scanner.SkipTriviaOptions{StopAfterLineBreak: false, StopAtComments: true}) } func (t *Tracker) endPositionToDeleteNodeInList(sourceFile *ast.SourceFile, node *ast.Node, prevNode *ast.Node, nextNode *ast.Node) int { end := t.startPositionToDeleteNodeInList(sourceFile, nextNode) - if prevNode == nil || positionsAreOnSameLine(t.getAdjustedEndPosition(sourceFile, node, trailingTriviaOptionInclude), end, sourceFile) { + if prevNode == nil || positionsAreOnSameLine(t.getAdjustedEndPosition(sourceFile, node, TrailingTriviaOptionInclude), end, sourceFile) { return end } token := astnav.FindPrecedingToken(sourceFile, astnav.GetStartOfNode(nextNode, sourceFile, false)) diff --git a/internal/ls/change/tracker.go b/internal/ls/change/tracker.go index d5d16e29dc..ef2c22ae18 100644 --- a/internal/ls/change/tracker.go +++ b/internal/ls/change/tracker.go @@ -29,28 +29,28 @@ type NodeOptions struct { // Text of inserted node will be formatted with this delta, otherwise delta will be inferred from the new node kind delta *int - leadingTriviaOption - trailingTriviaOption + LeadingTriviaOption + TrailingTriviaOption joiner string } -type leadingTriviaOption int +type LeadingTriviaOption int const ( - leadingTriviaOptionNone leadingTriviaOption = 0 - leadingTriviaOptionExclude leadingTriviaOption = 1 - leadingTriviaOptionIncludeAll leadingTriviaOption = 2 - leadingTriviaOptionJSDoc leadingTriviaOption = 3 - leadingTriviaOptionStartLine leadingTriviaOption = 4 + LeadingTriviaOptionNone LeadingTriviaOption = 0 + LeadingTriviaOptionExclude LeadingTriviaOption = 1 + LeadingTriviaOptionIncludeAll LeadingTriviaOption = 2 + LeadingTriviaOptionJSDoc LeadingTriviaOption = 3 + LeadingTriviaOptionStartLine LeadingTriviaOption = 4 ) -type trailingTriviaOption int +type TrailingTriviaOption int const ( - trailingTriviaOptionNone trailingTriviaOption = 0 - trailingTriviaOptionExclude trailingTriviaOption = 1 - trailingTriviaOptionExcludeWhitespace trailingTriviaOption = 2 - trailingTriviaOptionInclude trailingTriviaOption = 3 + TrailingTriviaOptionNone TrailingTriviaOption = 0 + TrailingTriviaOptionExclude TrailingTriviaOption = 1 + TrailingTriviaOptionExcludeWhitespace TrailingTriviaOption = 2 + TrailingTriviaOptionInclude TrailingTriviaOption = 3 ) type trackerEditKind int @@ -124,11 +124,11 @@ func (t *Tracker) ReplaceNode(sourceFile *ast.SourceFile, oldNode *ast.Node, new if options == nil { // defaults to `useNonAdjustedPositions` options = &NodeOptions{ - leadingTriviaOption: leadingTriviaOptionExclude, - trailingTriviaOption: trailingTriviaOptionExclude, + LeadingTriviaOption: LeadingTriviaOptionExclude, + TrailingTriviaOption: TrailingTriviaOptionExclude, } } - t.ReplaceRange(sourceFile, t.getAdjustedRange(sourceFile, oldNode, oldNode, options.leadingTriviaOption, options.trailingTriviaOption), newNode, *options) + t.ReplaceRange(sourceFile, t.getAdjustedRange(sourceFile, oldNode, oldNode, options.LeadingTriviaOption, options.TrailingTriviaOption), newNode, *options) } func (t *Tracker) ReplaceRange(sourceFile *ast.SourceFile, lsprotoRange lsproto.Range, newNode *ast.Node, options NodeOptions) { @@ -172,7 +172,14 @@ func (t *Tracker) InsertNodesAfter(sourceFile *ast.SourceFile, after *ast.Node, } func (t *Tracker) InsertNodeBefore(sourceFile *ast.SourceFile, before *ast.Node, newNode *ast.Node, blankLineBetween bool) { - t.InsertNodeAt(sourceFile, core.TextPos(t.getAdjustedStartPosition(sourceFile, before, leadingTriviaOptionNone, false)), newNode, t.getOptionsForInsertNodeBefore(before, newNode, blankLineBetween)) + t.InsertNodeAt(sourceFile, core.TextPos(t.getAdjustedStartPosition(sourceFile, before, LeadingTriviaOptionNone, false)), newNode, t.getOptionsForInsertNodeBefore(before, newNode, blankLineBetween)) +} + +// InsertModifierBefore inserts a modifier token (like 'type') before a node with a trailing space. +func (t *Tracker) InsertModifierBefore(sourceFile *ast.SourceFile, modifier ast.Kind, before *ast.Node) { + pos := astnav.GetStartOfNode(before, sourceFile, false) + token := sourceFile.GetOrCreateToken(modifier, pos, pos, before.Parent) + t.InsertNodeAt(sourceFile, core.TextPos(pos), token, NodeOptions{Suffix: " "}) } // Delete queues a node for deletion with smart handling of list items, imports, etc. @@ -183,13 +190,13 @@ func (t *Tracker) Delete(sourceFile *ast.SourceFile, node *ast.Node) { // DeleteNode deletes a node immediately with specified trivia options. // Stop! Consider using Delete instead, which has logic for deleting nodes from delimited lists. -func (t *Tracker) DeleteNode(sourceFile *ast.SourceFile, node *ast.Node, leadingTrivia leadingTriviaOption, trailingTrivia trailingTriviaOption) { +func (t *Tracker) DeleteNode(sourceFile *ast.SourceFile, node *ast.Node, leadingTrivia LeadingTriviaOption, trailingTrivia TrailingTriviaOption) { rng := t.getAdjustedRange(sourceFile, node, node, leadingTrivia, trailingTrivia) t.ReplaceRangeWithText(sourceFile, rng, "") } // DeleteNodeRange deletes a range of nodes with specified trivia options. -func (t *Tracker) DeleteNodeRange(sourceFile *ast.SourceFile, startNode *ast.Node, endNode *ast.Node, leadingTrivia leadingTriviaOption, trailingTrivia trailingTriviaOption) { +func (t *Tracker) DeleteNodeRange(sourceFile *ast.SourceFile, startNode *ast.Node, endNode *ast.Node, leadingTrivia LeadingTriviaOption, trailingTrivia TrailingTriviaOption) { startPosition := t.getAdjustedStartPosition(sourceFile, startNode, leadingTrivia, false) endPosition := t.getAdjustedEndPosition(sourceFile, endNode, trailingTrivia) startPos := t.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(startPosition)) @@ -253,7 +260,7 @@ func (t *Tracker) endPosForInsertNodeAfter(sourceFile *ast.SourceFile, after *as NodeOptions{}, ) } - return core.TextPos(t.getAdjustedEndPosition(sourceFile, after, trailingTriviaOptionNone)) + return core.TextPos(t.getAdjustedEndPosition(sourceFile, after, TrailingTriviaOptionNone)) } /** diff --git a/internal/ls/change/trackerimpl.go b/internal/ls/change/trackerimpl.go index 92b1babd2e..d39c5422c8 100644 --- a/internal/ls/change/trackerimpl.go +++ b/internal/ls/change/trackerimpl.go @@ -172,7 +172,7 @@ func (t *Tracker) getNonformattedText(node *ast.Node, sourceFile *ast.SourceFile } // method on the changeTracker because use of converters -func (t *Tracker) getAdjustedRange(sourceFile *ast.SourceFile, startNode *ast.Node, endNode *ast.Node, leadingOption leadingTriviaOption, trailingOption trailingTriviaOption) lsproto.Range { +func (t *Tracker) getAdjustedRange(sourceFile *ast.SourceFile, startNode *ast.Node, endNode *ast.Node, leadingOption LeadingTriviaOption, trailingOption TrailingTriviaOption) lsproto.Range { return t.converters.ToLSPRange( sourceFile, core.NewTextRange( @@ -183,8 +183,8 @@ func (t *Tracker) getAdjustedRange(sourceFile *ast.SourceFile, startNode *ast.No } // method on the changeTracker because use of converters -func (t *Tracker) getAdjustedStartPosition(sourceFile *ast.SourceFile, node *ast.Node, leadingOption leadingTriviaOption, hasTrailingComment bool) int { - if leadingOption == leadingTriviaOptionJSDoc { +func (t *Tracker) getAdjustedStartPosition(sourceFile *ast.SourceFile, node *ast.Node, leadingOption LeadingTriviaOption, hasTrailingComment bool) int { + if leadingOption == LeadingTriviaOptionJSDoc { if JSDocComments := parser.GetJSDocCommentRanges(t.NodeFactory, nil, node, sourceFile.Text()); len(JSDocComments) > 0 { return format.GetLineStartPositionForPosition(JSDocComments[0].Pos(), sourceFile) } @@ -194,9 +194,9 @@ func (t *Tracker) getAdjustedStartPosition(sourceFile *ast.SourceFile, node *ast startOfLinePos := format.GetLineStartPositionForPosition(start, sourceFile) switch leadingOption { - case leadingTriviaOptionExclude: + case LeadingTriviaOptionExclude: return start - case leadingTriviaOptionStartLine: + case LeadingTriviaOptionStartLine: if node.Loc.ContainsInclusive(startOfLinePos) { return startOfLinePos } @@ -218,7 +218,7 @@ func (t *Tracker) getAdjustedStartPosition(sourceFile *ast.SourceFile, node *ast // fullstart // when b is replaced - we usually want to keep the leading trvia // when b is deleted - we delete it - if leadingOption == leadingTriviaOptionIncludeAll { + if leadingOption == LeadingTriviaOptionIncludeAll { return fullStart } return start @@ -248,8 +248,8 @@ func (t *Tracker) getAdjustedStartPosition(sourceFile *ast.SourceFile, node *ast // method on the changeTracker because of converters // Return the end position of a multiline comment of it is on another line; otherwise returns `undefined`; -func (t *Tracker) getEndPositionOfMultilineTrailingComment(sourceFile *ast.SourceFile, node *ast.Node, trailingOpt trailingTriviaOption) int { - if trailingOpt == trailingTriviaOptionInclude { +func (t *Tracker) getEndPositionOfMultilineTrailingComment(sourceFile *ast.SourceFile, node *ast.Node, trailingOpt TrailingTriviaOption) int { + if trailingOpt == TrailingTriviaOptionInclude { // If the trailing comment is a multiline comment that extends to the next lines, // return the end of the comment and track it for the next nodes to adjust. lineStarts := sourceFile.ECMALineMap() @@ -274,11 +274,11 @@ func (t *Tracker) getEndPositionOfMultilineTrailingComment(sourceFile *ast.Sourc } // method on the changeTracker because of converters -func (t *Tracker) getAdjustedEndPosition(sourceFile *ast.SourceFile, node *ast.Node, trailingTriviaOption trailingTriviaOption) int { - if trailingTriviaOption == trailingTriviaOptionExclude { +func (t *Tracker) getAdjustedEndPosition(sourceFile *ast.SourceFile, node *ast.Node, TrailingTriviaOption TrailingTriviaOption) int { + if TrailingTriviaOption == TrailingTriviaOptionExclude { return node.End() } - if trailingTriviaOption == trailingTriviaOptionExcludeWhitespace { + if TrailingTriviaOption == TrailingTriviaOptionExcludeWhitespace { if comments := slices.AppendSeq( slices.Collect(scanner.GetTrailingCommentRanges(t.NodeFactory, sourceFile.Text(), node.End())), scanner.GetLeadingCommentRanges(t.NodeFactory, sourceFile.Text(), node.End()), @@ -290,13 +290,13 @@ func (t *Tracker) getAdjustedEndPosition(sourceFile *ast.SourceFile, node *ast.N return node.End() } - if multilineEndPosition := t.getEndPositionOfMultilineTrailingComment(sourceFile, node, trailingTriviaOption); multilineEndPosition != 0 { + if multilineEndPosition := t.getEndPositionOfMultilineTrailingComment(sourceFile, node, TrailingTriviaOption); multilineEndPosition != 0 { return multilineEndPosition } newEnd := scanner.SkipTriviaEx(sourceFile.Text(), node.End(), &scanner.SkipTriviaOptions{StopAfterLineBreak: true}) - if newEnd != node.End() && (trailingTriviaOption == trailingTriviaOptionInclude || stringutil.IsLineBreak(rune(sourceFile.Text()[newEnd-1]))) { + if newEnd != node.End() && (TrailingTriviaOption == TrailingTriviaOptionInclude || stringutil.IsLineBreak(rune(sourceFile.Text()[newEnd-1]))) { return newEnd } return node.End() From b465029d5af73b54a129d4aba8f33415961e3989 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 00:11:06 -0800 Subject: [PATCH 23/48] Fix bug in regular tests --- internal/testrunner/test_case_parser.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/testrunner/test_case_parser.go b/internal/testrunner/test_case_parser.go index 42e825809b..e8fbe2de3b 100644 --- a/internal/testrunner/test_case_parser.go +++ b/internal/testrunner/test_case_parser.go @@ -179,8 +179,9 @@ func ParseTestFilesAndSymlinksWithOptions[T any]( // New metadata statement after having collected some code to go with the previous metadata if currentFileName != "" { - if currentFileContent.Len() != 0 { - // Store result file + // Store result file - always save for regular tests, but skip empty implicit first file for fourslash + shouldSaveFile := currentFileContent.Len() != 0 || !options.AllowImplicitFirstFile + if shouldSaveFile { newTestFile, e := parseFile(currentFileName, currentFileContent.String(), currentFileOptions) if e != nil { parseError = e From 6cf1697e7e4f5b28fee57b9c41bef03cb5c28bee Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 00:13:34 -0800 Subject: [PATCH 24/48] Skip more --- internal/fourslash/_scripts/failingTests.txt | 6 ++++++ .../tests/gen/importNameCodeFixConvertTypeOnly1_test.go | 2 +- .../tests/gen/importNameCodeFixOptionalImport0_test.go | 2 +- .../tests/gen/importNameCodeFix_importType4_test.go | 2 +- .../tests/gen/importNameCodeFix_importType8_test.go | 2 +- .../fourslash/tests/gen/importNameCodeFix_pnpm1_test.go | 2 +- .../fourslash/tests/gen/importNameCodeFix_symlink_test.go | 2 +- 7 files changed, 12 insertions(+), 6 deletions(-) diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt index 8ecb6cf018..f1be25c330 100644 --- a/internal/fourslash/_scripts/failingTests.txt +++ b/internal/fourslash/_scripts/failingTests.txt @@ -579,3 +579,9 @@ TestAutoImportCrossProject_symlinks_toSrc TestAutoImportProvider4 TestAutoImportPnpm TestImportFixesGlobalTypingsCache +TestImportNameCodeFix_pnpm1 +TestImportNameCodeFix_importType4 +TestImportNameCodeFix_importType8 +TestImportNameCodeFixOptionalImport0 +TestImportNameCodeFixConvertTypeOnly1 +TestImportNameCodeFix_symlink diff --git a/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go b/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go index 3857963f27..fdf289e16a 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixConvertTypeOnly1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixConvertTypeOnly1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export class A {} diff --git a/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go index 38ad76631d..d6e2f78696 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixOptionalImport0(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: a/f1.ts [|import * as ns from "./foo"; diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go index 616fe3f572..3fadc0f617 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType4_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType4(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @preserveValueImports: true // @isolatedModules: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go b/internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go index 50d43c8152..f239ddfd14 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_importType8_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_importType8(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: es2015 // @verbatimModuleSyntax: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go b/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go index 9967048402..2d91a8fd41 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_pnpm1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_pnpm1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /home/src/workspaces/project/tsconfig.json { "compilerOptions": { "module": "commonjs" } } diff --git a/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go b/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go index 8c3dbe4a11..ca04ad52c6 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_symlink_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_symlink(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @moduleResolution: bundler // @noLib: true From 8b608fd51e20ca1f4977a337befd189719e3f0e5 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 00:21:10 -0800 Subject: [PATCH 25/48] Skip broken tests --- internal/fourslash/fourslash.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index 65f81d1423..e0c7d4b049 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -166,6 +166,9 @@ func NewFourslash(t *testing.T, capabilities *lsproto.ClientCapabilities, conten if compilerOptions.ModuleResolution == core.ModuleResolutionKindClassic { t.Skipf("Test uses deprecated 'moduleResolution: Classic' option") } + if compilerOptions.AllowSyntheticDefaultImports == core.TSFalse { + t.Skipf("Test uses unsupported 'allowSyntheticDefaultImports: false' option") + } inputReader, inputWriter := newLSPPipe() outputReader, outputWriter := newLSPPipe() From 7f7763028425a406d7cc56d7415228d7f4610ab6 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 08:47:22 -0800 Subject: [PATCH 26/48] Fix misported code --- internal/ls/autoimportfixes.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/ls/autoimportfixes.go b/internal/ls/autoimportfixes.go index c68ddc5b11..068931bdd2 100644 --- a/internal/ls/autoimportfixes.go +++ b/internal/ls/autoimportfixes.go @@ -299,7 +299,8 @@ func (ls *LanguageService) getNewImports( topLevelTypeOnly := (defaultImport == nil || needsTypeOnly(defaultImport.addAsTypeOnly)) && core.Every(namedImports, func(i *Import) bool { return needsTypeOnly(i.addAsTypeOnly) }) || (compilerOptions.VerbatimModuleSyntax.IsTrue() || ls.UserPreferences().PreferTypeOnlyAutoImports) && - defaultImport != nil && defaultImport.addAsTypeOnly != AddAsTypeOnlyNotAllowed && !core.Some(namedImports, func(i *Import) bool { return i.addAsTypeOnly == AddAsTypeOnlyNotAllowed }) + (defaultImport == nil || defaultImport.addAsTypeOnly != AddAsTypeOnlyNotAllowed) && + !core.Some(namedImports, func(i *Import) bool { return i.addAsTypeOnly == AddAsTypeOnlyNotAllowed }) var defaultImportNode *ast.Node if defaultImport != nil { From 7d6746deafc395972f422461c50bebadb42cc374 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 09:19:25 -0800 Subject: [PATCH 27/48] Rerun updatefailing --- internal/fourslash/_scripts/failingTests.txt | 175 ++++++++---------- ...CompletionExportEqualsWithDefault1_test.go | 2 +- .../tests/gen/autoImportJsDocImport1_test.go | 2 +- ...ForStringLiteralNonrelativeImport7_test.go | 2 +- ...mpletionsImport_default_symbolName_test.go | 2 +- ...tionsImport_exportEquals_anonymous_test.go | 2 +- .../completionsImport_exportEquals_test.go | 2 +- ...etionsImport_weirdDefaultSynthesis_test.go | 2 +- .../importNameCodeFixExistingImport2_test.go | 2 +- .../importNameCodeFixExistingImport3_test.go | 2 +- .../importNameCodeFixExistingImport5_test.go | 2 +- ...mportNameCodeFixIndentedIdentifier_test.go | 2 +- ...mportExportEqualsCommonJSInteropOn_test.go | 2 +- .../importNameCodeFixUMDGlobalReact1_test.go | 2 +- .../tests/gen/importTypeCompletions5_test.go | 2 +- .../tests/gen/javascriptModules21_test.go | 2 +- 16 files changed, 96 insertions(+), 109 deletions(-) diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt index f1be25c330..d248cafc17 100644 --- a/internal/fourslash/_scripts/failingTests.txt +++ b/internal/fourslash/_scripts/failingTests.txt @@ -4,14 +4,19 @@ TestArgumentsAreAvailableAfterEditsAtEndOfFunction TestAugmentedTypesClass1 TestAugmentedTypesClass3Fourslash TestAutoImportCompletionAmbientMergedModule1 -TestAutoImportCompletionExportEqualsWithDefault1 TestAutoImportCompletionExportListAugmentation1 TestAutoImportCompletionExportListAugmentation2 TestAutoImportCompletionExportListAugmentation3 TestAutoImportCompletionExportListAugmentation4 +TestAutoImportCrossProject_symlinks_stripSrc +TestAutoImportCrossProject_symlinks_toDist +TestAutoImportCrossProject_symlinks_toSrc TestAutoImportFileExcludePatterns3 +TestAutoImportJsDocImport1 TestAutoImportNodeNextJSRequire TestAutoImportPathsAliasesAndBarrels +TestAutoImportPnpm +TestAutoImportProvider4 TestAutoImportProvider_exportMap1 TestAutoImportProvider_exportMap2 TestAutoImportProvider_exportMap3 @@ -23,10 +28,12 @@ TestAutoImportProvider_exportMap8 TestAutoImportProvider_exportMap9 TestAutoImportProvider_globalTypingsCache TestAutoImportProvider_namespaceSameNameAsIntrinsic +TestAutoImportProvider_pnpm TestAutoImportProvider_wildcardExports1 TestAutoImportProvider_wildcardExports2 TestAutoImportProvider_wildcardExports3 TestAutoImportSortCaseSensitivity1 +TestAutoImportSymlinkCaseSensitive TestAutoImportTypeImport1 TestAutoImportTypeImport2 TestAutoImportTypeImport3 @@ -52,16 +59,6 @@ TestCompletionForComputedStringProperties TestCompletionForMetaProperty TestCompletionForObjectProperty TestCompletionForStringLiteral -TestCompletionForStringLiteral_details -TestCompletionForStringLiteral_quotePreference -TestCompletionForStringLiteral_quotePreference1 -TestCompletionForStringLiteral_quotePreference2 -TestCompletionForStringLiteral_quotePreference3 -TestCompletionForStringLiteral_quotePreference4 -TestCompletionForStringLiteral_quotePreference5 -TestCompletionForStringLiteral_quotePreference6 -TestCompletionForStringLiteral_quotePreference7 -TestCompletionForStringLiteral_quotePreference8 TestCompletionForStringLiteral4 TestCompletionForStringLiteralExport TestCompletionForStringLiteralImport1 @@ -74,7 +71,6 @@ TestCompletionForStringLiteralNonrelativeImport18 TestCompletionForStringLiteralNonrelativeImport2 TestCompletionForStringLiteralNonrelativeImport3 TestCompletionForStringLiteralNonrelativeImport4 -TestCompletionForStringLiteralNonrelativeImport7 TestCompletionForStringLiteralNonrelativeImport8 TestCompletionForStringLiteralNonrelativeImport9 TestCompletionForStringLiteralNonrelativeImportTypings1 @@ -84,6 +80,16 @@ TestCompletionForStringLiteralRelativeImport4 TestCompletionForStringLiteralRelativeImport6 TestCompletionForStringLiteralRelativeImportAllowJSTrue TestCompletionForStringLiteralWithDynamicImport +TestCompletionForStringLiteral_details +TestCompletionForStringLiteral_quotePreference +TestCompletionForStringLiteral_quotePreference1 +TestCompletionForStringLiteral_quotePreference2 +TestCompletionForStringLiteral_quotePreference3 +TestCompletionForStringLiteral_quotePreference4 +TestCompletionForStringLiteral_quotePreference5 +TestCompletionForStringLiteral_quotePreference6 +TestCompletionForStringLiteral_quotePreference7 +TestCompletionForStringLiteral_quotePreference8 TestCompletionImportMeta TestCompletionImportMetaWithGlobalDeclaration TestCompletionImportModuleSpecifierEndingDts @@ -121,16 +127,16 @@ TestCompletionListInUnclosedTaggedTemplate02 TestCompletionListInUnclosedTemplate01 TestCompletionListInUnclosedTemplate02 TestCompletionListInvalidMemberNames +TestCompletionListInvalidMemberNames2 TestCompletionListInvalidMemberNames_escapeQuote TestCompletionListInvalidMemberNames_startWithSpace TestCompletionListInvalidMemberNames_withExistingIdentifier -TestCompletionListInvalidMemberNames2 TestCompletionListOfGenericSymbol TestCompletionListOnAliases -TestCompletionListsStringLiteralTypeAsIndexedAccessTypeObject TestCompletionListStringParenthesizedExpression TestCompletionListStringParenthesizedType TestCompletionListWithoutVariableinitializer +TestCompletionListsStringLiteralTypeAsIndexedAccessTypeObject TestCompletionNoAutoInsertQuestionDotForThis TestCompletionNoAutoInsertQuestionDotForTypeParameter TestCompletionNoAutoInsertQuestionDotWithUserPreferencesOff @@ -142,6 +148,7 @@ TestCompletionOfAwaitPromise6 TestCompletionOfAwaitPromise7 TestCompletionOfInterfaceAndVar TestCompletionPreferredSuggestions1 +TestCompletionWithConditionalOperatorMissingColon TestCompletionsAfterJSDoc TestCompletionsBeforeRestArg1 TestCompletionsClassMemberImportTypeNodeParameter1 @@ -151,12 +158,10 @@ TestCompletionsClassMemberImportTypeNodeParameter4 TestCompletionsElementAccessNumeric TestCompletionsExportImport TestCompletionsGenericTypeWithMultipleBases1 +TestCompletionsImportOrExportSpecifier TestCompletionsImport_default_alreadyExistedWithRename TestCompletionsImport_default_anonymous -TestCompletionsImport_default_symbolName TestCompletionsImport_details_withMisspelledName -TestCompletionsImport_exportEquals -TestCompletionsImport_exportEquals_anonymous TestCompletionsImport_exportEquals_global TestCompletionsImport_filteredByInvalidPackageJson_direct TestCompletionsImport_filteredByPackageJson_direct @@ -172,15 +177,13 @@ TestCompletionsImport_named_namespaceImportExists TestCompletionsImport_noSemicolons TestCompletionsImport_packageJsonImportsPreference TestCompletionsImport_quoteStyle -TestCompletionsImport_reExport_wrongName TestCompletionsImport_reExportDefault2 +TestCompletionsImport_reExport_wrongName TestCompletionsImport_require_addToExisting TestCompletionsImport_typeOnly TestCompletionsImport_umdDefaultNoCrash1 TestCompletionsImport_uriStyleNodeCoreModules2 -TestCompletionsImport_weirdDefaultSynthesis TestCompletionsImport_windowsPathsProjectRelative -TestCompletionsImportOrExportSpecifier TestCompletionsInExport TestCompletionsInExport_moduleBlock TestCompletionsInRequire @@ -205,13 +208,13 @@ TestCompletionsOverridingMethod4 TestCompletionsOverridingMethod9 TestCompletionsOverridingMethodCrash1 TestCompletionsOverridingProperties1 +TestCompletionsPathsJsonModule +TestCompletionsPathsRelativeJsonModule TestCompletionsPaths_importType TestCompletionsPaths_kinds TestCompletionsPaths_pathMapping TestCompletionsPaths_pathMapping_nonTrailingWildcard1 TestCompletionsPaths_pathMapping_parentDirectory -TestCompletionsPathsJsonModule -TestCompletionsPathsRelativeJsonModule TestCompletionsRecommended_namespace TestCompletionsRecommended_union TestCompletionsRedeclareModuleAsGlobal @@ -219,10 +222,9 @@ TestCompletionsStringsWithTriggerCharacter TestCompletionsSymbolMembers TestCompletionsTriggerCharacter TestCompletionsTuple -TestCompletionsUniqueSymbol_import TestCompletionsUniqueSymbol1 +TestCompletionsUniqueSymbol_import TestCompletionsWithDeprecatedTag10 -TestCompletionWithConditionalOperatorMissingColon TestConstEnumQuickInfoAndCompletionList TestConstQuickInfoAndCompletionList TestContextuallyTypedFunctionExpressionGeneric1 @@ -233,8 +235,8 @@ TestExportDefaultFunction TestFindAllRefsModuleDotExports TestFindReferencesBindingPatternInJsdocNoCrash1 TestFindReferencesBindingPatternInJsdocNoCrash2 -TestGenericCombinators3 TestGenericCombinatorWithConstraints1 +TestGenericCombinators3 TestGenericFunctionWithGenericParams1 TestGenericInterfacesWithConstraints1 TestGenericTypeWithMultipleBases1MultiFile @@ -258,57 +260,68 @@ TestGetJavaScriptQuickInfo8 TestGetJavaScriptSyntacticDiagnostics24 TestGetOccurrencesIfElseBroken TestHoverOverComment -TestImportCompletions_importsMap1 -TestImportCompletions_importsMap2 -TestImportCompletions_importsMap3 -TestImportCompletions_importsMap4 -TestImportCompletions_importsMap5 TestImportCompletionsPackageJsonExportsSpecifierEndsInTs TestImportCompletionsPackageJsonExportsTrailingSlash1 -TestImportCompletionsPackageJsonImports_ts TestImportCompletionsPackageJsonImportsConditions1 TestImportCompletionsPackageJsonImportsLength1 TestImportCompletionsPackageJsonImportsLength2 TestImportCompletionsPackageJsonImportsPattern +TestImportCompletionsPackageJsonImportsPattern2 TestImportCompletionsPackageJsonImportsPattern_capsInPath1 TestImportCompletionsPackageJsonImportsPattern_capsInPath2 TestImportCompletionsPackageJsonImportsPattern_js_ts TestImportCompletionsPackageJsonImportsPattern_ts TestImportCompletionsPackageJsonImportsPattern_ts_ts -TestImportCompletionsPackageJsonImportsPattern2 -TestImportNameCodeFix_fileWithNoTrailingNewline -TestImportNameCodeFix_HeaderComment1 -TestImportNameCodeFix_HeaderComment2 -TestImportNameCodeFix_importType1 -TestImportNameCodeFix_importType2 -TestImportNameCodeFix_importType7 -TestImportNameCodeFix_jsCJSvsESM3 -TestImportNameCodeFix_order -TestImportNameCodeFix_order2 -TestImportNameCodeFix_trailingComma -TestImportNameCodeFix_withJson +TestImportCompletionsPackageJsonImports_ts +TestImportCompletions_importsMap1 +TestImportCompletions_importsMap2 +TestImportCompletions_importsMap3 +TestImportCompletions_importsMap4 +TestImportCompletions_importsMap5 +TestImportFixesGlobalTypingsCache +TestImportNameCodeFixConvertTypeOnly1 TestImportNameCodeFixExistingImport10 TestImportNameCodeFixExistingImport11 -TestImportNameCodeFixExistingImport2 -TestImportNameCodeFixExistingImport3 TestImportNameCodeFixExistingImport8 TestImportNameCodeFixExistingImport9 TestImportNameCodeFixExistingImportEquals0 TestImportNameCodeFixExportAsDefault -TestImportNameCodeFixIndentedIdentifier TestImportNameCodeFixNewImportAmbient1 TestImportNameCodeFixNewImportAmbient3 -TestImportNameCodeFixNewImportExportEqualsCommonJSInteropOn +TestImportNameCodeFixNewImportBaseUrl0 +TestImportNameCodeFixNewImportBaseUrl1 +TestImportNameCodeFixNewImportBaseUrl2 +TestImportNameCodeFixNewImportFile2 TestImportNameCodeFixNewImportFileQuoteStyle0 TestImportNameCodeFixNewImportFileQuoteStyle1 TestImportNameCodeFixNewImportFileQuoteStyle2 TestImportNameCodeFixNewImportFileQuoteStyleMixed0 TestImportNameCodeFixNewImportFileQuoteStyleMixed1 -TestImportNameCodeFixUMDGlobalReact1 +TestImportNameCodeFixNewImportRootDirs0 +TestImportNameCodeFixNewImportTypeRoots1 +TestImportNameCodeFixOptionalImport0 +TestImportNameCodeFix_HeaderComment1 +TestImportNameCodeFix_HeaderComment2 +TestImportNameCodeFix_avoidRelativeNodeModules +TestImportNameCodeFix_fileWithNoTrailingNewline +TestImportNameCodeFix_importType1 +TestImportNameCodeFix_importType2 +TestImportNameCodeFix_importType4 +TestImportNameCodeFix_importType7 +TestImportNameCodeFix_importType8 +TestImportNameCodeFix_jsCJSvsESM3 +TestImportNameCodeFix_jsx1 +TestImportNameCodeFix_order +TestImportNameCodeFix_order2 +TestImportNameCodeFix_pnpm1 +TestImportNameCodeFix_preferBaseUrl +TestImportNameCodeFix_reExportDefault +TestImportNameCodeFix_symlink +TestImportNameCodeFix_trailingComma +TestImportNameCodeFix_withJson TestImportTypeCompletions1 TestImportTypeCompletions3 TestImportTypeCompletions4 -TestImportTypeCompletions5 TestImportTypeCompletions6 TestImportTypeCompletions7 TestImportTypeCompletions8 @@ -317,10 +330,8 @@ TestIndexerReturnTypes1 TestIndirectClassInstantiation TestInstanceTypesForGenericType1 TestJavascriptModules20 -TestJavascriptModules21 TestJavascriptModulesTypeImport TestJsDocAugments -TestJsdocCallbackTag TestJsDocExtends TestJsDocFunctionSignatures10 TestJsDocFunctionSignatures11 @@ -330,9 +341,6 @@ TestJsDocFunctionSignatures7 TestJsDocFunctionSignatures8 TestJsDocGenerics2 TestJsDocInheritDoc -TestJsdocLink2 -TestJsdocLink3 -TestJsdocLink6 TestJsDocPropertyDescription1 TestJsDocPropertyDescription10 TestJsDocPropertyDescription11 @@ -347,25 +355,31 @@ TestJsDocPropertyDescription8 TestJsDocPropertyDescription9 TestJsDocServices TestJsDocTagsWithHyphen +TestJsFileImportNoTypes2 +TestJsQuickInfoGenerallyAcceptableSize +TestJsRequireQuickInfo +TestJsdocCallbackTag +TestJsdocLink2 +TestJsdocLink3 +TestJsdocLink6 TestJsdocTemplatePrototypeCompletions TestJsdocThrowsTagCompletion TestJsdocTypedefTag TestJsdocTypedefTag2 TestJsdocTypedefTagNamespace TestJsdocTypedefTagServices -TestJsFileImportNoTypes2 -TestJsQuickInfoGenerallyAcceptableSize -TestJsRequireQuickInfo TestLetQuickInfoAndCompletionList TestLocalFunction TestMemberListInReopenedEnum TestMemberListInWithBlock TestMemberListOfExportedClass TestMemberListOnContextualThis +TestModuleNodeNextAutoImport2 +TestModuleNodeNextAutoImport3 TestNgProxy1 -TestNodeModulesImportCompletions1 TestNoQuickInfoForLabel TestNoQuickInfoInWhitespace +TestNodeModulesImportCompletions1 TestNumericPropertyNames TestOverloadQuickInfo TestParameterWithDestructuring @@ -419,14 +433,12 @@ TestPathCompletionsTypesVersionsWildcard4 TestPathCompletionsTypesVersionsWildcard5 TestPathCompletionsTypesVersionsWildcard6 TestProtoVarVisibleWithOuterScopeUnderscoreProto -TestQuickInfo_notInsideComment -TestQuickinfo01 TestQuickInfoAlias TestQuickInfoAssertionNodeNotReusedWhenTypeNotEquivalent1 TestQuickInfoBindingPatternInJsdocNoCrash1 TestQuickInfoClassKeyword -TestQuickInfoContextuallyTypedSignatureOptionalParameterFromIntersection1 TestQuickInfoContextualTyping +TestQuickInfoContextuallyTypedSignatureOptionalParameterFromIntersection1 TestQuickInfoDisplayPartsIife TestQuickInfoElementAccessDeclaration TestQuickInfoForConstTypeReference @@ -439,15 +451,13 @@ TestQuickInfoForGenericTaggedTemplateExpression TestQuickInfoForGetterAndSetter TestQuickInfoForIndexerResultWithConstraint TestQuickInfoForNamedTupleMember -TestQuickinfoForNamespaceMergeWithClassConstrainedToSelf TestQuickInfoForObjectBindingElementPropertyName04 TestQuickInfoForShorthandProperty TestQuickInfoForSyntaxErrorNoError -TestQuickInfoForTypeofParameter TestQuickInfoForTypeParameterInTypeAlias1 TestQuickInfoForTypeParameterInTypeAlias2 +TestQuickInfoForTypeofParameter TestQuickInfoForUMDModuleAlias -TestQuickinfoForUnionProperty TestQuickInfoFromContextualType TestQuickInfoFunctionKeyword TestQuickInfoGenerics @@ -459,10 +469,10 @@ TestQuickInfoInWithBlock TestQuickInfoJSDocBackticks TestQuickInfoJSDocFunctionNew TestQuickInfoJSDocFunctionThis +TestQuickInfoJSExport TestQuickInfoJsDocGetterSetterNoCrash1 TestQuickInfoJsDocNonDiscriminatedUnionSharedProp TestQuickInfoJsdocTypedefMissingType -TestQuickInfoJSExport TestQuickInfoMappedSpreadTypes TestQuickInfoMappedType TestQuickInfoMappedTypeMethods @@ -507,7 +517,6 @@ TestQuickInfoOnUndefined TestQuickInfoOnVarInArrowExpression TestQuickInfoPrivateIdentifierInTypeReferenceNoCrash1 TestQuickInfoPropertyTag -TestQuickInforForSucessiveInferencesIsNotAny TestQuickInfoSignatureOptionalParameterFromUnion1 TestQuickInfoSignatureRestParameterFromUnion1 TestQuickInfoSignatureRestParameterFromUnion2 @@ -520,9 +529,14 @@ TestQuickInfoTypeAliasDefinedInDifferentFile TestQuickInfoTypeError TestQuickInfoTypeOfThisInStatics TestQuickInfoTypeOnlyNamespaceAndClass -TestQuickInfoUnion_discriminated TestQuickInfoUnionOfNamespaces +TestQuickInfoUnion_discriminated TestQuickInfoWidenedTypes +TestQuickInfo_notInsideComment +TestQuickInforForSucessiveInferencesIsNotAny +TestQuickinfo01 +TestQuickinfoForNamespaceMergeWithClassConstrainedToSelf +TestQuickinfoForUnionProperty TestQuickinfoWrongComment TestRecursiveInternalModuleImport TestReferencesForStatementKeywords @@ -558,30 +572,3 @@ TestTsxQuickInfo5 TestTsxQuickInfo6 TestTsxQuickInfo7 TestTypeOperatorNodeBuilding -TestImportNameCodeFix_jsx1 -TestImportNameCodeFix_reExportDefault -TestImportNameCodeFix_preferBaseUrl -TestImportNameCodeFixExistingImport5 -TestImportNameCodeFixNewImportBaseUrl1 -TestImportNameCodeFixNewImportBaseUrl0 -TestImportNameCodeFixNewImportBaseUrl2 -TestImportNameCodeFixNewImportFile2 -TestImportNameCodeFixNewImportTypeRoots1 -TestImportNameCodeFixNewImportRootDirs0 -TestImportNameCodeFix_avoidRelativeNodeModules -TestModuleNodeNextAutoImport2 -TestModuleNodeNextAutoImport3 -TestAutoImportCrossProject_symlinks_toDist -TestAutoImportProvider_pnpm -TestAutoImportCrossProject_symlinks_stripSrc -TestAutoImportSymlinkCaseSensitive -TestAutoImportCrossProject_symlinks_toSrc -TestAutoImportProvider4 -TestAutoImportPnpm -TestImportFixesGlobalTypingsCache -TestImportNameCodeFix_pnpm1 -TestImportNameCodeFix_importType4 -TestImportNameCodeFix_importType8 -TestImportNameCodeFixOptionalImport0 -TestImportNameCodeFixConvertTypeOnly1 -TestImportNameCodeFix_symlink diff --git a/internal/fourslash/tests/gen/autoImportCompletionExportEqualsWithDefault1_test.go b/internal/fourslash/tests/gen/autoImportCompletionExportEqualsWithDefault1_test.go index e5036d3293..c87ea24c91 100644 --- a/internal/fourslash/tests/gen/autoImportCompletionExportEqualsWithDefault1_test.go +++ b/internal/fourslash/tests/gen/autoImportCompletionExportEqualsWithDefault1_test.go @@ -12,7 +12,7 @@ import ( func TestAutoImportCompletionExportEqualsWithDefault1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @strict: true // @module: commonjs diff --git a/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go b/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go index 800437b6a5..38b88edb01 100644 --- a/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go +++ b/internal/fourslash/tests/gen/autoImportJsDocImport1_test.go @@ -9,7 +9,7 @@ import ( func TestAutoImportJsDocImport1(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @verbatimModuleSyntax: true // @target: esnext diff --git a/internal/fourslash/tests/gen/completionForStringLiteralNonrelativeImport7_test.go b/internal/fourslash/tests/gen/completionForStringLiteralNonrelativeImport7_test.go index 59b0088b59..5c6740e18f 100644 --- a/internal/fourslash/tests/gen/completionForStringLiteralNonrelativeImport7_test.go +++ b/internal/fourslash/tests/gen/completionForStringLiteralNonrelativeImport7_test.go @@ -10,7 +10,7 @@ import ( func TestCompletionForStringLiteralNonrelativeImport7(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @baseUrl: tests/cases/fourslash/modules // @Filename: tests/test0.ts diff --git a/internal/fourslash/tests/gen/completionsImport_default_symbolName_test.go b/internal/fourslash/tests/gen/completionsImport_default_symbolName_test.go index 4145b4d095..bae20c6a6d 100644 --- a/internal/fourslash/tests/gen/completionsImport_default_symbolName_test.go +++ b/internal/fourslash/tests/gen/completionsImport_default_symbolName_test.go @@ -12,7 +12,7 @@ import ( func TestCompletionsImport_default_symbolName(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: commonjs // @esModuleInterop: false diff --git a/internal/fourslash/tests/gen/completionsImport_exportEquals_anonymous_test.go b/internal/fourslash/tests/gen/completionsImport_exportEquals_anonymous_test.go index 40d012f3b6..264ddff310 100644 --- a/internal/fourslash/tests/gen/completionsImport_exportEquals_anonymous_test.go +++ b/internal/fourslash/tests/gen/completionsImport_exportEquals_anonymous_test.go @@ -12,7 +12,7 @@ import ( func TestCompletionsImport_exportEquals_anonymous(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @noLib: true // @module: commonjs diff --git a/internal/fourslash/tests/gen/completionsImport_exportEquals_test.go b/internal/fourslash/tests/gen/completionsImport_exportEquals_test.go index 071fb88853..5a1ef9edd0 100644 --- a/internal/fourslash/tests/gen/completionsImport_exportEquals_test.go +++ b/internal/fourslash/tests/gen/completionsImport_exportEquals_test.go @@ -12,7 +12,7 @@ import ( func TestCompletionsImport_exportEquals(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: commonjs // @esModuleInterop: false diff --git a/internal/fourslash/tests/gen/completionsImport_weirdDefaultSynthesis_test.go b/internal/fourslash/tests/gen/completionsImport_weirdDefaultSynthesis_test.go index 463ea288be..5514308ba0 100644 --- a/internal/fourslash/tests/gen/completionsImport_weirdDefaultSynthesis_test.go +++ b/internal/fourslash/tests/gen/completionsImport_weirdDefaultSynthesis_test.go @@ -10,7 +10,7 @@ import ( func TestCompletionsImport_weirdDefaultSynthesis(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @module: commonjs // @esModuleInterop: false diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport2_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport2_test.go index ed6204784c..0602242203 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport2_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport2_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport2(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `import * as ns from "./module"; // Comment diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport3_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport3_test.go index 3d97848208..041f86f0e2 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport3_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport3_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport3(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import d, * as ns from "./module" ; f1/*0*/();|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go b/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go index 707bf1903b..31610760a8 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixExistingImport5_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixExistingImport5(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `[|import "./module"; f1/*0*/();|] diff --git a/internal/fourslash/tests/gen/importNameCodeFixIndentedIdentifier_test.go b/internal/fourslash/tests/gen/importNameCodeFixIndentedIdentifier_test.go index 5785b37c45..b5c0e91aec 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixIndentedIdentifier_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixIndentedIdentifier_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixIndentedIdentifier(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts [|import * as b from "./b"; diff --git a/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsCommonJSInteropOn_test.go b/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsCommonJSInteropOn_test.go index 2fa4d4c865..b058fb5b34 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsCommonJSInteropOn_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixNewImportExportEqualsCommonJSInteropOn_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixNewImportExportEqualsCommonJSInteropOn(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Module: commonjs // @EsModuleInterop: true diff --git a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go index 29d083e101..a4772340ee 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixUMDGlobalReact1_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixUMDGlobalReact1(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @jsx: react // @allowSyntheticDefaultImports: false diff --git a/internal/fourslash/tests/gen/importTypeCompletions5_test.go b/internal/fourslash/tests/gen/importTypeCompletions5_test.go index 543d69aa3f..a05887ff74 100644 --- a/internal/fourslash/tests/gen/importTypeCompletions5_test.go +++ b/internal/fourslash/tests/gen/importTypeCompletions5_test.go @@ -12,7 +12,7 @@ import ( func TestImportTypeCompletions5(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @allowSyntheticDefaultImports: false // @esModuleInterop: false diff --git a/internal/fourslash/tests/gen/javascriptModules21_test.go b/internal/fourslash/tests/gen/javascriptModules21_test.go index 9e73e2b5d2..0f3c99ff0d 100644 --- a/internal/fourslash/tests/gen/javascriptModules21_test.go +++ b/internal/fourslash/tests/gen/javascriptModules21_test.go @@ -12,7 +12,7 @@ import ( func TestJavascriptModules21(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @allowJs: true // @module: system From 21cd3a3040570ac461fbfdd73092a50f3904e454 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 09:30:09 -0800 Subject: [PATCH 28/48] Use existing method --- internal/ast/utilities.go | 12 ------------ internal/checker/checker.go | 4 ++-- internal/ls/codeactions_importfixes.go | 6 +++--- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/internal/ast/utilities.go b/internal/ast/utilities.go index 8a09a01fb6..42ff96ab7f 100644 --- a/internal/ast/utilities.go +++ b/internal/ast/utilities.go @@ -3938,15 +3938,3 @@ func GetFirstConstructorWithBody(node *Node) *Node { } return nil } - -func GetTagNameOfNode(node *Node) *Node { - switch node.Kind { - case KindJsxOpeningElement: - return node.AsJsxOpeningElement().TagName - case KindJsxClosingElement: - return node.AsJsxClosingElement().TagName - case KindJsxSelfClosingElement: - return node.AsJsxSelfClosingElement().TagName - } - panic("Unhandled case in GetTagNameOfNode") -} diff --git a/internal/checker/checker.go b/internal/checker/checker.go index 465360d39b..0c559ef997 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -2859,7 +2859,7 @@ func (c *Checker) getDeprecatedSuggestionNode(node *ast.Node) *ast.Node { case ast.KindTaggedTemplateExpression: return c.getDeprecatedSuggestionNode(node.AsTaggedTemplateExpression().Tag) case ast.KindJsxOpeningElement, ast.KindJsxSelfClosingElement: - return c.getDeprecatedSuggestionNode(ast.GetTagNameOfNode(node)) + return c.getDeprecatedSuggestionNode(node.TagName()) case ast.KindElementAccessExpression: return node.AsElementAccessExpression().ArgumentExpression case ast.KindPropertyAccessExpression: @@ -30351,7 +30351,7 @@ func (c *Checker) hasContextualTypeWithNoGenericTypes(node *ast.Node, checkMode // If check mode has `CheckMode.RestBindingElement`, we skip binding pattern contextual types, // as we want the type of a rest element to be generic when possible. if (ast.IsIdentifier(node) || ast.IsPropertyAccessExpression(node) || ast.IsElementAccessExpression(node)) && - !((ast.IsJsxOpeningElement(node.Parent) || ast.IsJsxSelfClosingElement(node.Parent)) && ast.GetTagNameOfNode(node.Parent) == node) { + !((ast.IsJsxOpeningElement(node.Parent) || ast.IsJsxSelfClosingElement(node.Parent)) && node.Parent.TagName() == node) { contextualType := c.getContextualType(node, core.IfElse(checkMode&CheckModeRestBindingElement != 0, ContextFlagsSkipBindingPatterns, ContextFlagsNone)) if contextualType != nil { return !c.isGenericType(contextualType) diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 3820564cec..4c64ecf23b 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -184,7 +184,7 @@ func getUmdSymbol(token *ast.Node, ch *checker.Checker) *ast.Symbol { // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`. parent := token.Parent - if (ast.IsJsxOpeningLikeElement(parent) && ast.GetTagNameOfNode(parent) == token) || + if (ast.IsJsxOpeningLikeElement(parent) && parent.TagName() == token) || ast.IsJsxOpeningFragment(parent) { var location *ast.Node if ast.IsJsxOpeningLikeElement(parent) { @@ -292,7 +292,7 @@ func getTypeOnlyPromotionFix(ctx context.Context, sourceFile *ast.SourceFile, sy func getSymbolNamesToImport(sourceFile *ast.SourceFile, ch *checker.Checker, symbolToken *ast.Node, compilerOptions *core.CompilerOptions) []string { parent := symbolToken.Parent if (ast.IsJsxOpeningLikeElement(parent) || ast.IsJsxClosingElement(parent)) && - ast.GetTagNameOfNode(parent) == symbolToken && + parent.TagName() == symbolToken && jsxModeNeedsExplicitImport(compilerOptions.Jsx) { jsxNamespace := ch.GetJsxNamespace(sourceFile.AsNode()) if needsJsxNamespaceFix(jsxNamespace, symbolToken, ch) { @@ -686,7 +686,7 @@ func isJSXTagName(node *ast.Node) bool { return false } if ast.IsJsxOpeningLikeElement(parent) || ast.IsJsxClosingElement(parent) { - return ast.GetTagNameOfNode(parent) == node + return parent.TagName() == node } return false } From 818a2e18172034bf2571f0fb35e84723b0118db9 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 09:39:09 -0800 Subject: [PATCH 29/48] refactor to more closely match original code --- internal/ls/autoimports.go | 48 ++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/internal/ls/autoimports.go b/internal/ls/autoimports.go index 7642b31e17..2075de9c76 100644 --- a/internal/ls/autoimports.go +++ b/internal/ls/autoimports.go @@ -911,29 +911,9 @@ func tryUseExistingNamespaceImport(existingImports []*FixAddToExistingImportInfo if existingImport.importKind != ImportKindNamed { continue } - var namespacePrefix string - declaration := existingImport.declaration - switch declaration.Kind { - case ast.KindVariableDeclaration, ast.KindImportEqualsDeclaration: - name := declaration.Name() - if declaration.Kind == ast.KindVariableDeclaration && (name == nil || name.Kind != ast.KindIdentifier) { - continue - } - namespacePrefix = name.Text() - case ast.KindJSDocImportTag, ast.KindImportDeclaration: - importClause := ast.GetImportClauseOfDeclaration(declaration) - if importClause == nil || importClause.NamedBindings == nil || importClause.NamedBindings.Kind != ast.KindNamespaceImport { - continue - } - namespacePrefix = importClause.NamedBindings.Name().Text() - default: - debug.AssertNever(declaration) - } - if namespacePrefix == "" { - continue - } - moduleSpecifier := checker.TryGetModuleSpecifierFromDeclaration(declaration) - if moduleSpecifier != nil && moduleSpecifier.Text() != "" { + namespacePrefix := getNamespaceLikeImportText(existingImport.declaration) + moduleSpecifier := checker.TryGetModuleSpecifierFromDeclaration(existingImport.declaration) + if namespacePrefix != "" && moduleSpecifier != nil && moduleSpecifier.Text() != "" { return getUseNamespaceImport( moduleSpecifier.Text(), modulespecifiers.ResultKindNone, @@ -945,6 +925,28 @@ func tryUseExistingNamespaceImport(existingImports []*FixAddToExistingImportInfo return nil } +func getNamespaceLikeImportText(declaration *ast.Statement) string { + switch declaration.Kind { + case ast.KindVariableDeclaration: + name := declaration.Name() + if name != nil && name.Kind == ast.KindIdentifier { + return name.Text() + } + return "" + case ast.KindImportEqualsDeclaration: + return declaration.Name().Text() + case ast.KindJSDocImportTag, ast.KindImportDeclaration: + importClause := ast.GetImportClauseOfDeclaration(declaration) + if importClause != nil && importClause.NamedBindings != nil && importClause.NamedBindings.Kind == ast.KindNamespaceImport { + return importClause.NamedBindings.Name().Text() + } + return "" + default: + debug.AssertNever(declaration) + return "" + } +} + func tryAddToExistingImport(existingImports []*FixAddToExistingImportInfo, isValidTypeOnlyUseSite *bool, ch *checker.Checker, compilerOptions *core.CompilerOptions) *ImportFix { var best *ImportFix From 610a47054f8a732ead534e9cfb33f80c01fd6e4b Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 09:49:51 -0800 Subject: [PATCH 30/48] Remove not needed helper --- internal/ast/utilities.go | 18 ------------------ internal/ls/autoimports.go | 10 +++++----- 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/internal/ast/utilities.go b/internal/ast/utilities.go index 42ff96ab7f..3d62afa286 100644 --- a/internal/ast/utilities.go +++ b/internal/ast/utilities.go @@ -1411,24 +1411,6 @@ func GetNameOfDeclaration(declaration *Node) *Node { return nil } -func GetImportClauseOfDeclaration(declaration *Declaration) *ImportClause { - switch declaration.Kind { - case KindImportDeclaration: - importDecl := declaration.AsImportDeclaration() - if importDecl.ImportClause == nil { - return nil - } - return importDecl.ImportClause.AsImportClause() - case KindJSDocImportTag: - jsDocImport := declaration.AsJSDocImportTag() - if jsDocImport.ImportClause == nil { - return nil - } - return jsDocImport.ImportClause.AsImportClause() - } - return nil -} - func GetNonAssignedNameOfDeclaration(declaration *Node) *Node { // !!! switch declaration.Kind { diff --git a/internal/ls/autoimports.go b/internal/ls/autoimports.go index 2075de9c76..3df5564413 100644 --- a/internal/ls/autoimports.go +++ b/internal/ls/autoimports.go @@ -936,9 +936,9 @@ func getNamespaceLikeImportText(declaration *ast.Statement) string { case ast.KindImportEqualsDeclaration: return declaration.Name().Text() case ast.KindJSDocImportTag, ast.KindImportDeclaration: - importClause := ast.GetImportClauseOfDeclaration(declaration) - if importClause != nil && importClause.NamedBindings != nil && importClause.NamedBindings.Kind == ast.KindNamespaceImport { - return importClause.NamedBindings.Name().Text() + importClause := declaration.ImportClause() + if importClause != nil && importClause.AsImportClause().NamedBindings != nil && importClause.AsImportClause().NamedBindings.Kind == ast.KindNamespaceImport { + return importClause.AsImportClause().NamedBindings.Name().Text() } return "" default: @@ -992,11 +992,11 @@ func (info *FixAddToExistingImportInfo) getAddToExistingImportFix(isValidTypeOnl return nil } - importClause := ast.GetImportClauseOfDeclaration(info.declaration) + importClause := info.declaration.ImportClause() if importClause == nil || !ast.IsStringLiteralLike(info.declaration.ModuleSpecifier()) { return nil } - namedBindings := importClause.NamedBindings + namedBindings := importClause.AsImportClause().NamedBindings // A type-only import may not have both a default and named imports, so the only way a name can // be added to an existing type-only import is adding a named import to existing named bindings. if importClause.IsTypeOnly() && !(info.importKind == ImportKindNamed && namedBindings != nil) { From 4fa6f947b1c568d8a487d5320936f7eec4e0b857 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 09:52:10 -0800 Subject: [PATCH 31/48] Remove rando added lsutils package file --- internal/ls/autoimportfixes.go | 13 ++++++++++++- internal/ls/lsutil/importhelpers.go | 19 ------------------- 2 files changed, 12 insertions(+), 20 deletions(-) delete mode 100644 internal/ls/lsutil/importhelpers.go diff --git a/internal/ls/autoimportfixes.go b/internal/ls/autoimportfixes.go index 068931bdd2..045d7e50a5 100644 --- a/internal/ls/autoimportfixes.go +++ b/internal/ls/autoimportfixes.go @@ -179,7 +179,7 @@ func (ls *LanguageService) doAddExistingFix( if promoteFromTypeOnly { // Delete the 'type' keyword from the import clause - typeKeyword := lsutil.GetTypeKeywordOfTypeOnlyImport(importClause, sourceFile) + typeKeyword := getTypeKeywordOfTypeOnlyImport(importClause, sourceFile) ct.Delete(sourceFile, typeKeyword) // Add 'type' modifier to existing specifiers (not newly added ones) @@ -198,6 +198,17 @@ func (ls *LanguageService) doAddExistingFix( } } +func getTypeKeywordOfTypeOnlyImport(importClause *ast.ImportClause, sourceFile *ast.SourceFile) *ast.Node { + debug.Assert(importClause.IsTypeOnly(), "import clause must be type-only") + // The first child of a type-only import clause is the 'type' keyword + // import type { foo } from './bar' + // ^^^^ + typeKeyword := astnav.FindChildOfKind(importClause.AsNode(), ast.KindTypeKeyword, sourceFile) + debug.Assert(typeKeyword != nil, "type-only import clause should have a type keyword") + return typeKeyword +} + + func addElementToBindingPattern(ct *change.Tracker, sourceFile *ast.SourceFile, bindingPattern *ast.Node, name string, propertyName *string) { element := newBindingElementFromNameAndPropertyName(ct, name, propertyName) if len(bindingPattern.Elements()) > 0 { diff --git a/internal/ls/lsutil/importhelpers.go b/internal/ls/lsutil/importhelpers.go deleted file mode 100644 index c4cec30384..0000000000 --- a/internal/ls/lsutil/importhelpers.go +++ /dev/null @@ -1,19 +0,0 @@ -package lsutil - -import ( - "github.com/microsoft/typescript-go/internal/ast" - "github.com/microsoft/typescript-go/internal/astnav" - "github.com/microsoft/typescript-go/internal/debug" -) - -// GetTypeKeywordOfTypeOnlyImport returns the 'type' keyword token from a type-only import clause. -// This is equivalent to TypeScript's getTypeKeywordOfTypeOnlyImport helper. -func GetTypeKeywordOfTypeOnlyImport(importClause *ast.ImportClause, sourceFile *ast.SourceFile) *ast.Node { - debug.Assert(importClause.IsTypeOnly(), "import clause must be type-only") - // The first child of a type-only import clause is the 'type' keyword - // import type { foo } from './bar' - // ^^^^ - typeKeyword := astnav.FindChildOfKind(importClause.AsNode(), ast.KindTypeKeyword, sourceFile) - debug.Assert(typeKeyword != nil, "type-only import clause should have a type keyword") - return typeKeyword -} From 4d309bf7459f9ffc101e1f42181d25b4983ed04d Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 09:55:01 -0800 Subject: [PATCH 32/48] Drop rando comments about porting --- internal/ls/codeactions_importfixes.go | 30 +------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 4c64ecf23b..71f7ac0694 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -23,7 +23,6 @@ import ( "github.com/microsoft/typescript-go/internal/tspath" ) -// Import fix diagnostic codes (from importFixes.ts errorCodes) var importFixErrorCodes = []int32{ diagnostics.Cannot_find_name_0.Code(), diagnostics.Cannot_find_name_0_Did_you_mean_1.Code(), @@ -52,14 +51,13 @@ const ( importFixID = "fixMissingImport" ) -// ImportFixProvider is the CodeFixProvider for import-related fixes (registerCodeFix in importFixes.ts) +// ImportFixProvider is the CodeFixProvider for import-related fixes var ImportFixProvider = &CodeFixProvider{ ErrorCodes: importFixErrorCodes, GetCodeActions: getImportCodeActions, FixIds: []string{importFixID}, } -// fixInfo represents information about a single fix (from importFixes.ts) type fixInfo struct { fix *ImportFix symbolName string @@ -67,7 +65,6 @@ type fixInfo struct { isJsxNamespaceFix bool } -// getImportCodeActions generates import code actions (from registerCodeFix getCodeActions in importFixes.ts) func getImportCodeActions(ctx context.Context, fixContext *CodeFixContext) []CodeAction { info := getFixInfos(ctx, fixContext, fixContext.ErrorCode, fixContext.Span.Pos(), true /* useAutoImportProvider */) if len(info) == 0 { @@ -84,7 +81,6 @@ func getImportCodeActions(ctx context.Context, fixContext *CodeFixContext) []Cod return actions } -// getFixInfos gets all fix information for the given context (from importFixes.ts) func getFixInfos(ctx context.Context, fixContext *CodeFixContext, errorCode int32, pos int, useAutoImportProvider bool) []*fixInfo { symbolToken := astnav.GetTokenAtPosition(fixContext.SourceFile, pos) @@ -117,7 +113,6 @@ func getFixInfos(ctx context.Context, fixContext *CodeFixContext, errorCode int3 return sortFixInfo(info, fixContext) } -// getFixesInfoForUMDImport gets fixes for UMD imports (from importFixes.ts) func getFixesInfoForUMDImport(ctx context.Context, fixContext *CodeFixContext, token *ast.Node) []*fixInfo { ch, done := fixContext.Program.GetTypeChecker(ctx) defer done() @@ -171,7 +166,6 @@ func getFixesInfoForUMDImport(ctx context.Context, fixContext *CodeFixContext, t return result } -// getUmdSymbol tries to get the UMD symbol from a token (from importFixes.ts) func getUmdSymbol(token *ast.Node, ch *checker.Checker) *ast.Symbol { // try the identifier to see if it is the umd symbol var umdSymbol *ast.Symbol @@ -201,14 +195,12 @@ func getUmdSymbol(token *ast.Node, ch *checker.Checker) *ast.Symbol { return nil } -// isUMDExportSymbol checks if a symbol is a UMD export (from checker/symbolaccessibility.go) func isUMDExportSymbol(symbol *ast.Symbol) bool { return symbol != nil && len(symbol.Declarations) > 0 && symbol.Declarations[0] != nil && ast.IsNamespaceExportDeclaration(symbol.Declarations[0]) } -// getFixesInfoForNonUMDImport gets fixes for non-UMD imports (from importFixes.ts) func getFixesInfoForNonUMDImport(ctx context.Context, fixContext *CodeFixContext, symbolToken *ast.Node, useAutoImportProvider bool) []*fixInfo { ch, done := fixContext.Program.GetTypeChecker(ctx) defer done() @@ -265,7 +257,6 @@ func getFixesInfoForNonUMDImport(ctx context.Context, fixContext *CodeFixContext return allInfo } -// getTypeOnlyPromotionFix gets a fix for promoting a type-only import (from importFixes.ts) func getTypeOnlyPromotionFix(ctx context.Context, sourceFile *ast.SourceFile, symbolToken *ast.Node, symbolName string, program *compiler.Program) *ImportFix { ch, done := program.GetTypeChecker(ctx) defer done() @@ -288,7 +279,6 @@ func getTypeOnlyPromotionFix(ctx context.Context, sourceFile *ast.SourceFile, sy } } -// getSymbolNamesToImport gets the symbol names to import (from importFixes.ts) func getSymbolNamesToImport(sourceFile *ast.SourceFile, ch *checker.Checker, symbolToken *ast.Node, compilerOptions *core.CompilerOptions) []string { parent := symbolToken.Parent if (ast.IsJsxOpeningLikeElement(parent) || ast.IsJsxClosingElement(parent)) && @@ -307,7 +297,6 @@ func getSymbolNamesToImport(sourceFile *ast.SourceFile, ch *checker.Checker, sym return []string{symbolToken.Text()} } -// needsJsxNamespaceFix checks if JSX namespace fix is needed (from importFixes.ts) func needsJsxNamespaceFix(jsxNamespace string, symbolToken *ast.Node, ch *checker.Checker) bool { if scanner.IsIntrinsicJsxName(symbolToken.Text()) { return true @@ -323,12 +312,10 @@ func needsJsxNamespaceFix(jsxNamespace string, symbolToken *ast.Node, ch *checke return false } -// jsxModeNeedsExplicitImport checks if JSX mode needs explicit import (from importFixes.ts) func jsxModeNeedsExplicitImport(jsx core.JsxEmit) bool { return jsx == core.JsxEmitReact || jsx == core.JsxEmitReactNative } -// getExportInfos searches for exports (from importFixes.ts) func getExportInfos( ctx context.Context, symbolName string, @@ -410,9 +397,6 @@ func getExportInfos( return originalSymbolToExportInfos } -// symbolFlagsHaveMeaning already exists in utilities.go - -// getImportFixes gets import fixes for export infos (from importFixes.ts getImportFixes) type importFixesResult struct { fixes []*ImportFix computedWithoutCacheCount int @@ -499,13 +483,11 @@ func getImportFixes( } } -// shouldUseRequire determines if require should be used (from importFixes.ts) func shouldUseRequire(sourceFile *ast.SourceFile, program *compiler.Program) bool { // Delegate to the existing implementation in autoimports.go return getShouldUseRequire(sourceFile, program) } -// codeActionForFix creates a code action for a fix (from importFixes.ts codeActionForFix) func codeActionForFix(ctx context.Context, fixContext *CodeFixContext, info *fixInfo) *CodeAction { // Create a tracker with format options and converters from LanguageService tracker := change.NewTracker(ctx, fixContext.Program.Options(), fixContext.LS.FormatOptions(), fixContext.LS.converters) @@ -538,7 +520,6 @@ func codeActionForFix(ctx context.Context, fixContext *CodeFixContext, info *fix } } -// codeActionForFixWorker generates changes for a fix (from importFixes.ts codeActionForFixWorker) func codeActionForFixWorker( ctx context.Context, changes *change.Tracker, @@ -677,9 +658,6 @@ func codeActionForFixWorker( } } -// getMeaningFromLocation already exists in utilities.go - -// isJSXTagName checks if a node is a JSX tag name func isJSXTagName(node *ast.Node) bool { parent := node.Parent if parent == nil { @@ -738,7 +716,6 @@ func getImportClauseOfSpecifier(spec *ast.ImportSpecifier) *ast.ImportClause { return nil } -// sortFixInfo sorts fixes by preference (from importFixes.ts sortFixInfo) func sortFixInfo(fixes []*fixInfo, fixContext *CodeFixContext) []*fixInfo { if len(fixes) == 0 { return fixes @@ -773,7 +750,6 @@ func sortFixInfo(fixes []*fixInfo, fixContext *CodeFixContext) []*fixInfo { return sorted } -// compareModuleSpecifiers compares two import fixes by their module specifiers (from importFixes.ts) func compareModuleSpecifiers( a, b *ImportFix, sourceFile *ast.SourceFile, @@ -834,7 +810,6 @@ func compareModuleSpecifiers( return strings.Compare(a.moduleSpecifier, b.moduleSpecifier) } -// promoteFromTypeOnly promotes a type-only import to a regular import (from importFixes.ts) func promoteFromTypeOnly( changes *change.Tracker, aliasDeclaration *ast.Declaration, @@ -1116,7 +1091,6 @@ func tryGetModuleSpecifierFromDeclaration(node *ast.Node) *ast.Node { return nil } -// replaceStringLiteral replaces a string literal with a new text value (from importFixes.ts) func replaceStringLiteral(changes *change.Tracker, sourceFile *ast.SourceFile, stringLiteral *ast.Node, newText string) { // Get the position of the string literal content (excluding quotes) literalStart := stringLiteral.Pos() @@ -1139,7 +1113,6 @@ func replaceStringLiteral(changes *change.Tracker, sourceFile *ast.SourceFile, s }, newLiteral) } -// insertTypeModifierBefore inserts the 'type' keyword before an import specifier (from importFixes.ts) func insertTypeModifierBefore(changes *change.Tracker, sourceFile *ast.SourceFile, specifier *ast.Node) { // Insert "type " before the specifier // import { foo } => import { type foo } @@ -1152,7 +1125,6 @@ func insertTypeModifierBefore(changes *change.Tracker, sourceFile *ast.SourceFil changes.InsertText(sourceFile, lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, "type ") } -// deleteNode deletes a node from a list (from importFixes.ts) func deleteNode(changes *change.Tracker, sourceFile *ast.SourceFile, node *ast.Node, containingList []*ast.Node) { // Find the node in the list to determine if we need to delete a comma nodeIndex := -1 From 3b2df7a55da1a480752602c0b95eca8fbab6eb70 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 10:01:40 -0800 Subject: [PATCH 33/48] Remove redundant stuff, oops --- internal/ls/codeactions_importfixes.go | 135 +++---------------------- 1 file changed, 13 insertions(+), 122 deletions(-) diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 71f7ac0694..21df810ff2 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -415,71 +415,27 @@ func getImportFixes( ch, done := program.GetTypeChecker(ctx) defer done() - // Create import map of existing imports - importMap := createExistingImportMap(sourceFile, program, ch) - - // Get existing imports that could be extended - var existingImports []*FixAddToExistingImportInfo - for _, exportInfo := range exportInfos { - existingForExport := importMap.getImportsForExportInfo(exportInfo) - existingImports = append(existingImports, existingForExport...) - } - - // Try to use existing namespace import - var useNamespace *ImportFix - if usagePosition != nil { - // Convert text position to LSP position - line, character := scanner.GetECMALineAndCharacterOfPosition(sourceFile, *usagePosition) - useNamespace = tryUseExistingNamespaceImport(existingImports, lsproto.Position{ - Line: uint32(line), - Character: uint32(character), - }) - } - - // Try to add to existing import - addToExisting := tryAddToExistingImport(existingImports, &isValidTypeOnlyUseSite, ch, program.Options()) - - if addToExisting != nil { - // Don't bother providing an action to add a new import if we can add to an existing one. - fixes := []*ImportFix{} - if useNamespace != nil { - fixes = append(fixes, useNamespace) - } - fixes = append(fixes, addToExisting) - return &importFixesResult{ - fixes: fixes, - computedWithoutCacheCount: 0, - } - } - - // Get fixes for adding new imports using the existing implementation + // Convert text position to LSP position if provided var usagePos *lsproto.Position if usagePosition != nil { line, character := scanner.GetECMALineAndCharacterOfPosition(sourceFile, *usagePosition) usagePos = &lsproto.Position{Line: uint32(line), Character: uint32(character)} } - // Call getFixesForAddImport which has full module specifier caching support - newImportFixes := ls.getFixesForAddImport( + // Call the existing LanguageService method + computedWithoutCacheCount, fixes := ls.getImportFixes( ch, exportInfos, - existingImports, - sourceFile, usagePos, - isValidTypeOnlyUseSite, - useRequire, + &isValidTypeOnlyUseSite, + &useRequire, + sourceFile, false, // fromCacheOnly ) - fixes := []*ImportFix{} - if useNamespace != nil { - fixes = append(fixes, useNamespace) - } - fixes = append(fixes, newImportFixes...) - return &importFixesResult{ fixes: fixes, - computedWithoutCacheCount: 0, + computedWithoutCacheCount: computedWithoutCacheCount, } } @@ -627,7 +583,7 @@ func codeActionForFixWorker( } // Insert the import statements - insertImports(changes, sourceFile, statements, program, ls) + ls.insertImports(changes, sourceFile, statements, true /* blankLineBetween */) // Add namespace qualification if needed if fix.qualification() != nil { @@ -744,13 +700,15 @@ func sortFixInfo(fixes []*fixInfo, fixContext *CodeFixContext) []*fixInfo { } // Compare module specifiers - return compareModuleSpecifiers(a.fix, b.fix, fixContext.SourceFile, fixContext.Program, packageJsonFilter, fixContext.LS) + return compareModuleSpecifiersForCodeFixes(a.fix, b.fix, fixContext.SourceFile, fixContext.Program, packageJsonFilter, fixContext.LS) }) return sorted } -func compareModuleSpecifiers( +// compareModuleSpecifiersForCodeFixes compares module specifiers specifically for code fix actions. +// This is similar to but distinct from (*LanguageService).compareModuleSpecifiers used in auto-imports. +func compareModuleSpecifiersForCodeFixes( a, b *ImportFix, sourceFile *ast.SourceFile, program *compiler.Program, @@ -895,7 +853,7 @@ func promoteImportClause( // Handle .ts extension conversion to .js if necessary compilerOptions := program.Options() if compilerOptions.AllowImportingTsExtensions.IsFalse() { - moduleSpecifier := tryGetModuleSpecifierFromDeclaration(importClause.Parent) + moduleSpecifier := checker.TryGetModuleSpecifierFromDeclaration(importClause.Parent) if moduleSpecifier != nil { resolvedModule := program.GetResolvedModuleFromModuleSpecifier(sourceFile, moduleSpecifier) if resolvedModule != nil && resolvedModule.ResolvedUsingTsExtension { @@ -1181,70 +1139,3 @@ func deleteNode(changes *change.Tracker, sourceFile *ast.SourceFile, node *ast.N End: lsproto.Position{Line: uint32(endLine), Character: uint32(endChar)}, }, "") } - -// insertImports inserts new import statements in the correct position relative to existing imports -// (from utilities.ts insertImports) -func insertImports( - changes *change.Tracker, - sourceFile *ast.SourceFile, - imports []*ast.Statement, - program *compiler.Program, - ls *LanguageService, -) { - if len(imports) == 0 { - return - } - - // Find existing import statements - var existingImportStatements []*ast.Statement - for _, stmt := range sourceFile.Statements.Nodes { - if ast.IsAnyImportSyntax(stmt) || ast.IsRequireVariableStatement(stmt) { - existingImportStatements = append(existingImportStatements, stmt) - } - } - - // If no existing imports, insert at top of file - if len(existingImportStatements) == 0 { - changes.InsertAtTopOfFile(sourceFile, imports, true /* blankLineBetween */) - return - } - - // Get comparer and check if imports are sorted - comparer, isSorted := organizeimports.GetOrganizeImportsStringComparerWithDetection( - existingImportStatements, - ls.UserPreferences(), - ) - - // Sort the new imports - sortedNewImports := make([]*ast.Statement, len(imports)) - copy(sortedNewImports, imports) - slices.SortFunc(sortedNewImports, func(a, b *ast.Statement) int { - return organizeimports.CompareImportsOrRequireStatements(a, b, comparer) - }) - - // If existing imports are sorted, insert each new import in the correct position - if isSorted { - for _, newImport := range sortedNewImports { - insertionIndex := organizeimports.GetImportDeclarationInsertIndex( - existingImportStatements, - newImport, - func(a, b *ast.Statement) int { - return organizeimports.CompareImportsOrRequireStatements(a, b, comparer) - }, - ) - - if insertionIndex == 0 { - // Insert before the first import - changes.InsertNodeBefore(sourceFile, existingImportStatements[0], newImport, false /* blankLineBetween */) - } else { - // Insert after the previous import - prevImport := existingImportStatements[insertionIndex-1] - changes.InsertNodeAfter(sourceFile, prevImport, newImport) - } - } - } else { - // Imports are not sorted, insert after the last existing import - lastImport := existingImportStatements[len(existingImportStatements)-1] - changes.InsertNodesAfter(sourceFile, lastImport, sortedNewImports) - } -} From 6a4ce43aee31281cc9bcefb99c2cb0e57ec2f5b4 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 10:06:32 -0800 Subject: [PATCH 34/48] No, it really was a dupe, and fix a misport --- internal/ls/autoimports.go | 39 +++++++------- internal/ls/codeactions_importfixes.go | 71 +++----------------------- 2 files changed, 26 insertions(+), 84 deletions(-) diff --git a/internal/ls/autoimports.go b/internal/ls/autoimports.go index 3df5564413..39bbcc2a6b 100644 --- a/internal/ls/autoimports.go +++ b/internal/ls/autoimports.go @@ -581,26 +581,25 @@ func (l *LanguageService) compareModuleSpecifiers( allowsImportingSpecifier func(specifier string) bool, toPath func(fileName string) tspath.Path, ) int { - if a.kind == ImportFixKindUseNamespace || b.kind == ImportFixKindUseNamespace { - return 0 - } - if comparison := core.CompareBooleans( - b.moduleSpecifierKind != modulespecifiers.ResultKindNodeModules || allowsImportingSpecifier(b.moduleSpecifier), - a.moduleSpecifierKind != modulespecifiers.ResultKindNodeModules || allowsImportingSpecifier(a.moduleSpecifier), - ); comparison != 0 { - return comparison - } - if comparison := compareModuleSpecifierRelativity(a, b, l.UserPreferences()); comparison != 0 { - return comparison - } - if comparison := compareNodeCoreModuleSpecifiers(a.moduleSpecifier, b.moduleSpecifier, importingFile, l.GetProgram()); comparison != 0 { - return comparison - } - if comparison := core.CompareBooleans(isFixPossiblyReExportingImportingFile(a, importingFile.Path(), toPath), isFixPossiblyReExportingImportingFile(b, importingFile.Path(), toPath)); comparison != 0 { - return comparison - } - if comparison := tspath.CompareNumberOfDirectorySeparators(a.moduleSpecifier, b.moduleSpecifier); comparison != 0 { - return comparison + if a.kind != ImportFixKindUseNamespace && b.kind != ImportFixKindUseNamespace { + if comparison := core.CompareBooleans( + b.moduleSpecifierKind != modulespecifiers.ResultKindNodeModules || allowsImportingSpecifier(b.moduleSpecifier), + a.moduleSpecifierKind != modulespecifiers.ResultKindNodeModules || allowsImportingSpecifier(a.moduleSpecifier), + ); comparison != 0 { + return comparison + } + if comparison := compareModuleSpecifierRelativity(a, b, l.UserPreferences()); comparison != 0 { + return comparison + } + if comparison := compareNodeCoreModuleSpecifiers(a.moduleSpecifier, b.moduleSpecifier, importingFile, l.GetProgram()); comparison != 0 { + return comparison + } + if comparison := core.CompareBooleans(isFixPossiblyReExportingImportingFile(a, importingFile.Path(), toPath), isFixPossiblyReExportingImportingFile(b, importingFile.Path(), toPath)); comparison != 0 { + return comparison + } + if comparison := tspath.CompareNumberOfDirectorySeparators(a.moduleSpecifier, b.moduleSpecifier); comparison != 0 { + return comparison + } } return 0 } diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 21df810ff2..042eb195ff 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -17,7 +17,6 @@ import ( "github.com/microsoft/typescript-go/internal/ls/change" "github.com/microsoft/typescript-go/internal/ls/organizeimports" "github.com/microsoft/typescript-go/internal/lsp/lsproto" - "github.com/microsoft/typescript-go/internal/modulespecifiers" "github.com/microsoft/typescript-go/internal/outputpaths" "github.com/microsoft/typescript-go/internal/scanner" "github.com/microsoft/typescript-go/internal/tspath" @@ -700,74 +699,18 @@ func sortFixInfo(fixes []*fixInfo, fixContext *CodeFixContext) []*fixInfo { } // Compare module specifiers - return compareModuleSpecifiersForCodeFixes(a.fix, b.fix, fixContext.SourceFile, fixContext.Program, packageJsonFilter, fixContext.LS) + return fixContext.LS.compareModuleSpecifiers( + a.fix, + b.fix, + fixContext.SourceFile, + packageJsonFilter.allowsImportingSpecifier, + func(fileName string) tspath.Path { return tspath.Path(fileName) }, + ) }) return sorted } -// compareModuleSpecifiersForCodeFixes compares module specifiers specifically for code fix actions. -// This is similar to but distinct from (*LanguageService).compareModuleSpecifiers used in auto-imports. -func compareModuleSpecifiersForCodeFixes( - a, b *ImportFix, - sourceFile *ast.SourceFile, - program *compiler.Program, - packageJsonFilter *packageJsonImportFilter, - ls *LanguageService, -) int { - // For UseNamespace and AddToExisting, no further comparison needed - if a.kind == ImportFixKindUseNamespace || a.kind == ImportFixKindAddToExisting { - return 0 - } - if b.kind == ImportFixKindUseNamespace || b.kind == ImportFixKindAddToExisting { - return 0 - } - - // Compare package.json filtering - prefer imports allowed by package.json - if cmp := core.CompareBooleans( - b.moduleSpecifierKind != modulespecifiers.ResultKindNodeModules || packageJsonFilter.allowsImportingSpecifier(b.moduleSpecifier), - a.moduleSpecifierKind != modulespecifiers.ResultKindNodeModules || packageJsonFilter.allowsImportingSpecifier(a.moduleSpecifier), - ); cmp != 0 { - return cmp - } - - // Compare relativity based on user preferences - preferences := ls.UserPreferences() - switch preferences.ImportModuleSpecifierPreference { - case modulespecifiers.ImportModuleSpecifierPreferenceNonRelative, modulespecifiers.ImportModuleSpecifierPreferenceProjectRelative: - if cmp := core.CompareBooleans( - a.moduleSpecifierKind == modulespecifiers.ResultKindRelative, - b.moduleSpecifierKind == modulespecifiers.ResultKindRelative, - ); cmp != 0 { - return cmp - } - } - - // Compare node: prefix - prefer based on shouldUseUriStyleNodeCoreModules - if cmp := compareNodeCoreModuleSpecifiers(a.moduleSpecifier, b.moduleSpecifier, sourceFile, program); cmp != 0 { - return cmp - } - - // Compare re-export detection - avoid potential import cycles from barrel re-exports - toPath := func(fileName string) tspath.Path { - // Simple conversion - in real implementation this would use proper path resolution - return tspath.Path(fileName) - } - aIsReExport := isFixPossiblyReExportingImportingFile(a, sourceFile.Path(), toPath) - bIsReExport := isFixPossiblyReExportingImportingFile(b, sourceFile.Path(), toPath) - if cmp := core.CompareBooleans(aIsReExport, bIsReExport); cmp != 0 { - return cmp - } - - // Compare number of directory separators - prefer shorter paths - if cmp := tspath.CompareNumberOfDirectorySeparators(a.moduleSpecifier, b.moduleSpecifier); cmp != 0 { - return cmp - } - - // Final tiebreaker: lexicographic comparison - return strings.Compare(a.moduleSpecifier, b.moduleSpecifier) -} - func promoteFromTypeOnly( changes *change.Tracker, aliasDeclaration *ast.Declaration, From 00194012768e8119c50e74a68d18dd40912c8751 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 10:09:17 -0800 Subject: [PATCH 35/48] Yay, more stuff was fixed by this --- internal/fourslash/_scripts/failingTests.txt | 2 -- .../fourslash/tests/gen/importNameCodeFix_jsCJSvsESM3_test.go | 2 +- .../tests/gen/importNameCodeFix_reExportDefault_test.go | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt index d248cafc17..89e2b095f4 100644 --- a/internal/fourslash/_scripts/failingTests.txt +++ b/internal/fourslash/_scripts/failingTests.txt @@ -309,13 +309,11 @@ TestImportNameCodeFix_importType2 TestImportNameCodeFix_importType4 TestImportNameCodeFix_importType7 TestImportNameCodeFix_importType8 -TestImportNameCodeFix_jsCJSvsESM3 TestImportNameCodeFix_jsx1 TestImportNameCodeFix_order TestImportNameCodeFix_order2 TestImportNameCodeFix_pnpm1 TestImportNameCodeFix_preferBaseUrl -TestImportNameCodeFix_reExportDefault TestImportNameCodeFix_symlink TestImportNameCodeFix_trailingComma TestImportNameCodeFix_withJson diff --git a/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM3_test.go b/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM3_test.go index 99ab3b76b6..7006d6b90a 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM3_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_jsCJSvsESM3_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_jsCJSvsESM3(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @allowJs: true // @checkJs: true diff --git a/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go b/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go index 8a99b77559..c5b775e568 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_reExportDefault(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /user.ts foo; From 0ba0e5e9ef90c531b6b15a9ea410aeaef9a580cb Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 10:11:27 -0800 Subject: [PATCH 36/48] Dead code --- internal/ls/codeactions_importfixes.go | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 042eb195ff..0cf0bc2255 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -968,30 +968,6 @@ func deleteTypeKeywordFromImportEquals(changes *change.Tracker, sourceFile *ast. }, "") } -// tryGetModuleSpecifierFromDeclaration tries to get the module specifier from a declaration (from utilities.ts) -func tryGetModuleSpecifierFromDeclaration(node *ast.Node) *ast.Node { - if node == nil { - return nil - } - - switch node.Kind { - case ast.KindImportDeclaration: - importDecl := node.AsImportDeclaration() - if ast.IsStringLiteral(importDecl.ModuleSpecifier) { - return importDecl.ModuleSpecifier - } - case ast.KindImportEqualsDeclaration: - importEqDecl := node.AsImportEqualsDeclaration() - if importEqDecl.ModuleReference != nil && importEqDecl.ModuleReference.Kind == ast.KindExternalModuleReference { - extModRef := importEqDecl.ModuleReference.AsExternalModuleReference() - if extModRef.Expression != nil && ast.IsStringLiteral(extModRef.Expression) { - return extModRef.Expression - } - } - } - return nil -} - func replaceStringLiteral(changes *change.Tracker, sourceFile *ast.SourceFile, stringLiteral *ast.Node, newText string) { // Get the position of the string literal content (excluding quotes) literalStart := stringLiteral.Pos() From 6c6c1d423c1a4cdd471efafb9c1a5eb599b899a5 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 10:27:40 -0800 Subject: [PATCH 37/48] Mega dedupe --- internal/ls/autoimportfixes.go | 1 - internal/ls/autoimports.go | 51 ++++-- internal/ls/codeactions_importfixes.go | 221 ++----------------------- 3 files changed, 53 insertions(+), 220 deletions(-) diff --git a/internal/ls/autoimportfixes.go b/internal/ls/autoimportfixes.go index 045d7e50a5..e05dec1efe 100644 --- a/internal/ls/autoimportfixes.go +++ b/internal/ls/autoimportfixes.go @@ -208,7 +208,6 @@ func getTypeKeywordOfTypeOnlyImport(importClause *ast.ImportClause, sourceFile * return typeKeyword } - func addElementToBindingPattern(ct *change.Tracker, sourceFile *ast.SourceFile, bindingPattern *ast.Node, name string, propertyName *string) { element := newBindingElementFromNameAndPropertyName(ct, name, propertyName) if len(bindingPattern.Elements()) > 0 { diff --git a/internal/ls/autoimports.go b/internal/ls/autoimports.go index 39bbcc2a6b..04fa47e1b1 100644 --- a/internal/ls/autoimports.go +++ b/internal/ls/autoimports.go @@ -1461,19 +1461,33 @@ func (l *LanguageService) codeActionForFixWorker( switch fix.kind { case ImportFixKindUseNamespace: addNamespaceQualifier(changeTracker, sourceFile, fix.qualification()) - return diagnostics.FormatMessage(diagnostics.Change_0_to_1, symbolName, `${fix.namespacePrefix}.${symbolName}`) + return diagnostics.FormatMessage(diagnostics.Change_0_to_1, symbolName, fmt.Sprintf("%s.%s", *fix.namespacePrefix, symbolName)) case ImportFixKindJsdocTypeImport: - // !!! not implemented - // changeTracker.addImportType(changeTracker, sourceFile, fix, quotePreference); - // return diagnostics.FormatMessage(diagnostics.Change_0_to_1, symbolName, getImportTypePrefix(fix.moduleSpecifier, quotePreference) + symbolName); + if fix.usagePosition == nil { + return nil + } + quotePreference := getQuotePreference(sourceFile, l.UserPreferences()) + quoteChar := "\"" + if quotePreference == quotePreferenceSingle { + quoteChar = "'" + } + importTypePrefix := fmt.Sprintf("import(%s%s%s).", quoteChar, fix.moduleSpecifier, quoteChar) + changeTracker.InsertText(sourceFile, *fix.usagePosition, importTypePrefix) + return diagnostics.FormatMessage(diagnostics.Change_0_to_1, symbolName, importTypePrefix+symbolName) case ImportFixKindAddToExisting: + var defaultImport *Import + var namedImports []*Import + if fix.importKind == ImportKindDefault { + defaultImport = &Import{name: symbolName, addAsTypeOnly: fix.addAsTypeOnly} + } else if fix.importKind == ImportKindNamed { + namedImports = []*Import{{name: symbolName, addAsTypeOnly: fix.addAsTypeOnly, propertyName: fix.propertyName}} + } l.doAddExistingFix( changeTracker, sourceFile, fix.importClauseOrBindingPattern, - core.IfElse(fix.importKind == ImportKindDefault, &Import{name: symbolName, addAsTypeOnly: fix.addAsTypeOnly}, nil), - core.IfElse(fix.importKind == ImportKindNamed, []*Import{{name: symbolName, addAsTypeOnly: fix.addAsTypeOnly}}, nil), - // nil /*removeExistingImportSpecifiers*/, + defaultImport, + namedImports, ) moduleSpecifierWithoutQuotes := stringutil.StripQuotes(fix.moduleSpecifier) if includeSymbolNameInDescription { @@ -1482,9 +1496,14 @@ func (l *LanguageService) codeActionForFixWorker( return diagnostics.FormatMessage(diagnostics.Update_import_from_0, moduleSpecifierWithoutQuotes) case ImportFixKindAddNew: var declarations []*ast.Statement - defaultImport := core.IfElse(fix.importKind == ImportKindDefault, &Import{name: symbolName, addAsTypeOnly: fix.addAsTypeOnly}, nil) - namedImports := core.IfElse(fix.importKind == ImportKindNamed, []*Import{{name: symbolName, addAsTypeOnly: fix.addAsTypeOnly}}, nil) + var defaultImport *Import + var namedImports []*Import var namespaceLikeImport *Import + if fix.importKind == ImportKindDefault { + defaultImport = &Import{name: symbolName, addAsTypeOnly: fix.addAsTypeOnly} + } else if fix.importKind == ImportKindNamed { + namedImports = []*Import{{name: symbolName, addAsTypeOnly: fix.addAsTypeOnly, propertyName: fix.propertyName}} + } qualification := fix.qualification() if fix.importKind == ImportKindNamespace || fix.importKind == ImportKindCommonJS { namespaceLikeImport = &Import{kind: fix.importKind, addAsTypeOnly: fix.addAsTypeOnly, name: symbolName} @@ -1513,16 +1532,16 @@ func (l *LanguageService) codeActionForFixWorker( } return diagnostics.FormatMessage(diagnostics.Add_import_from_0, fix.moduleSpecifier) case ImportFixKindPromoteTypeOnly: - // !!! type only - // promotedDeclaration := promoteFromTypeOnly(changes, fix.typeOnlyAliasDeclaration, program, sourceFile, preferences); - // if promotedDeclaration.Kind == ast.KindImportSpecifier { - // return diagnostics.FormatMessage(diagnostics.Remove_type_from_import_of_0_from_1, symbolName, getModuleSpecifierText(promotedDeclaration.parent.parent)) - // } - // return diagnostics.FormatMessage(diagnostics.Remove_type_from_import_declaration_from_0, getModuleSpecifierText(promotedDeclaration)); + promotedDeclaration := promoteFromTypeOnly(changeTracker, fix.typeOnlyAliasDeclaration, l.GetProgram(), sourceFile, l) + if promotedDeclaration.Kind == ast.KindImportSpecifier { + moduleSpec := getModuleSpecifierFromDeclaration(promotedDeclaration.Parent.Parent) + return diagnostics.FormatMessage(diagnostics.Remove_type_from_import_of_0_from_1, symbolName, moduleSpec) + } + moduleSpec := getModuleSpecifierFromDeclaration(promotedDeclaration) + return diagnostics.FormatMessage(diagnostics.Remove_type_from_import_declaration_from_0, moduleSpec) default: panic(fmt.Sprintf(`Unexpected fix kind %v`, fix.kind)) } - return nil } func getNewRequires( diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 0cf0bc2255..a91d4f76f2 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -5,7 +5,6 @@ import ( "context" "fmt" "slices" - "strings" "github.com/microsoft/typescript-go/internal/ast" "github.com/microsoft/typescript-go/internal/astnav" @@ -139,19 +138,18 @@ func getFixesInfoForUMDImport(ctx context.Context, fixContext *CodeFixContext, t // before a named import, like converting `writeFile` to `fs.writeFile` (whether `fs` is already imported or // not), and this function will only be called for UMD symbols, which are necessarily an `export =`, not a // named export. - fixes := getImportFixes( - ctx, + _, fixes := fixContext.LS.getImportFixes( + ch, exportInfo, nil, // usagePosition undefined for UMD - false, - useRequire, - fixContext.Program, + ptrTo(false), + &useRequire, fixContext.SourceFile, - fixContext.LS, + false, // fromCacheOnly ) var result []*fixInfo - for _, fix := range fixes.fixes { + for _, fix := range fixes { errorIdentifierText := "" if ast.IsIdentifier(token) { errorIdentifierText = token.Text() @@ -226,22 +224,22 @@ func getFixesInfoForNonUMDImport(ctx context.Context, fixContext *CodeFixContext useAutoImportProvider, fixContext.LS, ) - for exportInfoList := range exportInfos.Values() { for _, exportInfo := range exportInfoList { usagePos := scanner.GetTokenPosOfNode(symbolToken, fixContext.SourceFile, false) - fixes := getImportFixes( - ctx, + line, character := scanner.GetECMALineAndCharacterOfPosition(fixContext.SourceFile, usagePos) + lspPos := lsproto.Position{Line: uint32(line), Character: uint32(character)} + _, fixes := fixContext.LS.getImportFixes( + ch, []*SymbolExportInfo{exportInfo}, - &usagePos, - isValidTypeOnlyUseSite, - useRequire, - fixContext.Program, + &lspPos, + &isValidTypeOnlyUseSite, + &useRequire, fixContext.SourceFile, - fixContext.LS, + false, // fromCacheOnly ) - for _, fix := range fixes.fixes { + for _, fix := range fixes { allInfo = append(allInfo, &fixInfo{ fix: fix, symbolName: symbolName, @@ -396,48 +394,6 @@ func getExportInfos( return originalSymbolToExportInfos } -type importFixesResult struct { - fixes []*ImportFix - computedWithoutCacheCount int -} - -func getImportFixes( - ctx context.Context, - exportInfos []*SymbolExportInfo, - usagePosition *int, - isValidTypeOnlyUseSite bool, - useRequire bool, - program *compiler.Program, - sourceFile *ast.SourceFile, - ls *LanguageService, -) *importFixesResult { - ch, done := program.GetTypeChecker(ctx) - defer done() - - // Convert text position to LSP position if provided - var usagePos *lsproto.Position - if usagePosition != nil { - line, character := scanner.GetECMALineAndCharacterOfPosition(sourceFile, *usagePosition) - usagePos = &lsproto.Position{Line: uint32(line), Character: uint32(character)} - } - - // Call the existing LanguageService method - computedWithoutCacheCount, fixes := ls.getImportFixes( - ch, - exportInfos, - usagePos, - &isValidTypeOnlyUseSite, - &useRequire, - sourceFile, - false, // fromCacheOnly - ) - - return &importFixesResult{ - fixes: fixes, - computedWithoutCacheCount: computedWithoutCacheCount, - } -} - func shouldUseRequire(sourceFile *ast.SourceFile, program *compiler.Program) bool { // Delegate to the existing implementation in autoimports.go return getShouldUseRequire(sourceFile, program) @@ -447,18 +403,15 @@ func codeActionForFix(ctx context.Context, fixContext *CodeFixContext, info *fix // Create a tracker with format options and converters from LanguageService tracker := change.NewTracker(ctx, fixContext.Program.Options(), fixContext.LS.FormatOptions(), fixContext.LS.converters) - description := codeActionForFixWorker( - ctx, + msg := fixContext.LS.codeActionForFixWorker( tracker, fixContext.SourceFile, info.symbolName, info.fix, info.symbolName != info.errorIdentifierText, - fixContext.Program, - fixContext.LS, ) - if description == "" { + if msg == nil { return nil } @@ -470,149 +423,11 @@ func codeActionForFix(ctx context.Context, fixContext *CodeFixContext, info *fix } return &CodeAction{ - Description: description, + Description: msg.Message(), Changes: edits, } } -func codeActionForFixWorker( - ctx context.Context, - changes *change.Tracker, - sourceFile *ast.SourceFile, - symbolName string, - fix *ImportFix, - includeSymbolNameInDescription bool, - program *compiler.Program, - ls *LanguageService, -) string { - switch fix.kind { - case ImportFixKindUseNamespace: - addNamespaceQualifier(changes, sourceFile, fix.qualification()) - return diagnostics.FormatMessage(diagnostics.Change_0_to_1, symbolName, fmt.Sprintf("%s.%s", *fix.namespacePrefix, symbolName)).Message() - - case ImportFixKindJsdocTypeImport: - // Insert import() type annotation at usage position - if fix.usagePosition == nil { - return "" - } - quotePreference := getQuotePreference(sourceFile, ls.UserPreferences()) - quoteChar := "\"" - if quotePreference == quotePreferenceSingle { - quoteChar = "'" - } - importTypePrefix := fmt.Sprintf("import(%s%s%s).", quoteChar, fix.moduleSpecifier, quoteChar) - - changes.InsertText(sourceFile, *fix.usagePosition, importTypePrefix) - - return diagnostics.FormatMessage(diagnostics.Change_0_to_1, symbolName, importTypePrefix+symbolName).Message() - - case ImportFixKindAddToExisting: - // Call doAddExistingFix from autoimportfixes.go - var defaultImport *Import - var namedImports []*Import - - if fix.importKind == ImportKindDefault { - defaultImport = &Import{ - name: symbolName, - addAsTypeOnly: fix.addAsTypeOnly, - } - } else if fix.importKind == ImportKindNamed { - namedImports = []*Import{ - { - name: symbolName, - addAsTypeOnly: fix.addAsTypeOnly, - propertyName: fix.propertyName, - }, - } - } - - ls.doAddExistingFix( - changes, - sourceFile, - fix.importClauseOrBindingPattern, - defaultImport, - namedImports, - ) - - moduleSpecifierWithoutQuotes := strings.Trim(fix.moduleSpecifier, "\"'") - if includeSymbolNameInDescription { - return diagnostics.FormatMessage(diagnostics.Import_0_from_1, symbolName, moduleSpecifierWithoutQuotes).Message() - } - return diagnostics.FormatMessage(diagnostics.Update_import_from_0, moduleSpecifierWithoutQuotes).Message() - - case ImportFixKindAddNew: - // Generate new import statement - var defaultImport *Import - var namedImports []*Import - var namespaceLikeImport *Import - - if fix.importKind == ImportKindDefault { - defaultImport = &Import{ - name: symbolName, - addAsTypeOnly: fix.addAsTypeOnly, - } - } else if fix.importKind == ImportKindNamed { - namedImports = []*Import{ - { - name: symbolName, - addAsTypeOnly: fix.addAsTypeOnly, - propertyName: fix.propertyName, - }, - } - } else if fix.importKind == ImportKindNamespace || fix.importKind == ImportKindCommonJS { - // For namespace/CommonJS imports, use qualification if available - name := symbolName - if fix.qualification() != nil { - name = fix.qualification().namespacePrefix - } - namespaceLikeImport = &Import{ - name: name, - kind: fix.importKind, - addAsTypeOnly: fix.addAsTypeOnly, - } - } - - // Create the import declarations - var statements []*ast.Statement - if fix.useRequire { - statements = getNewRequires(changes, fix.moduleSpecifier, defaultImport, namedImports, namespaceLikeImport, program.Options()) - } else { - quotePreference := getQuotePreference(sourceFile, ls.UserPreferences()) - statements = ls.getNewImports(changes, fix.moduleSpecifier, quotePreference, defaultImport, namedImports, namespaceLikeImport, program.Options()) - } - - // Insert the import statements - ls.insertImports(changes, sourceFile, statements, true /* blankLineBetween */) - - // Add namespace qualification if needed - if fix.qualification() != nil { - addNamespaceQualifier(changes, sourceFile, fix.qualification()) - } - - if includeSymbolNameInDescription { - return diagnostics.FormatMessage(diagnostics.Import_0_from_1, symbolName, fix.moduleSpecifier).Message() - } - return diagnostics.FormatMessage(diagnostics.Add_import_from_0, fix.moduleSpecifier).Message() - - case ImportFixKindPromoteTypeOnly: - // Promote type-only import to regular import - promotedDeclaration := promoteFromTypeOnly(changes, fix.typeOnlyAliasDeclaration, program, sourceFile, ls) - - // Use the promoted declaration to get the module specifier for better diagnostics - if promotedDeclaration.Kind == ast.KindImportSpecifier { - // ImportSpecifier: get module specifier from parent.parent (ImportClause.parent = ImportDeclaration) - moduleSpec := getModuleSpecifierFromDeclaration(promotedDeclaration.Parent.Parent) - return diagnostics.FormatMessage(diagnostics.Remove_type_from_import_of_0_from_1, symbolName, moduleSpec).Message() - } - // ImportClause or ImportEqualsDeclaration: get module specifier directly - moduleSpec := getModuleSpecifierFromDeclaration(promotedDeclaration) - return diagnostics.FormatMessage(diagnostics.Remove_type_from_import_declaration_from_0, moduleSpec).Message() - - default: - return "" - } -} - func isJSXTagName(node *ast.Node) bool { parent := node.Parent if parent == nil { From 038aff1ab78a6a01d0ba386cff04822abed17190 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 10:30:15 -0800 Subject: [PATCH 38/48] Even more stuff fixed --- internal/fourslash/_scripts/failingTests.txt | 3 +-- .../fourslash/tests/gen/completionsImport_importType_test.go | 2 +- .../gen/completionsImport_named_namespaceImportExists_test.go | 2 +- .../tests/gen/importNameCodeFix_reExportDefault_test.go | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt index 89e2b095f4..987966b1fe 100644 --- a/internal/fourslash/_scripts/failingTests.txt +++ b/internal/fourslash/_scripts/failingTests.txt @@ -169,11 +169,9 @@ TestCompletionsImport_filteredByPackageJson_nested TestCompletionsImport_filteredByPackageJson_peerDependencies TestCompletionsImport_filteredByPackageJson_typesImplicit TestCompletionsImport_filteredByPackageJson_typesOnly -TestCompletionsImport_importType TestCompletionsImport_jsxOpeningTagImportDefault TestCompletionsImport_mergedReExport TestCompletionsImport_named_didNotExistBefore -TestCompletionsImport_named_namespaceImportExists TestCompletionsImport_noSemicolons TestCompletionsImport_packageJsonImportsPreference TestCompletionsImport_quoteStyle @@ -314,6 +312,7 @@ TestImportNameCodeFix_order TestImportNameCodeFix_order2 TestImportNameCodeFix_pnpm1 TestImportNameCodeFix_preferBaseUrl +TestImportNameCodeFix_reExportDefault TestImportNameCodeFix_symlink TestImportNameCodeFix_trailingComma TestImportNameCodeFix_withJson diff --git a/internal/fourslash/tests/gen/completionsImport_importType_test.go b/internal/fourslash/tests/gen/completionsImport_importType_test.go index 28c24d84d2..9f71101db2 100644 --- a/internal/fourslash/tests/gen/completionsImport_importType_test.go +++ b/internal/fourslash/tests/gen/completionsImport_importType_test.go @@ -12,7 +12,7 @@ import ( func TestCompletionsImport_importType(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @allowJs: true // @Filename: /a.js diff --git a/internal/fourslash/tests/gen/completionsImport_named_namespaceImportExists_test.go b/internal/fourslash/tests/gen/completionsImport_named_namespaceImportExists_test.go index a8eb3a70da..2451350049 100644 --- a/internal/fourslash/tests/gen/completionsImport_named_namespaceImportExists_test.go +++ b/internal/fourslash/tests/gen/completionsImport_named_namespaceImportExists_test.go @@ -12,7 +12,7 @@ import ( func TestCompletionsImport_named_namespaceImportExists(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.ts export function foo() {} diff --git a/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go b/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go index c5b775e568..8a99b77559 100644 --- a/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFix_reExportDefault_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFix_reExportDefault(t *testing.T) { t.Parallel() - + t.Skip() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /user.ts foo; From 570405869b564f84e08d8bea3e6db91cc452b467 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 10:34:14 -0800 Subject: [PATCH 39/48] codeActionForFix --- internal/ls/codeactions_importfixes.go | 53 ++++++++++---------------- 1 file changed, 21 insertions(+), 32 deletions(-) diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index a91d4f76f2..c4dfdfbd05 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -71,9 +71,27 @@ func getImportCodeActions(ctx context.Context, fixContext *CodeFixContext) []Cod var actions []CodeAction for _, fixInfo := range info { - action := codeActionForFix(ctx, fixContext, fixInfo) - if action != nil { - actions = append(actions, *action) + tracker := change.NewTracker(ctx, fixContext.Program.Options(), fixContext.LS.FormatOptions(), fixContext.LS.converters) + msg := fixContext.LS.codeActionForFixWorker( + tracker, + fixContext.SourceFile, + fixInfo.symbolName, + fixInfo.fix, + fixInfo.symbolName != fixInfo.errorIdentifierText, + ) + + if msg != nil { + // Convert changes to LSP edits + changes := tracker.GetChanges() + var edits []*lsproto.TextEdit + for _, fileChanges := range changes { + edits = append(edits, fileChanges...) + } + + actions = append(actions, CodeAction{ + Description: msg.Message(), + Changes: edits, + }) } } return actions @@ -399,35 +417,6 @@ func shouldUseRequire(sourceFile *ast.SourceFile, program *compiler.Program) boo return getShouldUseRequire(sourceFile, program) } -func codeActionForFix(ctx context.Context, fixContext *CodeFixContext, info *fixInfo) *CodeAction { - // Create a tracker with format options and converters from LanguageService - tracker := change.NewTracker(ctx, fixContext.Program.Options(), fixContext.LS.FormatOptions(), fixContext.LS.converters) - - msg := fixContext.LS.codeActionForFixWorker( - tracker, - fixContext.SourceFile, - info.symbolName, - info.fix, - info.symbolName != info.errorIdentifierText, - ) - - if msg == nil { - return nil - } - - // Convert changes to LSP edits - changes := tracker.GetChanges() - var edits []*lsproto.TextEdit - for _, fileChanges := range changes { - edits = append(edits, fileChanges...) - } - - return &CodeAction{ - Description: msg.Message(), - Changes: edits, - } -} - func isJSXTagName(node *ast.Node) bool { parent := node.Parent if parent == nil { From d4a39851f7852af68170de468586245f6c5e66ea Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 10:43:32 -0800 Subject: [PATCH 40/48] slight renaming and cleanup --- internal/ls/autoimports.go | 2 +- internal/ls/autoimportsexportinfo.go | 2 +- internal/ls/codeactions_importfixes.go | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/internal/ls/autoimports.go b/internal/ls/autoimports.go index 04fa47e1b1..259e1e8f04 100644 --- a/internal/ls/autoimports.go +++ b/internal/ls/autoimports.go @@ -362,7 +362,7 @@ func (l *LanguageService) getImportCompletionAction( ) (string, codeAction) { var exportInfos []*SymbolExportInfo // `exportMapKey` should be in the `itemData` of each auto-import completion entry and sent in resolving completion entry requests - exportInfos = l.getExportInfos(ctx, ch, sourceFile, exportMapKey) + exportInfos = l.getExportInfoMap(ctx, ch, sourceFile, exportMapKey) if len(exportInfos) == 0 { panic("Some exportInfo should match the specified exportMapKey") } diff --git a/internal/ls/autoimportsexportinfo.go b/internal/ls/autoimportsexportinfo.go index 9b1b66703c..1d3c0ee771 100644 --- a/internal/ls/autoimportsexportinfo.go +++ b/internal/ls/autoimportsexportinfo.go @@ -11,7 +11,7 @@ import ( "github.com/microsoft/typescript-go/internal/stringutil" ) -func (l *LanguageService) getExportInfos( +func (l *LanguageService) getExportInfoMap( ctx context.Context, ch *checker.Checker, importingFile *ast.SourceFile, diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index c4dfdfbd05..9e18088358 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -239,7 +239,6 @@ func getFixesInfoForNonUMDImport(ctx context.Context, fixContext *CodeFixContext getMeaningFromLocation(symbolToken), fixContext.SourceFile, fixContext.Program, - useAutoImportProvider, fixContext.LS, ) for exportInfoList := range exportInfos.Values() { @@ -338,7 +337,6 @@ func getExportInfos( currentTokenMeaning ast.SemanticMeaning, fromFile *ast.SourceFile, program *compiler.Program, - useAutoImportProvider bool, ls *LanguageService, ) *collections.MultiMap[ast.SymbolId, *SymbolExportInfo] { // For each original symbol, keep all re-exports of that symbol together @@ -401,7 +399,8 @@ func getExportInfos( return "" }) != "" { addSymbol(moduleSymbol, sourceFile, defaultInfo.exportingModuleSymbol, defaultInfo.exportKind, isFromPackageJson) - } // Check for named export with identical name + } + // Check for named export with identical name exportSymbol := checker.TryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol) if exportSymbol != nil && symbolFlagsHaveMeaning(checker.GetSymbolFlags(exportSymbol), currentTokenMeaning) { addSymbol(moduleSymbol, sourceFile, exportSymbol, ExportKindNamed, isFromPackageJson) From f80b9902c5763d3c9823a6c51b52f4fc3d113509 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 10:48:40 -0800 Subject: [PATCH 41/48] Stop using the wrong position helper --- internal/ls/change/tracker.go | 5 +++ internal/ls/codeactions_importfixes.go | 58 ++++++++++---------------- 2 files changed, 27 insertions(+), 36 deletions(-) diff --git a/internal/ls/change/tracker.go b/internal/ls/change/tracker.go index ef2c22ae18..e4341075e3 100644 --- a/internal/ls/change/tracker.go +++ b/internal/ls/change/tracker.go @@ -110,6 +110,11 @@ func NewTracker(ctx context.Context, compilerOptions *core.CompilerOptions, form } } +// Converters returns the position converters for converting between text positions and LSP positions +func (t *Tracker) Converters() *lsconv.Converters { + return t.converters +} + // GetChanges returns the accumulated text edits. // Note: after calling this, the Tracker object must be discarded! func (t *Tracker) GetChanges() map[string][]*lsproto.TextEdit { diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 9e18088358..5e6111cdb3 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -244,8 +244,7 @@ func getFixesInfoForNonUMDImport(ctx context.Context, fixContext *CodeFixContext for exportInfoList := range exportInfos.Values() { for _, exportInfo := range exportInfoList { usagePos := scanner.GetTokenPosOfNode(symbolToken, fixContext.SourceFile, false) - line, character := scanner.GetECMALineAndCharacterOfPosition(fixContext.SourceFile, usagePos) - lspPos := lsproto.Position{Line: uint32(line), Character: uint32(character)} + lspPos := fixContext.LS.converters.PositionToLineAndCharacter(fixContext.SourceFile, core.TextPos(usagePos)) _, fixes := fixContext.LS.getImportFixes( ch, []*SymbolExportInfo{exportInfo}, @@ -699,13 +698,11 @@ func deleteTypeKeywordFromImportClause(changes *change.Tracker, sourceFile *ast. } // Convert text positions to LSP positions - startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, typeStart) - endLine, endChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, endPos) + // Note: changes.Converters() provides access to the converters + conv := changes.Converters() + lspRange := conv.ToLSPRange(sourceFile, core.NewTextRange(typeStart, endPos)) - changes.ReplaceRangeWithText(sourceFile, lsproto.Range{ - Start: lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, - End: lsproto.Position{Line: uint32(endLine), Character: uint32(endChar)}, - }, "") + changes.ReplaceRangeWithText(sourceFile, lspRange, "") } // deleteTypeKeywordFromSpecifier deletes the 'type' keyword from an import specifier @@ -727,13 +724,10 @@ func deleteTypeKeywordFromSpecifier(changes *change.Tracker, sourceFile *ast.Sou } // Convert text positions to LSP positions - startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, specStart) - endLine, endChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, endPos) + conv := changes.Converters() + lspRange := conv.ToLSPRange(sourceFile, core.NewTextRange(specStart, endPos)) - changes.ReplaceRangeWithText(sourceFile, lsproto.Range{ - Start: lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, - End: lsproto.Position{Line: uint32(endLine), Character: uint32(endChar)}, - }, "") + changes.ReplaceRangeWithText(sourceFile, lspRange, "") } // deleteTypeKeywordFromImportEquals deletes the 'type' keyword from an import equals declaration @@ -762,13 +756,10 @@ func deleteTypeKeywordFromImportEquals(changes *change.Tracker, sourceFile *ast. } // Convert text positions to LSP positions - startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, typeStart) - endLine, endChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, typeEnd) + conv := changes.Converters() + lspRange := conv.ToLSPRange(sourceFile, core.NewTextRange(typeStart, typeEnd)) - changes.ReplaceRangeWithText(sourceFile, lsproto.Range{ - Start: lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, - End: lsproto.Position{Line: uint32(endLine), Character: uint32(endChar)}, - }, "") + changes.ReplaceRangeWithText(sourceFile, lspRange, "") } func replaceStringLiteral(changes *change.Tracker, sourceFile *ast.SourceFile, stringLiteral *ast.Node, newText string) { @@ -776,10 +767,6 @@ func replaceStringLiteral(changes *change.Tracker, sourceFile *ast.SourceFile, s literalStart := stringLiteral.Pos() literalEnd := stringLiteral.End() - // Convert text positions to LSP positions - startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, literalStart) - endLine, endChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, literalEnd) - // Determine the quote character used text := sourceFile.Text() quoteChar := text[literalStart] @@ -787,10 +774,11 @@ func replaceStringLiteral(changes *change.Tracker, sourceFile *ast.SourceFile, s // Create the new string literal with quotes newLiteral := string(quoteChar) + newText + string(quoteChar) - changes.ReplaceRangeWithText(sourceFile, lsproto.Range{ - Start: lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, - End: lsproto.Position{Line: uint32(endLine), Character: uint32(endChar)}, - }, newLiteral) + // Convert text positions to LSP positions + conv := changes.Converters() + lspRange := conv.ToLSPRange(sourceFile, core.NewTextRange(literalStart, literalEnd)) + + changes.ReplaceRangeWithText(sourceFile, lspRange, newLiteral) } func insertTypeModifierBefore(changes *change.Tracker, sourceFile *ast.SourceFile, specifier *ast.Node) { @@ -799,10 +787,11 @@ func insertTypeModifierBefore(changes *change.Tracker, sourceFile *ast.SourceFil specStart := specifier.Pos() // Convert text position to LSP position - startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, specStart) + conv := changes.Converters() + lspPos := conv.PositionToLineAndCharacter(sourceFile, core.TextPos(specStart)) // Insert "type " at the beginning of the specifier - changes.InsertText(sourceFile, lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, "type ") + changes.InsertText(sourceFile, lspPos, "type ") } func deleteNode(changes *change.Tracker, sourceFile *ast.SourceFile, node *ast.Node, containingList []*ast.Node) { @@ -853,11 +842,8 @@ func deleteNode(changes *change.Tracker, sourceFile *ast.SourceFile, node *ast.N } // Convert text positions to LSP positions - startLine, startChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, start) - endLine, endChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, end) + conv := changes.Converters() + lspRange := conv.ToLSPRange(sourceFile, core.NewTextRange(start, end)) - changes.ReplaceRangeWithText(sourceFile, lsproto.Range{ - Start: lsproto.Position{Line: uint32(startLine), Character: uint32(startChar)}, - End: lsproto.Position{Line: uint32(endLine), Character: uint32(endChar)}, - }, "") + changes.ReplaceRangeWithText(sourceFile, lspRange, "") } From 9425684241273df8efed5c9f7d3a6c2ad814160c Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 10:51:12 -0800 Subject: [PATCH 42/48] Document bad helpers I hate --- internal/ls/codeactions_importfixes.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 5e6111cdb3..f004c60f49 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -670,6 +670,9 @@ func promoteImportClause( } } +// The below helpers are a workaround for missing Tracker functionality. +// TODO: remove these. + // deleteTypeKeywordFromImportClause deletes the 'type' keyword from an import clause func deleteTypeKeywordFromImportClause(changes *change.Tracker, sourceFile *ast.SourceFile, importClause *ast.ImportClause) { // The type keyword is the first token in the import clause From 11c2d15388dbc4511b9a161d4f0624d0afb1b986 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 11:02:25 -0800 Subject: [PATCH 43/48] Cleanup --- internal/ls/change/tracker.go | 11 +- internal/ls/codeactions_importfixes.go | 225 ++++--------------------- 2 files changed, 38 insertions(+), 198 deletions(-) diff --git a/internal/ls/change/tracker.go b/internal/ls/change/tracker.go index e4341075e3..28c5c65205 100644 --- a/internal/ls/change/tracker.go +++ b/internal/ls/change/tracker.go @@ -110,11 +110,6 @@ func NewTracker(ctx context.Context, compilerOptions *core.CompilerOptions, form } } -// Converters returns the position converters for converting between text positions and LSP positions -func (t *Tracker) Converters() *lsconv.Converters { - return t.converters -} - // GetChanges returns the accumulated text edits. // Note: after calling this, the Tracker object must be discarded! func (t *Tracker) GetChanges() map[string][]*lsproto.TextEdit { @@ -193,6 +188,12 @@ func (t *Tracker) Delete(sourceFile *ast.SourceFile, node *ast.Node) { t.deletedNodes = append(t.deletedNodes, deletedNode{sourceFile: sourceFile, node: node}) } +// DeleteRange deletes a text range from the source file. +func (t *Tracker) DeleteRange(sourceFile *ast.SourceFile, textRange core.TextRange) { + lspRange := t.converters.ToLSPRange(sourceFile, textRange) + t.ReplaceRangeWithText(sourceFile, lspRange, "") +} + // DeleteNode deletes a node immediately with specified trivia options. // Stop! Consider using Delete instead, which has logic for deleting nodes from delimited lists. func (t *Tracker) DeleteNode(sourceFile *ast.SourceFile, node *ast.Node, leadingTrivia LeadingTriviaOption, trailingTrivia TrailingTriviaOption) { diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index f004c60f49..7800c22d32 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -14,6 +14,7 @@ import ( "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/diagnostics" "github.com/microsoft/typescript-go/internal/ls/change" + "github.com/microsoft/typescript-go/internal/ls/lsutil" "github.com/microsoft/typescript-go/internal/ls/organizeimports" "github.com/microsoft/typescript-go/internal/lsp/lsproto" "github.com/microsoft/typescript-go/internal/outputpaths" @@ -528,23 +529,20 @@ func promoteFromTypeOnly( case ast.KindImportSpecifier: spec := aliasDeclaration.AsImportSpecifier() if spec.IsTypeOnly { - // TODO: TypeScript creates a new specifier with isTypeOnly=false, computes insertion index, - // and if different from current position, deletes and re-inserts at new position. - // We just delete the type keyword which may result in incorrectly ordered imports. - // Also, TypeScript uses changes.deleteRange with getTokenPosOfNode for more precise range, - // we use a simpler approach. - - // If there are multiple specifiers, we might need to move this one if spec.Parent != nil && spec.Parent.Kind == ast.KindNamedImports { - namedImports := spec.Parent.AsNamedImports() - if len(namedImports.Elements.Nodes) > 1 { - // For now, just remove the 'type' keyword from this specifier - // Full implementation would handle reordering - deleteTypeKeywordFromSpecifier(changes, sourceFile, spec) + // TypeScript creates a new specifier with isTypeOnly=false, computes insertion index, + // and if different from current position, deletes and re-inserts at new position. + // For now, we just delete the range from the first token (type keyword) to the property name or name. + firstToken := lsutil.GetFirstToken(aliasDeclaration, sourceFile) + typeKeywordPos := scanner.GetTokenPosOfNode(firstToken, sourceFile, false) + var targetNode *ast.DeclarationName + if spec.PropertyName != nil { + targetNode = spec.PropertyName } else { - // Single specifier - just remove the 'type' keyword - deleteTypeKeywordFromSpecifier(changes, sourceFile, spec) + targetNode = spec.Name() } + targetPos := scanner.GetTokenPosOfNode(targetNode.AsNode(), sourceFile, false) + changes.DeleteRange(sourceFile, core.NewTextRange(typeKeywordPos, targetPos)) } return aliasDeclaration } else { @@ -572,8 +570,13 @@ func promoteFromTypeOnly( return aliasDeclaration.Parent case ast.KindImportEqualsDeclaration: - // Remove the 'type' keyword (which is the second child: 'import' 'type' name '=' ...) - deleteTypeKeywordFromImportEquals(changes, sourceFile, aliasDeclaration.AsImportEqualsDeclaration()) + // Remove the 'type' keyword (which is the second token: 'import' 'type' name '=' ...) + importEqDecl := aliasDeclaration.AsImportEqualsDeclaration() + // The type keyword is after 'import' and before the name + scan := scanner.GetScannerForSourceFile(sourceFile, importEqDecl.Pos()) + // Skip 'import' keyword to get to 'type' + scan.Scan() + deleteTypeKeyword(changes, sourceFile, scan.TokenStart()) return aliasDeclaration default: panic(fmt.Sprintf("Unexpected alias declaration kind: %v", aliasDeclaration.Kind)) @@ -592,7 +595,7 @@ func promoteImportClause( ) { // Delete the 'type' keyword if importClause.PhaseModifier == ast.KindTypeKeyword { - deleteTypeKeywordFromImportClause(changes, sourceFile, importClause) + deleteTypeKeyword(changes, sourceFile, importClause.Pos()) } // Handle .ts extension conversion to .js if necessary @@ -608,8 +611,8 @@ func promoteImportClause( outputpaths.GetOutputExtension(moduleText, compilerOptions.Jsx), ) // Replace the module specifier with the new extension - // We need to update the string literal, keeping the quotes - replaceStringLiteral(changes, sourceFile, moduleSpecifier, changedExtension) + newStringLiteral := changes.NewStringLiteral(changedExtension) + changes.ReplaceNode(sourceFile, moduleSpecifier, newStringLiteral, nil) } } } @@ -645,7 +648,7 @@ func promoteImportClause( // If not already at index 0, move it there if aliasIndex > 0 { // Delete the specifier from its current position - deleteNode(changes, sourceFile, aliasDeclaration, namedImportsData.Elements.Nodes) + changes.Delete(sourceFile, aliasDeclaration) // Insert it at index 0 changes.InsertImportSpecifierAtIndex(sourceFile, aliasDeclaration, namedImports, 0) } @@ -662,7 +665,7 @@ func promoteImportClause( } // Skip if already type-only if !spec.IsTypeOnly { - insertTypeModifierBefore(changes, sourceFile, element) + changes.InsertModifierBefore(sourceFile, ast.KindTypeKeyword, element) } } } @@ -670,183 +673,19 @@ func promoteImportClause( } } -// The below helpers are a workaround for missing Tracker functionality. -// TODO: remove these. - -// deleteTypeKeywordFromImportClause deletes the 'type' keyword from an import clause -func deleteTypeKeywordFromImportClause(changes *change.Tracker, sourceFile *ast.SourceFile, importClause *ast.ImportClause) { - // The type keyword is the first token in the import clause - // import type { foo } from "bar" - // ^^^^^ - this keyword - // We need to find and delete "type " (including trailing space) - - // The import clause starts at the position of the "type" keyword - // Use the scanner to get the token at that position - scan := scanner.GetScannerForSourceFile(sourceFile, importClause.Pos()) - token := scan.Token() - - if token != ast.KindTypeKeyword { - panic(fmt.Sprintf("Expected type keyword at import clause start, got %v at pos %d", token, importClause.Pos())) +// deleteTypeKeyword deletes the 'type' keyword token starting at the given position, +// including any trailing whitespace. +func deleteTypeKeyword(changes *change.Tracker, sourceFile *ast.SourceFile, startPos int) { + scan := scanner.GetScannerForSourceFile(sourceFile, startPos) + if scan.Token() != ast.KindTypeKeyword { + return } - - // Use TokenStart (not TokenFullStart) to avoid including leading whitespace typeStart := scan.TokenStart() typeEnd := scan.TokenEnd() - - // Skip whitespace after 'type' to include it in the deletion + // Skip trailing whitespace text := sourceFile.Text() - endPos := typeEnd - for endPos < len(text) && (text[endPos] == ' ' || text[endPos] == '\t') { - endPos++ - } - - // Convert text positions to LSP positions - // Note: changes.Converters() provides access to the converters - conv := changes.Converters() - lspRange := conv.ToLSPRange(sourceFile, core.NewTextRange(typeStart, endPos)) - - changes.ReplaceRangeWithText(sourceFile, lspRange, "") -} - -// deleteTypeKeywordFromSpecifier deletes the 'type' keyword from an import specifier -func deleteTypeKeywordFromSpecifier(changes *change.Tracker, sourceFile *ast.SourceFile, spec *ast.ImportSpecifier) { - // import { type foo } from "bar" - // ^^^^^ - this keyword and space after - - specStart := spec.Pos() - - // The 'type' keyword is at the start of the specifier - // We want to delete "type " (including the trailing space) - typeKeywordEnd := specStart + 4 // length of "type" - - // Skip whitespace after 'type' - text := sourceFile.Text() - endPos := typeKeywordEnd - for endPos < len(text) && (text[endPos] == ' ' || text[endPos] == '\t') { - endPos++ - } - - // Convert text positions to LSP positions - conv := changes.Converters() - lspRange := conv.ToLSPRange(sourceFile, core.NewTextRange(specStart, endPos)) - - changes.ReplaceRangeWithText(sourceFile, lspRange, "") -} - -// deleteTypeKeywordFromImportEquals deletes the 'type' keyword from an import equals declaration -func deleteTypeKeywordFromImportEquals(changes *change.Tracker, sourceFile *ast.SourceFile, decl *ast.ImportEqualsDeclaration) { - // import type Foo = require("bar") - // ^^^^^ - this keyword and space after - - // The 'type' keyword comes after 'import' and before the name - // We need to find it by looking at the text - declStart := decl.Pos() - text := sourceFile.Text() - - // Skip 'import' keyword and whitespace - pos := declStart + 6 // length of "import" - for pos < len(text) && (text[pos] == ' ' || text[pos] == '\t') { - pos++ - } - - // Now we should be at 'type' - typeStart := pos - typeEnd := pos + 4 // length of "type" - - // Skip whitespace after 'type' for typeEnd < len(text) && (text[typeEnd] == ' ' || text[typeEnd] == '\t') { typeEnd++ } - - // Convert text positions to LSP positions - conv := changes.Converters() - lspRange := conv.ToLSPRange(sourceFile, core.NewTextRange(typeStart, typeEnd)) - - changes.ReplaceRangeWithText(sourceFile, lspRange, "") -} - -func replaceStringLiteral(changes *change.Tracker, sourceFile *ast.SourceFile, stringLiteral *ast.Node, newText string) { - // Get the position of the string literal content (excluding quotes) - literalStart := stringLiteral.Pos() - literalEnd := stringLiteral.End() - - // Determine the quote character used - text := sourceFile.Text() - quoteChar := text[literalStart] - - // Create the new string literal with quotes - newLiteral := string(quoteChar) + newText + string(quoteChar) - - // Convert text positions to LSP positions - conv := changes.Converters() - lspRange := conv.ToLSPRange(sourceFile, core.NewTextRange(literalStart, literalEnd)) - - changes.ReplaceRangeWithText(sourceFile, lspRange, newLiteral) -} - -func insertTypeModifierBefore(changes *change.Tracker, sourceFile *ast.SourceFile, specifier *ast.Node) { - // Insert "type " before the specifier - // import { foo } => import { type foo } - specStart := specifier.Pos() - - // Convert text position to LSP position - conv := changes.Converters() - lspPos := conv.PositionToLineAndCharacter(sourceFile, core.TextPos(specStart)) - - // Insert "type " at the beginning of the specifier - changes.InsertText(sourceFile, lspPos, "type ") -} - -func deleteNode(changes *change.Tracker, sourceFile *ast.SourceFile, node *ast.Node, containingList []*ast.Node) { - // Find the node in the list to determine if we need to delete a comma - nodeIndex := -1 - for i, n := range containingList { - if n == node { - nodeIndex = i - break - } - } - - if nodeIndex == -1 { - return // Node not found in list - } - - // Determine the range to delete - start := node.Pos() - end := node.End() - - // If this is not the last element, we need to include the comma after it - if nodeIndex < len(containingList)-1 { - // Find and include the comma after this element - text := sourceFile.Text() - pos := end - // Skip whitespace to find the comma - for pos < len(text) && (text[pos] == ' ' || text[pos] == '\t' || text[pos] == '\n' || text[pos] == '\r') { - pos++ - } - if pos < len(text) && text[pos] == ',' { - end = pos + 1 - // Also skip trailing whitespace after comma - for end < len(text) && (text[end] == ' ' || text[end] == '\t') { - end++ - } - } - } else if nodeIndex > 0 { - // This is the last element - include the comma before it - text := sourceFile.Text() - pos := start - 1 - // Skip whitespace backwards to find the comma - for pos >= 0 && (text[pos] == ' ' || text[pos] == '\t' || text[pos] == '\n' || text[pos] == '\r') { - pos-- - } - if pos >= 0 && text[pos] == ',' { - start = pos - } - } - - // Convert text positions to LSP positions - conv := changes.Converters() - lspRange := conv.ToLSPRange(sourceFile, core.NewTextRange(start, end)) - - changes.ReplaceRangeWithText(sourceFile, lspRange, "") + changes.DeleteRange(sourceFile, core.NewTextRange(typeStart, typeEnd)) } From 88cfaa5b5f9d39011da64fc0009ce8d98cdb1796 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 11:19:43 -0800 Subject: [PATCH 44/48] Temporarily work around ordering problem --- internal/fourslash/_scripts/failingTests.txt | 1 - .../importNameCodeFixOptionalImport0_test.go | 2 +- internal/ls/codeactions_importfixes.go | 56 +++++++++++-------- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt index 987966b1fe..7e671cbede 100644 --- a/internal/fourslash/_scripts/failingTests.txt +++ b/internal/fourslash/_scripts/failingTests.txt @@ -297,7 +297,6 @@ TestImportNameCodeFixNewImportFileQuoteStyleMixed0 TestImportNameCodeFixNewImportFileQuoteStyleMixed1 TestImportNameCodeFixNewImportRootDirs0 TestImportNameCodeFixNewImportTypeRoots1 -TestImportNameCodeFixOptionalImport0 TestImportNameCodeFix_HeaderComment1 TestImportNameCodeFix_HeaderComment2 TestImportNameCodeFix_avoidRelativeNodeModules diff --git a/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go index d6e2f78696..38ad76631d 100644 --- a/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go +++ b/internal/fourslash/tests/gen/importNameCodeFixOptionalImport0_test.go @@ -9,7 +9,7 @@ import ( func TestImportNameCodeFixOptionalImport0(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: a/f1.ts [|import * as ns from "./foo"; diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 7800c22d32..8e659d03b8 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "slices" + "strings" "github.com/microsoft/typescript-go/internal/ast" "github.com/microsoft/typescript-go/internal/astnav" @@ -233,7 +234,7 @@ func getFixesInfoForNonUMDImport(ctx context.Context, fixContext *CodeFixContext isValidTypeOnlyUseSite := ast.IsValidTypeOnlyAliasUseSite(symbolToken) useRequire := shouldUseRequire(fixContext.SourceFile, fixContext.Program) - exportInfos := getExportInfos( + exportInfosMap := getExportInfos( ctx, symbolName, isJSXTagName(symbolToken), @@ -242,28 +243,39 @@ func getFixesInfoForNonUMDImport(ctx context.Context, fixContext *CodeFixContext fixContext.Program, fixContext.LS, ) - for exportInfoList := range exportInfos.Values() { - for _, exportInfo := range exportInfoList { - usagePos := scanner.GetTokenPosOfNode(symbolToken, fixContext.SourceFile, false) - lspPos := fixContext.LS.converters.PositionToLineAndCharacter(fixContext.SourceFile, core.TextPos(usagePos)) - _, fixes := fixContext.LS.getImportFixes( - ch, - []*SymbolExportInfo{exportInfo}, - &lspPos, - &isValidTypeOnlyUseSite, - &useRequire, - fixContext.SourceFile, - false, // fromCacheOnly - ) - for _, fix := range fixes { - allInfo = append(allInfo, &fixInfo{ - fix: fix, - symbolName: symbolName, - errorIdentifierText: symbolToken.Text(), - isJsxNamespaceFix: symbolName != symbolToken.Text(), - }) - } + // Flatten all export infos from the map into a single slice + var allExportInfos []*SymbolExportInfo + for exportInfoList := range exportInfosMap.Values() { + allExportInfos = append(allExportInfos, exportInfoList...) + } + + // Sort by moduleFileName to ensure deterministic iteration order + // TODO: This might not work 100% of the time; need to revisit this + slices.SortStableFunc(allExportInfos, func(a, b *SymbolExportInfo) int { + return strings.Compare(a.moduleFileName, b.moduleFileName) + }) + + if len(allExportInfos) > 0 { + usagePos := scanner.GetTokenPosOfNode(symbolToken, fixContext.SourceFile, false) + lspPos := fixContext.LS.converters.PositionToLineAndCharacter(fixContext.SourceFile, core.TextPos(usagePos)) + _, fixes := fixContext.LS.getImportFixes( + ch, + allExportInfos, + &lspPos, + &isValidTypeOnlyUseSite, + &useRequire, + fixContext.SourceFile, + false, // fromCacheOnly + ) + + for _, fix := range fixes { + allInfo = append(allInfo, &fixInfo{ + fix: fix, + symbolName: symbolName, + errorIdentifierText: symbolToken.Text(), + isJsxNamespaceFix: symbolName != symbolToken.Text(), + }) } } } From c6efb6609019651d7f45f674d626070551c1e78b Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 13:51:31 -0800 Subject: [PATCH 45/48] Delete dupe helper --- internal/ls/autoimports.go | 4 ++-- internal/ls/codeactions_importfixes.go | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/internal/ls/autoimports.go b/internal/ls/autoimports.go index 259e1e8f04..8fc2c3a37e 100644 --- a/internal/ls/autoimports.go +++ b/internal/ls/autoimports.go @@ -536,7 +536,7 @@ func (l *LanguageService) getImportFixForSymbol( if isValidTypeOnlySite == nil { isValidTypeOnlySite = ptrTo(ast.IsValidTypeOnlyAliasUseSite(astnav.GetTokenAtPosition(sourceFile, position))) } - useRequire := getShouldUseRequire(sourceFile, l.GetProgram()) + useRequire := shouldUseRequire(sourceFile, l.GetProgram()) packageJsonImportFilter := l.createPackageJsonImportFilter(sourceFile) _, fixes := l.getImportFixes(ch, exportInfos, ptrTo(l.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(position))), isValidTypeOnlySite, &useRequire, sourceFile, false /* fromCacheOnly */) return l.getBestFix(fixes, sourceFile, packageJsonImportFilter.allowsImportingSpecifier) @@ -1162,7 +1162,7 @@ func getAddAsTypeOnly( return AddAsTypeOnlyAllowed } -func getShouldUseRequire( +func shouldUseRequire( sourceFile *ast.SourceFile, // !!! | FutureSourceFile program *compiler.Program, ) bool { diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 8e659d03b8..0f4a73f212 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -423,11 +423,6 @@ func getExportInfos( return originalSymbolToExportInfos } -func shouldUseRequire(sourceFile *ast.SourceFile, program *compiler.Program) bool { - // Delegate to the existing implementation in autoimports.go - return getShouldUseRequire(sourceFile, program) -} - func isJSXTagName(node *ast.Node) bool { parent := node.Parent if parent == nil { From d26c966320d4c4391cb7f7869e2b4f1768f44928 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 13:55:57 -0800 Subject: [PATCH 46/48] More duplication, sigh --- internal/ls/autoimports.go | 6 ++-- internal/ls/codeactions_importfixes.go | 47 -------------------------- 2 files changed, 3 insertions(+), 50 deletions(-) diff --git a/internal/ls/autoimports.go b/internal/ls/autoimports.go index 8fc2c3a37e..dabf61d4ac 100644 --- a/internal/ls/autoimports.go +++ b/internal/ls/autoimports.go @@ -1534,10 +1534,10 @@ func (l *LanguageService) codeActionForFixWorker( case ImportFixKindPromoteTypeOnly: promotedDeclaration := promoteFromTypeOnly(changeTracker, fix.typeOnlyAliasDeclaration, l.GetProgram(), sourceFile, l) if promotedDeclaration.Kind == ast.KindImportSpecifier { - moduleSpec := getModuleSpecifierFromDeclaration(promotedDeclaration.Parent.Parent) + moduleSpec := getModuleSpecifierText(promotedDeclaration.Parent.Parent) return diagnostics.FormatMessage(diagnostics.Remove_type_from_import_of_0_from_1, symbolName, moduleSpec) } - moduleSpec := getModuleSpecifierFromDeclaration(promotedDeclaration) + moduleSpec := getModuleSpecifierText(promotedDeclaration) return diagnostics.FormatMessage(diagnostics.Remove_type_from_import_declaration_from_0, moduleSpec) default: panic(fmt.Sprintf(`Unexpected fix kind %v`, fix.kind)) @@ -1628,7 +1628,7 @@ func createConstEqualsRequireDeclaration(changeTracker *change.Tracker, name *as ) } -func getModuleSpecifierText(promotedDeclaration *ast.ImportDeclaration) string { +func getModuleSpecifierText(promotedDeclaration *ast.Node) string { if promotedDeclaration.Kind == ast.KindImportEqualsDeclaration { importEqualsDeclaration := promotedDeclaration.AsImportEqualsDeclaration() if ast.IsExternalModuleReference(importEqualsDeclaration.ModuleReference) { diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 0f4a73f212..9c4bbf5aec 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -434,53 +434,6 @@ func isJSXTagName(node *ast.Node) bool { return false } -// getModuleSpecifierFromDeclaration gets the module specifier string from a declaration -func getModuleSpecifierFromDeclaration(decl *ast.Declaration) string { - var moduleSpec *ast.Node - - switch decl.Kind { - case ast.KindImportDeclaration: - moduleSpec = decl.AsImportDeclaration().ModuleSpecifier - case ast.KindImportEqualsDeclaration: - importEq := decl.AsImportEqualsDeclaration() - if importEq.ModuleReference != nil && importEq.ModuleReference.Kind == ast.KindExternalModuleReference { - moduleSpec = importEq.ModuleReference.AsExternalModuleReference().Expression - } - case ast.KindImportSpecifier: - // Walk up to find the import declaration - if clause := getImportClauseOfSpecifier(decl.AsImportSpecifier()); clause != nil { - if clause.Parent != nil && clause.Parent.Kind == ast.KindImportDeclaration { - moduleSpec = clause.Parent.AsImportDeclaration().ModuleSpecifier - } - } - case ast.KindImportClause: - if decl.Parent != nil && decl.Parent.Kind == ast.KindImportDeclaration { - moduleSpec = decl.Parent.AsImportDeclaration().ModuleSpecifier - } - case ast.KindNamespaceImport: - if decl.Parent != nil && decl.Parent.Kind == ast.KindImportClause { - if decl.Parent.Parent != nil && decl.Parent.Parent.Kind == ast.KindImportDeclaration { - moduleSpec = decl.Parent.Parent.AsImportDeclaration().ModuleSpecifier - } - } - } - - if moduleSpec != nil && ast.IsStringLiteral(moduleSpec) { - return moduleSpec.AsStringLiteral().Text - } - return "" -} - -// getImportClauseOfSpecifier gets the import clause containing a specifier -func getImportClauseOfSpecifier(spec *ast.ImportSpecifier) *ast.ImportClause { - if spec.Parent != nil && spec.Parent.Kind == ast.KindNamedImports { - if spec.Parent.Parent != nil && spec.Parent.Parent.Kind == ast.KindImportClause { - return spec.Parent.Parent.AsImportClause() - } - } - return nil -} - func sortFixInfo(fixes []*fixInfo, fixContext *CodeFixContext) []*fixInfo { if len(fixes) == 0 { return fixes From 96a03c39c422a482c14f912327f02e9970af5427 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 13:59:18 -0800 Subject: [PATCH 47/48] Remove another dupe --- internal/ls/codeactions_importfixes.go | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/internal/ls/codeactions_importfixes.go b/internal/ls/codeactions_importfixes.go index 9c4bbf5aec..23449bd365 100644 --- a/internal/ls/codeactions_importfixes.go +++ b/internal/ls/codeactions_importfixes.go @@ -237,7 +237,7 @@ func getFixesInfoForNonUMDImport(ctx context.Context, fixContext *CodeFixContext exportInfosMap := getExportInfos( ctx, symbolName, - isJSXTagName(symbolToken), + ast.IsJsxTagName(symbolToken), getMeaningFromLocation(symbolToken), fixContext.SourceFile, fixContext.Program, @@ -423,17 +423,6 @@ func getExportInfos( return originalSymbolToExportInfos } -func isJSXTagName(node *ast.Node) bool { - parent := node.Parent - if parent == nil { - return false - } - if ast.IsJsxOpeningLikeElement(parent) || ast.IsJsxClosingElement(parent) { - return parent.TagName() == node - } - return false -} - func sortFixInfo(fixes []*fixInfo, fixContext *CodeFixContext) []*fixInfo { if len(fixes) == 0 { return fixes From 66c2dc461c931cab0c6d4f05cb4e58dddc238529 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 11 Nov 2025 15:07:57 -0800 Subject: [PATCH 48/48] Small cleanups after reviewing the code --- internal/checker/utilities.go | 7 +++++++ internal/ls/autoimports.go | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/checker/utilities.go b/internal/checker/utilities.go index 087a3e211a..bfb65ac11d 100644 --- a/internal/checker/utilities.go +++ b/internal/checker/utilities.go @@ -1007,6 +1007,13 @@ func IsKnownSymbol(symbol *ast.Symbol) bool { return isLateBoundName(symbol.Name) } +func IsPrivateIdentifierSymbol(symbol *ast.Symbol) bool { + if symbol == nil { + return false + } + return strings.HasPrefix(symbol.Name, ast.InternalSymbolNamePrefix+"#") +} + func isLateBoundName(name string) bool { return len(name) >= 2 && name[0] == '\xfe' && name[1] == '@' } diff --git a/internal/ls/autoimports.go b/internal/ls/autoimports.go index dabf61d4ac..6a44f28299 100644 --- a/internal/ls/autoimports.go +++ b/internal/ls/autoimports.go @@ -356,7 +356,7 @@ func (l *LanguageService) getImportCompletionAction( sourceFile *ast.SourceFile, position int, exportMapKey ExportInfoMapKey, - symbolName string, // !!! needs *string ? + symbolName string, isJsxTagName bool, // formatContext *formattingContext, ) (string, codeAction) { @@ -482,7 +482,7 @@ func fileContainsPackageImport(sourceFile *ast.SourceFile, packageName string) b } func isImportableSymbol(symbol *ast.Symbol, ch *checker.Checker) bool { - return !ch.IsUndefinedSymbol(symbol) && !ch.IsUnknownSymbol(symbol) && !checker.IsKnownSymbol(symbol) // !!! && !checker.IsPrivateIdentifierSymbol(symbol); + return !ch.IsUndefinedSymbol(symbol) && !ch.IsUnknownSymbol(symbol) && !checker.IsKnownSymbol(symbol) && !checker.IsPrivateIdentifierSymbol(symbol) } func getDefaultLikeExportInfo(moduleSymbol *ast.Symbol, ch *checker.Checker) *ExportInfo {