Skip to content

feat: typescript 7 content mapper - #3111

Draft
jasonlyu123 wants to merge 22 commits into
sveltejs:masterfrom
jasonlyu123:ts7-content-mapper
Draft

feat: typescript 7 content mapper#3111
jasonlyu123 wants to merge 22 commits into
sveltejs:masterfrom
jasonlyu123:ts7-content-mapper

Conversation

@jasonlyu123

@jasonlyu123 jasonlyu123 commented Aug 22, 2026

Copy link
Copy Markdown
Member

#2733

The language server part currently requires changes in the TypeScript 7 VSCode extension that haven't been published yet. Can only be tested with a local TypeScript extension build.

Known problems

  • auto import
    panic in TypeScript language server
    panic is resolved, but mapping is still a problem. At least normal completion is fixed now.
  • organize imports
    Because we move imports by statements, we need to find a way to move by groups.
  • inlay hints
    Duplicated entries. Open an upstream issue, and also reduce the places where it happens.
  • document highlight
    VS Code doesn't seem to allow multiple providers. Need to manually merge it when we have middleware api.

PR Test instruction

(Will edit this after this change is published)

  • Clone the TypeScript repo to the same directory as language tools
  • Copy launch.template.json to launch.json
  • Add this to launch.json
        {
            "type": "extensionHost",
            "request": "launch",
            "name": "Launch VS Code extension with Svelte",
            "runtimeExecutable": "${execPath}",
            "args": [
                "--extensionDevelopmentPath=${workspaceFolder}/packages/vscode-typescript",
                "--extensionDevelopmentPath=${workspaceFolder}/../language-tools/packages/svelte-vscode"
            ],
            "outFiles": [
                "${workspaceFolder}/packages/vscode-typescript/dist/**/*.js",
                "${workspaceFolder}/../language-tools/packages/svelte-vscode/dist/**/*.js"
            ],
            "autoAttachChildProcesses": true,
            "preLaunchTask": "Watch for extension run"
        },
  • Install content mapper and svelte2tsx using a relative path to a test svelte project.
{
  "devDependencies": {
  	"svelte-typescript-content-mapper": "file:../language-tools/packages/typescript-content-mapper"
  },
  "pnpm": {
  	"overrides": {
  		"@sveltejs/load-config": "file:../language-tools/packages/load-config",
  		"svelte2tsx": "file:../language-tools/packages/svelte2tsx"
  	}
  }
  • Add this to the tsconfig.json of the test project
	"contentMappers": [
  	{
  		"package": "svelte-typescript-content-mapper",
  		"extensions": [".svelte"]
  	}
  ]

Make sure you're using the latest commit in the typescript repo.

@changeset-bot

changeset-bot Bot commented Aug 22, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: ff16c5e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@andrewbranch

Copy link
Copy Markdown

Exciting progress! Do you have a stack trace for the auto-import panic handy?

@jasonlyu123

Copy link
Copy Markdown
Member Author

Do you have a stack trace for the auto-import panic handy?

Debug failure. False expression: Token end is child end
runtime/debug.Stack()
	C:/Program Files/Go/src/runtime/debug/stack.go:26 +0x8e
github.com/microsoft/TypeScript/tsc/internal/lsp.(*Server).recover(0x25835d125508, 0x25836906e3f0)
	C:/projects/TypeScript/tsc/internal/lsp/server.go:1477 +0x4f
panic({0x7ff7b8bc3580?, 0x2583610277f0?})
	C:/Program Files/Go/src/runtime/panic.go:860 +0x14f
github.com/microsoft/TypeScript/tsc/internal/debug.Fail({0x258368c81bc0, 0x37})
	C:/projects/TypeScript/tsc/internal/debug/debug.go:14 +0x65
github.com/microsoft/TypeScript/tsc/internal/debug.assertSlow({0x258368d9cde8, 0x1, 0x1})
	C:/projects/TypeScript/tsc/internal/debug/debug.go:60 +0xa5
github.com/microsoft/TypeScript/tsc/internal/debug.Assert(0x0, {0x258368d9cde8, 0x1, 0x1})
	C:/projects/TypeScript/tsc/internal/debug/debug.go:49 +0x3b
github.com/microsoft/TypeScript/tsc/internal/format.(*formatSpanWorker).processChildNode(0x25835f7505a0, 0x258369118000, 0x258369115400, 0x0, 0x0, 0x25836205f6c8, 0xffffffffffffffff, 0x258369118000, 0x258369115400, 0x0, ...)
	C:/projects/TypeScript/tsc/internal/format/span.go:410 +0x957
github.com/microsoft/TypeScript/tsc/internal/format.(*formatSpanWorker).execute.func1(0x25836205f6c8)
	C:/projects/TypeScript/tsc/internal/format/span.go:236 +0x15a
github.com/microsoft/TypeScript/tsc/internal/ast.(*NodeVisitor).VisitNode(0x2583690fb620, 0x25836205f6c8)
	C:/projects/TypeScript/tsc/internal/ast/visitor.go:51 +0x87
github.com/microsoft/TypeScript/tsc/internal/ast.(*NodeVisitor).visitNode(0x2583690fb620, 0x25836205f6c8)
	C:/projects/TypeScript/tsc/internal/ast/visitor.go:198 +0x6a
github.com/microsoft/TypeScript/tsc/internal/ast.(*ImportDeclaration).VisitEachChild(0x258369118000, 0x2583690fb620)
	C:/projects/TypeScript/tsc/internal/ast/ast_generated.go:2564 +0xa5
github.com/microsoft/TypeScript/tsc/internal/ast.(*Node).VisitEachChild(0x258369118000, 0x2583690fb620)
	C:/projects/TypeScript/tsc/internal/ast/ast.go:208 +0x42
github.com/microsoft/TypeScript/tsc/internal/format.(*formatSpanWorker).executeProcessNodeVisitor(0x25835f7505a0, 0x258369118000, 0x258369115400, 0x0, 0x0)
	C:/projects/TypeScript/tsc/internal/format/span.go:537 +0x125
github.com/microsoft/TypeScript/tsc/internal/format.(*formatSpanWorker).processNode(0x25835f7505a0, 0x258369118000, 0x2583690f4388, 0x0, 0x0, 0x4, 0x4)
	C:/projects/TypeScript/tsc/internal/format/span.go:638 +0x156
github.com/microsoft/TypeScript/tsc/internal/format.(*formatSpanWorker).processChildNode(0x25835f7505a0, 0x2583690f4388, 0x258369115360, 0x0, 0x0, 0x258369118000, 0xffffffffffffffff, 0x2583690f4388, 0x258369115360, 0x0, ...)
	C:/projects/TypeScript/tsc/internal/format/span.go:428 +0xb05
github.com/microsoft/TypeScript/tsc/internal/format.(*formatSpanWorker).processChildNodes(0x25835f7505a0, 0x2583690f4388, 0x258369115360, 0x0, 0x0, 0x2583619c9140, 0x2583690f4388, 0x0, 0x258369115360)
	C:/projects/TypeScript/tsc/internal/format/span.go:501 +0x36c
github.com/microsoft/TypeScript/tsc/internal/format.(*formatSpanWorker).execute.func2(0x2583619c9140, 0x2583690fb620)
	C:/projects/TypeScript/tsc/internal/format/span.go:243 +0x10d
github.com/microsoft/TypeScript/tsc/internal/ast.(*NodeVisitor).visitNodes(0x2583690fb620, 0x2583619c9140)
	C:/projects/TypeScript/tsc/internal/ast/visitor.go:234 +0x4b
github.com/microsoft/TypeScript/tsc/internal/ast.(*NodeVisitor).visitTopLevelStatements(0x2583690fb620, 0x2583619c9140)
	C:/projects/TypeScript/tsc/internal/ast/visitor.go:257 +0x6a
github.com/microsoft/TypeScript/tsc/internal/ast.(*SourceFile).VisitEachChild(0x2583690f4388, 0x2583690fb620)
	C:/projects/TypeScript/tsc/internal/ast/ast.go:2798 +0x45
github.com/microsoft/TypeScript/tsc/internal/ast.(*Node).VisitEachChild(0x2583690f4388, 0x2583690fb620)
	C:/projects/TypeScript/tsc/internal/ast/ast.go:208 +0x42
github.com/microsoft/TypeScript/tsc/internal/format.(*formatSpanWorker).executeProcessNodeVisitor(0x25835f7505a0, 0x2583690f4388, 0x258369115360, 0x0, 0x0)
	C:/projects/TypeScript/tsc/internal/format/span.go:537 +0x125
github.com/microsoft/TypeScript/tsc/internal/format.(*formatSpanWorker).processNode(0x25835f7505a0, 0x2583690f4388, 0x2583690f4388, 0x0, 0x0, 0x4, 0x4)
	C:/projects/TypeScript/tsc/internal/format/span.go:638 +0x156
github.com/microsoft/TypeScript/tsc/internal/format.(*formatSpanWorker).execute(0x25835f7505a0, 0x25836437d130)
	C:/projects/TypeScript/tsc/internal/format/span.go:257 +0x593
github.com/microsoft/TypeScript/tsc/internal/format.newFormattingScanner({0x258364ff7800, 0x2f}, 0x0, 0x0, 0x2f, 0x25835f7505a0)
	C:/projects/TypeScript/tsc/internal/format/scanner.go:57 +0x189
github.com/microsoft/TypeScript/tsc/internal/format.FormatNodeGivenIndentation({0x7ff7b9033b98, 0x258368dfc1b0}, 0x2583690f4388, 0x2583690f4388, 0x0, 0x4, 0x4)
	C:/projects/TypeScript/tsc/internal/format/api.go:83 +0x15f
github.com/microsoft/TypeScript/tsc/internal/ls/change.(*Tracker).getFormattedTextOfNode(0x2583678a5b20, 0x2583650558f0, 0x25836888a708, 0x25836888a708, 0x1f6, {{0x0, 0x0}, {0x7ff7b901e6e8, 0x1}, 0x0, ...})
	C:/projects/TypeScript/tsc/internal/ls/change/trackerimpl.go:140 +0x4b3
github.com/microsoft/TypeScript/tsc/internal/ls/change.(*Tracker).computeNewText.func1(0x2583650558f0)
	C:/projects/TypeScript/tsc/internal/ls/change/trackerimpl.go:86 +0x112
github.com/microsoft/TypeScript/tsc/internal/ls/change.(*Tracker).computeNewText(0x2583678a5b20, 0x2583690f3400, 0x25836888a708, 0x25836888a708)
	C:/projects/TypeScript/tsc/internal/ls/change/trackerimpl.go:98 +0x2d7
github.com/microsoft/TypeScript/tsc/internal/ls/change.(*Tracker).getTextChangesFromChanges.func2(0x2583690f3400)
	C:/projects/TypeScript/tsc/internal/ls/change/trackerimpl.go:43 +0x4b
github.com/microsoft/TypeScript/tsc/internal/core.MapNonNil[...]({0x2583690b53e8, 0x1, 0x1}, 0x258368d9e920)
	C:/projects/TypeScript/tsc/internal/core/core.go:120 +0xd9
github.com/microsoft/TypeScript/tsc/internal/ls/change.(*Tracker).getTextChangesFromChanges(0x2583678a5b20)
	C:/projects/TypeScript/tsc/internal/ls/change/trackerimpl.go:40 +0x2de
github.com/microsoft/TypeScript/tsc/internal/ls/change.(*Tracker).GetChanges(0x2583678a5b20)
	C:/projects/TypeScript/tsc/internal/ls/change/tracker.go:137 +0x65
github.com/microsoft/TypeScript/tsc/internal/ls/autoimport.fileEdits(0x2583678a5b20, 0x25836888a708)
	C:/projects/TypeScript/tsc/internal/ls/autoimport/fix.go:134 +0x66
github.com/microsoft/TypeScript/tsc/internal/ls/autoimport.(*Fix).Edits(_, {_, _}, _, _, {{0x0, 0x4, 0x4, {0x7ff7b901e6e8, 0x1}, ...}, ...}, ...)
	C:/projects/TypeScript/tsc/internal/ls/autoimport/fix.go:109 +0xe66
github.com/microsoft/TypeScript/tsc/internal/ls.(*LanguageService).filterContentMappedAutoImports(0x258361516b40, {0x7ff7b9033b98, 0x258367fdc960}, 0x25835f17fb88, 0x25836888a708, 0x258368dfc150)
	C:/projects/TypeScript/tsc/internal/ls/completions.go:89 +0x44f
github.com/microsoft/TypeScript/tsc/internal/ls.(*LanguageService).ProvideCompletion(0x258361516b40, {0x7ff7b9033b98, 0x258367fdc960}, {0x258361234000, 0x44}, {0x8, 0x2}, 0x258363ef35a0)
	C:/projects/TypeScript/tsc/internal/ls/completions.go:70 +0x51c
github.com/microsoft/TypeScript/tsc/internal/lsp.(*Server).handleCompletion(0x25835d125508, {0x7ff7b9033b98, 0x258367fdc870}, 0x258361516b40, 0x258367fdc8a0)
	C:/projects/TypeScript/tsc/internal/lsp/server.go:2112 +0xe5
github.com/microsoft/TypeScript/tsc/internal/lsp.registerLanguageServiceWithAutoImportsRequestHandler[...].func1.1.1()
	C:/projects/TypeScript/tsc/internal/lsp/server.go:1374 +0x174
github.com/microsoft/TypeScript/tsc/internal/project.(*Session).WithLanguageServiceAndSnapshot.func1()
	C:/projects/TypeScript/tsc/internal/project/session.go:1336 +0xb1
github.com/microsoft/TypeScript/tsc/internal/lsp.(*Server).handleRequestOrNotification.func1()
	C:/projects/TypeScript/tsc/internal/lsp/server.go:1167 +0x75
github.com/microsoft/TypeScript/tsc/internal/lsp.(*Server).dispatchLoop.func3()
	C:/projects/TypeScript/tsc/internal/lsp/server.go:1014 +0x33
created by github.com/microsoft/TypeScript/tsc/internal/lsp.(*Server).dispatchLoop in goroutine 10
	C:/projects/TypeScript/tsc/internal/lsp/server.go:1013 +0x81f

Weirdly, in getFormattedTextOfNode, the text returned in t.getNonformattedText is a broken import statement.

import { SvelteComponentTyped } from te-tsgo-t;

And if I track down the module specifier printing in that function, in the getLiteralTextOfNode function here, p.emitContext.textSource is nil. It sounds like the emitContext might not be the same one when the node is created?

Btw, should I open an issue to track this? There is also a problem with duplicated inlay hints that seems to happen when a node is split into multiple spans. Should I open two separate issues?

@andrewbranch

Copy link
Copy Markdown

Two issues would be great, if you don't mind!

we did this in the language-server too
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants