Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/core/parsedoptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package core
type ParsedOptions struct {
CompilerOptions *CompilerOptions `json:"compilerOptions"`
WatchOptions *WatchOptions `json:"watchOptions"`
TypeAcquisition *TypeAcquisition `json:"typeAcquisition"`

FileNames []string `json:"fileNames"`
ProjectReferences []ProjectReference `json:"projectReferences"`
Expand Down
8 changes: 8 additions & 0 deletions internal/core/typeacquisition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package core

type TypeAcquisition struct {
Enable Tristate `json:"enable,omitzero"`
Include []string `json:"include,omitzero"`
Exclude []string `json:"exclude,omitzero"`
DisableFilenameBasedTypeAcquisition Tristate `json:"disableFilenameBasedTypeAcquisition,omitzero"`
}
27 changes: 27 additions & 0 deletions internal/execute/tsc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,30 @@ func TestExtends(t *testing.T) {
c.verify(t, "extends")
}
}

func TestTypeAcquisition(t *testing.T) {
t.Parallel()
if !bundled.Embedded {
// Without embedding, we'd need to read all of the lib files out from disk into the MapFS.
// Just skip this for now.
t.Skip("bundled files are not embedded")
}
(&tscInput{
subScenario: "parse tsconfig with typeAcquisition",
sys: newTestSys(FileMap{"/home/src/workspaces/project/tsconfig.json": `{
"compilerOptions": {
"composite": true,
"noEmit": true,
},
"typeAcquisition": {
"enable": true,
"include": ["0.d.ts", "1.d.ts"],
"exclude": ["0.js", "1.js"],
"disableFilenameBasedTypeAcquisition": true,
},
}`},
"/home/src/workspaces/project",
),
commandLineArgs: []string{},
}).verify(t, "typeAcquisition")
}
29 changes: 29 additions & 0 deletions internal/tsoptions/declstypeacquisition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package tsoptions

var typeAcquisitionDeclaration = &CommandLineOption{
Name: "typeAcquisition",
Kind: CommandLineOptionTypeObject,
ElementOptions: commandLineOptionsToMap(typeAcquisitionDecls),
}

// Do not delete this without updating the website's tsconfig generation.
var typeAcquisitionDecls = []*CommandLineOption{
{
Name: "enable",
Kind: CommandLineOptionTypeBoolean,
DefaultValueDescription: false,
},
{
Name: "include",
Kind: CommandLineOptionTypeList,
},
{
Name: "exclude",
Kind: CommandLineOptionTypeList,
},
{
Name: "disableFilenameBasedTypeAcquisition",
Kind: CommandLineOptionTypeBoolean,
DefaultValueDescription: false,
},
}
31 changes: 31 additions & 0 deletions internal/tsoptions/parsinghelpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ func parseJsonToStringKey(json any) *collections.OrderedMap[string, any] {
if v, ok := m.Get("excludes"); ok {
result.Set("excludes", v)
}
if v, ok := m.Get("typeAcquisition"); ok {
result.Set("typeAcquisition", v)
}
}
return result
}
Expand All @@ -133,6 +136,14 @@ func (o *watchOptionsParser) ParseOption(key string, value any) []*ast.Diagnosti
return ParseWatchOptions(key, value, o.WatchOptions)
}

type typeAcquisitionParser struct {
*core.TypeAcquisition
}

func (o *typeAcquisitionParser) ParseOption(key string, value any) []*ast.Diagnostic {
return ParseTypeAcquisition(key, value, o.TypeAcquisition)
}

func ParseCompilerOptions(key string, value any, allOptions *core.CompilerOptions) []*ast.Diagnostic {
if value == nil {
return nil
Expand Down Expand Up @@ -426,6 +437,26 @@ func ParseWatchOptions(key string, value any, allOptions *core.WatchOptions) []*
return nil
}

func ParseTypeAcquisition(key string, value any, allOptions *core.TypeAcquisition) []*ast.Diagnostic {
if value == nil {
return nil
}
if allOptions == nil {
return nil
}
switch key {
case "enable":
allOptions.Enable = parseTristate(value)
case "include":
allOptions.Include = parseStringArray(value)
case "exclude":
allOptions.Exclude = parseStringArray(value)
case "disableFilenameBasedTypeAcquisition":
allOptions.DisableFilenameBasedTypeAcquisition = parseTristate(value)
}
return nil
}

// mergeCompilerOptions merges the source compiler options into the target compiler options.
// Fields in the source options will overwrite the corresponding fields in the target options.
func mergeCompilerOptions(targetOptions, sourceOptions *core.CompilerOptions) *core.CompilerOptions {
Expand Down
109 changes: 69 additions & 40 deletions internal/tsoptions/tsconfigparsing.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ var tsconfigRootOptionsMap = &CommandLineOption{
Kind: CommandLineOptionTypeObject,
ElementOptions: commandLineOptionsToMap([]*CommandLineOption{
compilerOptionsDeclaration,
// watchOptionsDeclaration,
typeAcquisitionDeclaration,
extendsOptionDeclaration,
{
Name: "references",
Expand Down Expand Up @@ -107,8 +109,8 @@ type ExtendedConfigCacheEntry struct {
type parsedTsconfig struct {
raw any
options *core.CompilerOptions
// watchOptions *compiler.WatchOptions
// typeAcquisition *compiler.TypeAcquisition
// watchOptions *core.WatchOptions
typeAcquisition *core.TypeAcquisition
// Note that the case of the config path has not yet been normalized, as no files have been imported into the project yet
extendedConfigPath any
}
Expand All @@ -119,8 +121,8 @@ func parseOwnConfigOfJsonSourceFile(
basePath string,
configFileName string,
) (*parsedTsconfig, []*ast.Diagnostic) {
options := getDefaultCompilerOptions(configFileName)
// var typeAcquisition *compiler.TypeAcquisition
compilerOptions := getDefaultCompilerOptions(configFileName)
var typeAcquisition *core.TypeAcquisition
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// var watchOptions *compiler.WatchOptions
var extendedConfigPath any
var rootCompilerOptions []*ast.PropertyName
Expand All @@ -139,7 +141,17 @@ func parseOwnConfigOfJsonSourceFile(
}
if parentOption != nil && parentOption.Name != "undefined" && value != nil {
if option != nil && option.Name != "" {
propertySetErrors = append(propertySetErrors, ParseCompilerOptions(option.Name, value, options)...)
var parseDiagnostics []*ast.Diagnostic
switch parentOption.Name {
case "compilerOptions":
parseDiagnostics = ParseCompilerOptions(option.Name, value, compilerOptions)
case "typeAcquisition":
if typeAcquisition == nil {
typeAcquisition = getDefaultTypeAcquisition(configFileName)
}
parseDiagnostics = ParseTypeAcquisition(option.Name, value, typeAcquisition)
}
propertySetErrors = append(propertySetErrors, parseDiagnostics...)
} else if keyText != "" {
if parentOption.ElementOptions != nil {
// !!! TODO: support suggestion
Expand Down Expand Up @@ -178,9 +190,9 @@ func parseOwnConfigOfJsonSourceFile(
// }
return &parsedTsconfig{
raw: json,
options: options,
options: compilerOptions,
// watchOptions: watchOptions,
// typeAcquisition: typeAcquisition,
typeAcquisition: typeAcquisition,
extendedConfigPath: extendedConfigPath,
}, errors
}
Expand Down Expand Up @@ -479,19 +491,19 @@ type tsConfigOptions struct {
notDefined string
}

func commandLineOptionsToMap(options []*CommandLineOption) map[string]*CommandLineOption {
func commandLineOptionsToMap(compilerOptions []*CommandLineOption) map[string]*CommandLineOption {
result := make(map[string]*CommandLineOption)
for i := range options {
result[(options[i]).Name] = options[i]
for i := range compilerOptions {
result[(compilerOptions[i]).Name] = compilerOptions[i]
}
return result
}

var commandLineCompilerOptionsMap map[string]*CommandLineOption = commandLineOptionsToMap(OptionsDeclarations)

func convertMapToOptions[O optionParser](options *collections.OrderedMap[string, any], result O) O {
func convertMapToOptions[O optionParser](compilerOptions *collections.OrderedMap[string, any], result O) O {
// this assumes any `key`, `value` pair in `options` will have `value` already be the correct type. this function should no error handling
for key, value := range options.Entries() {
for key, value := range compilerOptions.Entries() {
result.ParseOption(key, value)
}
return result
Expand Down Expand Up @@ -758,6 +770,14 @@ func getDefaultCompilerOptions(configFileName string) *core.CompilerOptions {
return options
}

func getDefaultTypeAcquisition(configFileName string) *core.TypeAcquisition {
options := &core.TypeAcquisition{}
if configFileName != "" && tspath.GetBaseFileName(configFileName) == "jsconfig.json" {
options.Enable = core.TSTrue
}
return options
}

func convertCompilerOptionsFromJsonWorker(jsonOptions any, basePath string, configFileName string) (*core.CompilerOptions, []*ast.Diagnostic) {
options := getDefaultCompilerOptions(configFileName)
_, errors := convertOptionsFromJson(commandLineCompilerOptionsMap, jsonOptions, basePath, &compilerOptionsParser{options})
Expand All @@ -767,6 +787,12 @@ func convertCompilerOptionsFromJsonWorker(jsonOptions any, basePath string, conf
return options, errors
}

func convertTypeAcquisitionFromJsonWorker(jsonOptions any, basePath string, configFileName string) (*core.TypeAcquisition, []*ast.Diagnostic) {
options := getDefaultTypeAcquisition(configFileName)
_, errors := convertOptionsFromJson(typeAcquisitionDeclaration.ElementOptions, jsonOptions, basePath, &typeAcquisitionParser{options})
return options, errors
}

func parseOwnConfigOfJson(
json *collections.OrderedMap[string, any],
host ParseConfigHost,
Expand All @@ -778,8 +804,8 @@ func parseOwnConfigOfJson(
errors = append(errors, ast.NewCompilerDiagnostic(diagnostics.Unknown_option_excludes_Did_you_mean_exclude))
}
options, err := convertCompilerOptionsFromJsonWorker(json.GetOrZero("compilerOptions"), basePath, configFileName)
errors = append(errors, err...)
// typeAcquisition := convertTypeAcquisitionFromJsonWorker(json.typeAcquisition, basePath, errors, configFileName)
typeAcquisition, err2 := convertTypeAcquisitionFromJsonWorker(json.GetOrZero("typeAcquisition"), basePath, configFileName)
errors = append(append(errors, err...), err2...)
// watchOptions := convertWatchOptionsFromJsonWorker(json.watchOptions, basePath, errors)
// json.compileOnSave = convertCompileOnSaveOptionFromJson(json, basePath, errors)
var extendedConfigPath []string
Expand All @@ -790,6 +816,7 @@ func parseOwnConfigOfJson(
parsedConfig := &parsedTsconfig{
raw: json,
options: options,
typeAcquisition: typeAcquisition,
extendedConfigPath: extendedConfigPath,
}
return parsedConfig, errors
Expand Down Expand Up @@ -1176,7 +1203,9 @@ func parseJsonConfigFileContentWorker(

return &ParsedCommandLine{
ParsedConfig: &core.ParsedOptions{
CompilerOptions: parsedConfig.options,
CompilerOptions: parsedConfig.options,
TypeAcquisition: parsedConfig.typeAcquisition,
// WatchOptions: nil,
FileNames: getFileNames(basePathForFileNames),
ProjectReferences: getProjectReferences(basePathForFileNames),
},
Expand Down Expand Up @@ -1321,43 +1350,43 @@ func substituteStringArrayWithConfigDirTemplate(list []string, basePath string)
}
}

func handleOptionConfigDirTemplateSubstitution(options *core.CompilerOptions, basePath string) {
if options == nil {
func handleOptionConfigDirTemplateSubstitution(compilerOptions *core.CompilerOptions, basePath string) {
if compilerOptions == nil {
return
}

// !!! don't hardcode this; use options declarations?

for v := range options.Paths.Values() {
for v := range compilerOptions.Paths.Values() {
substituteStringArrayWithConfigDirTemplate(v, basePath)
}

substituteStringArrayWithConfigDirTemplate(options.RootDirs, basePath)
substituteStringArrayWithConfigDirTemplate(options.TypeRoots, basePath)
substituteStringArrayWithConfigDirTemplate(compilerOptions.RootDirs, basePath)
substituteStringArrayWithConfigDirTemplate(compilerOptions.TypeRoots, basePath)

if startsWithConfigDirTemplate(options.GenerateCpuProfile) {
options.GenerateCpuProfile = getSubstitutedPathWithConfigDirTemplate(options.GenerateCpuProfile, basePath)
if startsWithConfigDirTemplate(compilerOptions.GenerateCpuProfile) {
compilerOptions.GenerateCpuProfile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.GenerateCpuProfile, basePath)
}
if startsWithConfigDirTemplate(options.GenerateTrace) {
options.GenerateTrace = getSubstitutedPathWithConfigDirTemplate(options.GenerateTrace, basePath)
if startsWithConfigDirTemplate(compilerOptions.GenerateTrace) {
compilerOptions.GenerateTrace = getSubstitutedPathWithConfigDirTemplate(compilerOptions.GenerateTrace, basePath)
}
if startsWithConfigDirTemplate(options.OutFile) {
options.OutFile = getSubstitutedPathWithConfigDirTemplate(options.OutFile, basePath)
if startsWithConfigDirTemplate(compilerOptions.OutFile) {
compilerOptions.OutFile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.OutFile, basePath)
}
if startsWithConfigDirTemplate(options.OutDir) {
options.OutDir = getSubstitutedPathWithConfigDirTemplate(options.OutDir, basePath)
if startsWithConfigDirTemplate(compilerOptions.OutDir) {
compilerOptions.OutDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.OutDir, basePath)
}
if startsWithConfigDirTemplate(options.RootDir) {
options.RootDir = getSubstitutedPathWithConfigDirTemplate(options.RootDir, basePath)
if startsWithConfigDirTemplate(compilerOptions.RootDir) {
compilerOptions.RootDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.RootDir, basePath)
}
if startsWithConfigDirTemplate(options.TsBuildInfoFile) {
options.TsBuildInfoFile = getSubstitutedPathWithConfigDirTemplate(options.TsBuildInfoFile, basePath)
if startsWithConfigDirTemplate(compilerOptions.TsBuildInfoFile) {
compilerOptions.TsBuildInfoFile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.TsBuildInfoFile, basePath)
}
if startsWithConfigDirTemplate(options.BaseUrl) {
options.BaseUrl = getSubstitutedPathWithConfigDirTemplate(options.BaseUrl, basePath)
if startsWithConfigDirTemplate(compilerOptions.BaseUrl) {
compilerOptions.BaseUrl = getSubstitutedPathWithConfigDirTemplate(compilerOptions.BaseUrl, basePath)
}
if startsWithConfigDirTemplate(options.DeclarationDir) {
options.DeclarationDir = getSubstitutedPathWithConfigDirTemplate(options.DeclarationDir, basePath)
if startsWithConfigDirTemplate(compilerOptions.DeclarationDir) {
compilerOptions.DeclarationDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.DeclarationDir, basePath)
}
}

Expand Down Expand Up @@ -1517,8 +1546,8 @@ func getFileNamesFromConfigSpecs(
return files
}

func GetSupportedExtensions(options *core.CompilerOptions, extraFileExtensions []fileExtensionInfo) [][]string {
needJSExtensions := options.GetAllowJS()
func GetSupportedExtensions(compilerOptions *core.CompilerOptions, extraFileExtensions []fileExtensionInfo) [][]string {
needJSExtensions := compilerOptions.GetAllowJS()
if len(extraFileExtensions) == 0 {
if needJSExtensions {
return tspath.AllSupportedExtensions
Expand All @@ -1543,8 +1572,8 @@ func GetSupportedExtensions(options *core.CompilerOptions, extraFileExtensions [
return extensions
}

func GetSupportedExtensionsWithJsonIfResolveJsonModule(options *core.CompilerOptions, supportedExtensions [][]string) [][]string {
if options == nil || !options.GetResolveJsonModule() {
func GetSupportedExtensionsWithJsonIfResolveJsonModule(compilerOptions *core.CompilerOptions, supportedExtensions [][]string) [][]string {
if compilerOptions == nil || !compilerOptions.GetResolveJsonModule() {
return supportedExtensions
}
if core.Same(supportedExtensions, tspath.AllSupportedExtensions) {
Expand Down
Loading