Skip to content

[wip] Build mode #1484

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 28 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
230e4d9
Add commandline --build parsing
sheetalkamat Jul 23, 2025
3415e2f
add help
sheetalkamat Aug 12, 2025
43b279f
Build order
sheetalkamat Jul 23, 2025
1836d84
tsc -b
sheetalkamat Aug 6, 2025
93c4741
tsc --b commandline tests
sheetalkamat Aug 13, 2025
d773a65
tsc --b --clean tests
sheetalkamat Aug 13, 2025
2395828
tsc -b config file errors tests
sheetalkamat Aug 13, 2025
fcda46c
tsc composite tests
sheetalkamat Aug 13, 2025
29e57ae
tsc -b extends
sheetalkamat Aug 13, 2025
ed38157
Include quotes of string literals of import in the file include reaso…
sheetalkamat Aug 15, 2025
8252f4e
tsc -b solution tests
sheetalkamat Aug 14, 2025
294de5a
tsc -b and tsc -p declaration emit tests
sheetalkamat Aug 14, 2025
c377b2e
emitdeclaration only tests
sheetalkamat Aug 14, 2025
7c52f3e
tsc -b file delete tests
sheetalkamat Aug 13, 2025
2008c5c
tsc -b demo
sheetalkamat Aug 14, 2025
15ac654
inferredTypeFromTransitiveModule tests
sheetalkamat Aug 13, 2025
bbc048e
javascriptProjectEmit
sheetalkamat Aug 13, 2025
46d1cf1
lateBoundSymbol
sheetalkamat Aug 13, 2025
4089ccf
tsc libraryResolution tests
sheetalkamat Aug 13, 2025
adc24ac
Store failed libResolution with --libReplacement so errors and trace …
sheetalkamat Aug 15, 2025
2c87582
Dont do module resolution for lib.d.ts with --libReplacement as it wa…
sheetalkamat Aug 15, 2025
7151c60
Fix the text ranges for libRefrence and others
sheetalkamat Aug 15, 2025
08d6eb4
tsc --listFilesOnly
sheetalkamat Aug 15, 2025
49f5e24
tsc module resolution
sheetalkamat Aug 15, 2025
3b218d1
Use correct options for parsing paths
sheetalkamat Aug 15, 2025
86a4aa5
tsc build module specifiers
sheetalkamat Aug 13, 2025
d62c31a
tsc --noCheck
sheetalkamat Aug 13, 2025
f5f6e8a
Correct the noCheck error state encoding to work correctly with tsc -b
sheetalkamat Aug 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions internal/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"io"
"strconv"
"sync"
"time"

"github.com/go-json-experiment/json"
"github.com/microsoft/typescript-go/internal/bundled"
Expand Down Expand Up @@ -472,3 +473,8 @@ func (s *Server) Stat(path string) vfs.FileInfo {
func (s *Server) Remove(path string) error {
panic("unimplemented")
}

// Chtimes implements vfs.FS.
func (s *Server) Chtimes(path string, aTime time.Time, mTime time.Time) error {
panic("unimplemented")
}
7 changes: 7 additions & 0 deletions internal/bundled/embed.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,13 @@ func (vfs *wrappedFS) Remove(path string) error {
return vfs.fs.Remove(path)
}

func (vfs *wrappedFS) Chtimes(path string, aTime time.Time, mTime time.Time) error {
if _, ok := splitPath(path); ok {
panic("cannot change times on embedded file system")
}
return vfs.fs.Chtimes(path, aTime, mTime)
}

type fileInfo struct {
mode fs.FileMode
name string
Expand Down
2 changes: 1 addition & 1 deletion internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -14633,7 +14633,7 @@ func (c *Checker) resolveExternalModule(location *ast.Node, moduleReference stri
}

var message *diagnostics.Message
if overrideHost != nil && overrideHost.Kind == ast.KindImportDeclaration && overrideHost.AsImportDeclaration().ImportClause.IsTypeOnly() {
if overrideHost != nil && overrideHost.Kind == ast.KindImportDeclaration && overrideHost.AsImportDeclaration().ImportClause != nil && overrideHost.AsImportDeclaration().ImportClause.IsTypeOnly() {
message = diagnostics.Type_only_import_of_an_ECMAScript_module_from_a_CommonJS_module_must_have_a_resolution_mode_attribute
} else if overrideHost != nil && overrideHost.Kind == ast.KindImportType {
message = diagnostics.Type_import_of_an_ECMAScript_module_from_a_CommonJS_module_must_have_a_resolution_mode_attribute
Expand Down
7 changes: 6 additions & 1 deletion internal/collections/syncset.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ func (s *SyncSet[T]) Has(key T) bool {
return ok
}

func (s *SyncSet[T]) AddIfAbsent(key T) bool {
_, loaded := s.m.LoadOrStore(key, struct{}{})
return !loaded
}

func (s *SyncSet[T]) Add(key T) {
s.m.Store(key, struct{}{})
s.AddIfAbsent(key)
}

func (s *SyncSet[T]) Delete(key T) {
Expand Down
7 changes: 2 additions & 5 deletions internal/compiler/emitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ type emitter struct {
}

func (e *emitter) emit() {
if e.host.Options().ListEmittedFiles.IsTrue() {
e.emitResult.EmittedFiles = []string{}
}
// !!! tracing
e.emitJSFile(e.sourceFile, e.paths.JsFilePath(), e.paths.SourceMapFilePath())
e.emitDeclarationFile(e.sourceFile, e.paths.DeclarationFilePath(), e.paths.DeclarationMapPath())
Expand Down Expand Up @@ -262,7 +259,7 @@ func (e *emitter) printSourceFile(jsFilePath string, sourceMapFilePath string, s
err := e.host.WriteFile(sourceMapFilePath, sourceMap, false /*writeByteOrderMark*/)
if err != nil {
e.emitterDiagnostics.Add(ast.NewCompilerDiagnostic(diagnostics.Could_not_write_file_0_Colon_1, jsFilePath, err.Error()))
} else if e.emitResult.EmittedFiles != nil {
} else {
e.emitResult.EmittedFiles = append(e.emitResult.EmittedFiles, sourceMapFilePath)
}
}
Expand All @@ -286,7 +283,7 @@ func (e *emitter) printSourceFile(jsFilePath string, sourceMapFilePath string, s
}
if err != nil {
e.emitterDiagnostics.Add(ast.NewCompilerDiagnostic(diagnostics.Could_not_write_file_0_Colon_1, jsFilePath, err.Error()))
} else if e.emitResult.EmittedFiles != nil && !skippedDtsWrite {
} else if !skippedDtsWrite {
e.emitResult.EmittedFiles = append(e.emitResult.EmittedFiles, jsFilePath)
}

Expand Down
7 changes: 6 additions & 1 deletion internal/compiler/fileInclude.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/microsoft/typescript-go/internal/core"
"github.com/microsoft/typescript-go/internal/diagnostics"
"github.com/microsoft/typescript-go/internal/module"
"github.com/microsoft/typescript-go/internal/scanner"
"github.com/microsoft/typescript-go/internal/tsoptions"
"github.com/microsoft/typescript-go/internal/tspath"
)
Expand Down Expand Up @@ -57,7 +58,11 @@ type referenceFileLocation struct {

func (r *referenceFileLocation) text() string {
if r.node != nil {
return r.node.Text()
if !ast.NodeIsSynthesized(r.node) {
return r.file.Text()[scanner.SkipTrivia(r.file.Text(), r.node.Loc.Pos()):r.node.End()]
} else {
return fmt.Sprintf(`"%s"`, r.node.Text())
}
} else {
return r.file.Text()[r.ref.Pos():r.ref.End()]
}
Expand Down
12 changes: 6 additions & 6 deletions internal/compiler/fileloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -610,19 +610,19 @@ func (p *fileLoader) pathForLibFile(name string) *LibFile {

path := tspath.CombinePaths(p.defaultLibraryPath, name)
replaced := false
if p.opts.Config.CompilerOptions().LibReplacement.IsTrue() {
if p.opts.Config.CompilerOptions().LibReplacement.IsTrue() && name != "lib.d.ts" {
libraryName := getLibraryNameFromLibFileName(name)
resolveFrom := getInferredLibraryNameResolveFrom(p.opts.Config.CompilerOptions(), p.opts.Host.GetCurrentDirectory(), name)
resolution, trace := p.resolver.ResolveModuleName(libraryName, resolveFrom, core.ModuleKindCommonJS, nil)
if resolution.IsResolved() {
path = resolution.ResolvedFileName
replaced = true
p.pathForLibFileResolutions.LoadOrStore(p.toPath(resolveFrom), &libResolution{
libraryName: libraryName,
resolution: resolution,
trace: trace,
})
}
p.pathForLibFileResolutions.LoadOrStore(p.toPath(resolveFrom), &libResolution{
libraryName: libraryName,
resolution: resolution,
trace: trace,
})
}

libPath, _ := p.pathForLibFileCache.LoadOrStore(name, &LibFile{name, path, replaced})
Expand Down
5 changes: 2 additions & 3 deletions internal/compiler/program.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ func equalCheckJSDirectives(d1 *ast.CheckJsDirective, d2 *ast.CheckJsDirective)

func (p *Program) SourceFiles() []*ast.SourceFile { return p.files }
func (p *Program) Options() *core.CompilerOptions { return p.opts.Config.CompilerOptions() }
func (p *Program) GetRootFileNames() []string { return p.opts.Config.FileNames() }
func (p *Program) Host() CompilerHost { return p.opts.Host }
func (p *Program) GetConfigFileParsingDiagnostics() []*ast.Diagnostic {
return slices.Clip(p.opts.Config.GetConfigFileParsingDiagnostics())
Expand Down Expand Up @@ -1364,9 +1365,7 @@ func CombineEmitResults(results []*EmitResult) *EmitResult {
result.EmitSkipped = true
}
result.Diagnostics = append(result.Diagnostics, emitResult.Diagnostics...)
if emitResult.EmittedFiles != nil {
result.EmittedFiles = append(result.EmittedFiles, emitResult.EmittedFiles...)
}
result.EmittedFiles = append(result.EmittedFiles, emitResult.EmittedFiles...)
if emitResult.SourceMaps != nil {
result.SourceMaps = append(result.SourceMaps, emitResult.SourceMaps...)
}
Expand Down
6 changes: 6 additions & 0 deletions internal/compiler/projectreferencedtsfakinghost.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package compiler

import (
"strings"
"time"

"github.com/microsoft/typescript-go/internal/collections"
"github.com/microsoft/typescript-go/internal/core"
Expand Down Expand Up @@ -82,6 +83,11 @@ func (fs *projectReferenceDtsFakingVfs) Remove(path string) error {
panic("should not be called by resolver")
}

// Chtimes implements vfs.FS.
func (fs *projectReferenceDtsFakingVfs) Chtimes(path string, aTime time.Time, mTime time.Time) error {
panic("should not be called by resolver")
}

// DirectoryExists implements vfs.FS.
func (fs *projectReferenceDtsFakingVfs) DirectoryExists(path string) bool {
if fs.projectReferenceFileMapper.opts.Host.FS().DirectoryExists(path) {
Expand Down
15 changes: 15 additions & 0 deletions internal/core/buildoptions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package core

type BuildOptions struct {
_ noCopy

Dry Tristate `json:"dry,omitzero"`
Force Tristate `json:"force,omitzero"`
Verbose Tristate `json:"verbose,omitzero"`
StopBuildOnErrors Tristate `json:"stopBuildOnErrors,omitzero"`

// CompilerOptions are not parsed here and will be available on ParsedBuildCommandLine

// Internal fields
Clean Tristate `json:"clean,omitzero"`
}
3 changes: 1 addition & 2 deletions internal/core/compileroptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ type CompilerOptions struct {
AllowUnusedLabels Tristate `json:"allowUnusedLabels,omitzero"`
AssumeChangesOnlyAffectDirectDependencies Tristate `json:"assumeChangesOnlyAffectDirectDependencies,omitzero"`
AlwaysStrict Tristate `json:"alwaysStrict,omitzero"`
Build Tristate `json:"build,omitzero"`
CheckJs Tristate `json:"checkJs,omitzero"`
CustomConditions []string `json:"customConditions,omitzero"`
Composite Tristate `json:"composite,omitzero"`
Expand Down Expand Up @@ -142,7 +141,7 @@ type CompilerOptions struct {
Version Tristate `json:"version,omitzero"`
Watch Tristate `json:"watch,omitzero"`
ShowConfig Tristate `json:"showConfig,omitzero"`
TscBuild Tristate `json:"tscBuild,omitzero"`
Build Tristate `json:"build,omitzero"`
Help Tristate `json:"help,omitzero"`
All Tristate `json:"all,omitzero"`

Expand Down
4 changes: 2 additions & 2 deletions internal/core/projectreference.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ type ProjectReference struct {
}

func ResolveProjectReferencePath(ref *ProjectReference) string {
return resolveConfigFileNameOfProjectReference(ref.Path)
return ResolveConfigFileNameOfProjectReference(ref.Path)
}

func resolveConfigFileNameOfProjectReference(path string) string {
func ResolveConfigFileNameOfProjectReference(path string) string {
if tspath.FileExtensionIs(path, tspath.ExtensionJson) {
return path
}
Expand Down
8 changes: 4 additions & 4 deletions internal/diagnostics/diagnostics_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions internal/diagnostics/extraDiagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,21 @@
"A JSDoc '@type' tag may not occur with a '@param' or '@returns' tag.": {
"category": "Error",
"code": 8040
},
"Failed to delete file '{0}'.": {
"category": "Message",
"code": 6353
},
"Project '{0}' is out of date because config file does not exist.": {
"category": "Message",
"code": 6401
},
"Project '{0}' is out of date because input '{1}' does not exist.": {
"category": "Message",
"code": 6420
},
"Failed to update timestamp of file '{0}'.": {
"category": "Message",
"code": 5074
}
}
13 changes: 12 additions & 1 deletion internal/diagnosticwriter/diagnosticwriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ func FormatDiagnosticsWithColorAndContext(output io.Writer, diags []*ast.Diagnos
if len(diags) == 0 {
return
}

for i, diagnostic := range diags {
if i > 0 {
fmt.Fprint(output, formatOpts.NewLine)
Expand Down Expand Up @@ -386,3 +385,15 @@ func WriteFormatDiagnostic(output io.Writer, diagnostic *ast.Diagnostic, formatO
WriteFlattenedDiagnosticMessage(output, diagnostic, formatOpts.NewLine)
fmt.Fprint(output, formatOpts.NewLine)
}

func FormatDiagnosticsStatusWithColorAndTime(output io.Writer, time string, diag *ast.Diagnostic, formatOpts *FormattingOptions) {
fmt.Fprint(output, "[")
writeWithStyleAndReset(output, time, foregroundColorEscapeGrey)
fmt.Fprint(output, "] ")
WriteFlattenedDiagnosticMessage(output, diag, formatOpts.NewLine)
}

func FormatDiagnosticsStatusAndTime(output io.Writer, time string, diag *ast.Diagnostic, formatOpts *FormattingOptions) {
fmt.Fprint(output, time, " - ")
WriteFlattenedDiagnosticMessage(output, diag, formatOpts.NewLine)
}
Loading
Loading