Skip to content

Commit e86ed12

Browse files
authored
Fix parsing of commandline string array (#1565)
1 parent 0caf18a commit e86ed12

File tree

143 files changed

+519
-1504
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

143 files changed

+519
-1504
lines changed

internal/fourslash/fourslash.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ func NewFourslash(t *testing.T, capabilities *lsproto.ClientCapabilities, conten
153153
compilerOptions := &core.CompilerOptions{
154154
SkipDefaultLibCheck: core.TSTrue,
155155
}
156-
harnessutil.SetCompilerOptionsFromTestConfig(t, testData.GlobalOptions, compilerOptions)
156+
harnessutil.SetCompilerOptionsFromTestConfig(t, testData.GlobalOptions, compilerOptions, rootDir)
157157

158158
inputReader, inputWriter := newLSPPipe()
159159
outputReader, outputWriter := newLSPPipe()

internal/incremental/snapshottobuildinfo.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,16 @@ func (t *toBuildInfo) toFileIdListId(set *collections.Set[tspath.Path]) BuildInf
9191
}
9292

9393
func (t *toBuildInfo) toRelativeToBuildInfoCompilerOptionValue(option *tsoptions.CommandLineOption, v any) any {
94-
if !option.IsFilePath {
95-
return v
96-
}
9794
if option.Kind == "list" {
98-
if arr, ok := v.([]string); ok {
99-
return core.Map(arr, t.relativeToBuildInfo)
95+
if option.Elements().IsFilePath {
96+
if arr, ok := v.([]string); ok {
97+
return core.Map(arr, t.relativeToBuildInfo)
98+
}
99+
}
100+
} else if option.IsFilePath {
101+
if str, ok := v.(string); ok && str != "" {
102+
return t.relativeToBuildInfo(v.(string))
100103
}
101-
} else if str, ok := v.(string); ok && str != "" {
102-
return t.relativeToBuildInfo(v.(string))
103104
}
104105
return v
105106
}

internal/testutil/harnessutil/harnessutil.go

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func CompileFiles(
9898

9999
// Parse harness and compiler options from the test configuration
100100
if testConfig != nil {
101-
setOptionsFromTestConfig(t, testConfig, compilerOptions, &harnessOptions)
101+
setOptionsFromTestConfig(t, testConfig, compilerOptions, &harnessOptions, currentDirectory)
102102
}
103103

104104
return CompileFilesEx(t, inputFiles, otherFiles, &harnessOptions, compilerOptions, currentDirectory, symlinks, tsconfig)
@@ -224,7 +224,7 @@ func CompileFilesEx(
224224
result.Repeat = func(testConfig TestConfiguration) *CompilationResult {
225225
newHarnessOptions := *harnessOptions
226226
newCompilerOptions := compilerOptions.Clone()
227-
setOptionsFromTestConfig(t, testConfig, newCompilerOptions, &newHarnessOptions)
227+
setOptionsFromTestConfig(t, testConfig, newCompilerOptions, &newHarnessOptions, currentDirectory)
228228
return CompileFilesEx(t, inputFiles, otherFiles, &newHarnessOptions, newCompilerOptions, currentDirectory, symlinks, tsconfig)
229229
}
230230
return result
@@ -255,15 +255,15 @@ var testLibFolderMap = sync.OnceValue(func() map[string]any {
255255
return testfs
256256
})
257257

258-
func SetCompilerOptionsFromTestConfig(t *testing.T, testConfig TestConfiguration, compilerOptions *core.CompilerOptions) {
258+
func SetCompilerOptionsFromTestConfig(t *testing.T, testConfig TestConfiguration, compilerOptions *core.CompilerOptions, currentDirectory string) {
259259
for name, value := range testConfig {
260260
if name == "typescriptversion" {
261261
continue
262262
}
263263

264264
commandLineOption := getCommandLineOption(name)
265265
if commandLineOption != nil {
266-
parsedValue := getOptionValue(t, commandLineOption, value)
266+
parsedValue := getOptionValue(t, commandLineOption, value, currentDirectory)
267267
errors := tsoptions.ParseCompilerOptions(commandLineOption.Name, parsedValue, compilerOptions)
268268
if len(errors) > 0 {
269269
t.Fatalf("Error parsing value '%s' for compiler option '%s'.", value, commandLineOption.Name)
@@ -272,15 +272,15 @@ func SetCompilerOptionsFromTestConfig(t *testing.T, testConfig TestConfiguration
272272
}
273273
}
274274

275-
func setOptionsFromTestConfig(t *testing.T, testConfig TestConfiguration, compilerOptions *core.CompilerOptions, harnessOptions *HarnessOptions) {
275+
func setOptionsFromTestConfig(t *testing.T, testConfig TestConfiguration, compilerOptions *core.CompilerOptions, harnessOptions *HarnessOptions, currentDirectory string) {
276276
for name, value := range testConfig {
277277
if name == "typescriptversion" {
278278
continue
279279
}
280280

281281
commandLineOption := getCommandLineOption(name)
282282
if commandLineOption != nil {
283-
parsedValue := getOptionValue(t, commandLineOption, value)
283+
parsedValue := getOptionValue(t, commandLineOption, value, currentDirectory)
284284
errors := tsoptions.ParseCompilerOptions(commandLineOption.Name, parsedValue, compilerOptions)
285285
if len(errors) > 0 {
286286
t.Fatalf("Error parsing value '%s' for compiler option '%s'.", value, commandLineOption.Name)
@@ -289,7 +289,7 @@ func setOptionsFromTestConfig(t *testing.T, testConfig TestConfiguration, compil
289289
}
290290
harnessOption := getHarnessOption(name)
291291
if harnessOption != nil {
292-
parsedValue := getOptionValue(t, harnessOption, value)
292+
parsedValue := getOptionValue(t, harnessOption, value, currentDirectory)
293293
parseHarnessOption(t, harnessOption.Name, parsedValue, harnessOptions)
294294
continue
295295
}
@@ -395,7 +395,10 @@ func parseHarnessOption(t *testing.T, key string, value any, harnessOptions *Har
395395
case "fileName":
396396
harnessOptions.FileName = value.(string)
397397
case "libFiles":
398-
harnessOptions.LibFiles = value.([]string)
398+
harnessOptions.LibFiles = make([]string, 0, len(value.([]any)))
399+
for _, v := range value.([]any) {
400+
harnessOptions.LibFiles = append(harnessOptions.LibFiles, v.(string))
401+
}
399402
case "noImplicitReferences":
400403
harnessOptions.NoImplicitReferences = value.(bool)
401404
case "currentDirectory":
@@ -421,9 +424,12 @@ func parseHarnessOption(t *testing.T, key string, value any, harnessOptions *Har
421424

422425
var deprecatedModuleResolution []string = []string{"node", "classic", "node10"}
423426

424-
func getOptionValue(t *testing.T, option *tsoptions.CommandLineOption, value string) tsoptions.CompilerOptionsValue {
427+
func getOptionValue(t *testing.T, option *tsoptions.CommandLineOption, value string, cwd string) tsoptions.CompilerOptionsValue {
425428
switch option.Kind {
426429
case tsoptions.CommandLineOptionTypeString:
430+
if option.IsFilePath {
431+
return tspath.GetNormalizedAbsolutePath(value, cwd)
432+
}
427433
return value
428434
case tsoptions.CommandLineOptionTypeNumber:
429435
numVal, err := strconv.Atoi(value)
@@ -448,6 +454,11 @@ func getOptionValue(t *testing.T, option *tsoptions.CommandLineOption, value str
448454
return enumVal
449455
case tsoptions.CommandLineOptionTypeList, tsoptions.CommandLineOptionTypeListOrElement:
450456
listVal, errors := tsoptions.ParseListTypeOption(option, value)
457+
if option.Elements().IsFilePath {
458+
return core.Map(listVal, func(item any) any {
459+
return tspath.GetNormalizedAbsolutePath(item.(string), cwd)
460+
})
461+
}
451462
if len(errors) > 0 {
452463
t.Fatalf("Unknown value '%s' for compiler option '%s'", value, option.Name)
453464
}
@@ -987,7 +998,7 @@ func getValueOfOptionString(t *testing.T, option string, value string) tsoptions
987998
if optionDecl.Name == "moduleResolution" && slices.Contains(deprecatedModuleResolution, strings.ToLower(value)) {
988999
return value
9891000
}
990-
return getOptionValue(t, optionDecl, value)
1001+
return getOptionValue(t, optionDecl, value, "/")
9911002
}
9921003

9931004
func getCommandLineOption(option string) *tsoptions.CommandLineOption {

internal/tsoptions/commandlineparser.go

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -282,59 +282,55 @@ func (p *commandLineParser) parseOptionValue(
282282
return i
283283
}
284284

285-
func (p *commandLineParser) parseListTypeOption(opt *CommandLineOption, value string) ([]string, []*ast.Diagnostic) {
285+
func (p *commandLineParser) parseListTypeOption(opt *CommandLineOption, value string) ([]any, []*ast.Diagnostic) {
286286
return ParseListTypeOption(opt, value)
287287
}
288288

289-
func ParseListTypeOption(opt *CommandLineOption, value string) ([]string, []*ast.Diagnostic) {
289+
func ParseListTypeOption(opt *CommandLineOption, value string) ([]any, []*ast.Diagnostic) {
290290
value = strings.TrimSpace(value)
291291
var errors []*ast.Diagnostic
292292
if strings.HasPrefix(value, "-") {
293-
return []string{}, errors
293+
return []any{}, errors
294294
}
295295
if opt.Kind == "listOrElement" && !strings.ContainsRune(value, ',') {
296296
val, err := validateJsonOptionValue(opt, value, nil, nil)
297297
if err != nil {
298-
return []string{}, err
298+
return []any{}, err
299299
}
300-
return []string{val.(string)}, errors
300+
return []any{val.(string)}, errors
301301
}
302302
if value == "" {
303-
return []string{}, errors
303+
return []any{}, errors
304304
}
305305
values := strings.Split(value, ",")
306306
switch opt.Elements().Kind {
307307
case "string":
308-
elements := core.Filter(core.Map(values, func(v string) string {
308+
elements := core.MapFiltered(values, func(v string) (any, bool) {
309309
val, err := validateJsonOptionValue(opt.Elements(), v, nil, nil)
310310
if s, ok := val.(string); ok && len(err) == 0 && s != "" {
311-
return s
311+
return s, true
312312
}
313313
errors = append(errors, err...)
314-
return ""
315-
}), isDefined)
314+
return "", false
315+
})
316316
return elements, errors
317317
case "boolean", "object", "number":
318318
// do nothing: only string and enum/object types currently allowed as list entries
319319
// !!! we don't actually have number list options, so I didn't implement number list parsing
320320
panic("List of " + opt.Elements().Kind + " is not yet supported.")
321321
default:
322-
result := core.Filter(core.Map(values, func(v string) string {
322+
result := core.MapFiltered(values, func(v string) (any, bool) {
323323
val, err := convertJsonOptionOfEnumType(opt.Elements(), strings.TrimFunc(v, stringutil.IsWhiteSpaceLike), nil, nil)
324324
if s, ok := val.(string); ok && len(err) == 0 && s != "" {
325-
return s
325+
return s, true
326326
}
327327
errors = append(errors, err...)
328-
return ""
329-
}), isDefined)
328+
return "", false
329+
})
330330
return result, errors
331331
}
332332
}
333333

334-
func isDefined(s string) bool {
335-
return s != ""
336-
}
337-
338334
func convertJsonOptionOfEnumType(
339335
opt *CommandLineOption,
340336
value string,

internal/tsoptions/parsinghelpers.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -564,16 +564,18 @@ func convertToOptionsWithAbsolutePaths(optionsBase *collections.OrderedMap[strin
564564

565565
func ConvertOptionToAbsolutePath(o string, v any, optionMap CommandLineOptionNameMap, cwd string) (any, bool) {
566566
option := optionMap.Get(o)
567-
if option == nil || !option.IsFilePath {
567+
if option == nil {
568568
return nil, false
569569
}
570570
if option.Kind == "list" {
571-
if arr, ok := v.([]string); ok {
572-
return core.Map(arr, func(item string) string {
573-
return tspath.GetNormalizedAbsolutePath(item, cwd)
574-
}), true
571+
if option.Elements().IsFilePath {
572+
if arr, ok := v.([]string); ok {
573+
return core.Map(arr, func(item string) string {
574+
return tspath.GetNormalizedAbsolutePath(item, cwd)
575+
}), true
576+
}
575577
}
576-
} else {
578+
} else if option.IsFilePath {
577579
return tspath.GetNormalizedAbsolutePath(v.(string), cwd), true
578580
}
579581
return nil, false

testdata/baselines/reference/submodule/compiler/declarationEmitHasTypesRefOnNamespaceUse.errors.txt

Lines changed: 0 additions & 17 deletions
This file was deleted.

testdata/baselines/reference/submodule/compiler/declarationEmitHasTypesRefOnNamespaceUse.errors.txt.diff

Lines changed: 0 additions & 21 deletions
This file was deleted.

testdata/baselines/reference/submodule/compiler/declarationEmitHasTypesRefOnNamespaceUse.symbols

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,15 @@
33
=== /src/index.ts ===
44
class Src implements NS.Dep { }
55
>Src : Symbol(Src, Decl(index.ts, 0, 0))
6+
>NS.Dep : Symbol(Dep, Decl(dep.d.ts, 0, 22))
7+
>NS : Symbol(NS, Decl(dep.d.ts, 0, 0))
8+
>Dep : Symbol(Dep, Decl(dep.d.ts, 0, 22))
69

10+
=== /deps/dep/dep.d.ts ===
11+
declare namespace NS {
12+
>NS : Symbol(NS, Decl(dep.d.ts, 0, 0))
13+
14+
interface Dep {
15+
>Dep : Symbol(Dep, Decl(dep.d.ts, 0, 22))
16+
}
17+
}

testdata/baselines/reference/submodule/compiler/declarationEmitHasTypesRefOnNamespaceUse.symbols.diff

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,10 @@
55
class Src implements NS.Dep { }
66
>Src : Symbol(Src, Decl(index.ts, 0, 0))
77
->NS.Dep : Symbol(NS.Dep, Decl(dep.d.ts, 0, 22))
8-
->NS : Symbol(NS, Decl(dep.d.ts, 0, 0))
8+
+>NS.Dep : Symbol(Dep, Decl(dep.d.ts, 0, 22))
9+
>NS : Symbol(NS, Decl(dep.d.ts, 0, 0))
910
->Dep : Symbol(NS.Dep, Decl(dep.d.ts, 0, 22))
10-
-
11-
-=== /deps/dep/dep.d.ts ===
12-
-declare namespace NS {
13-
->NS : Symbol(NS, Decl(dep.d.ts, 0, 0))
14-
-
15-
- interface Dep {
16-
->Dep : Symbol(Dep, Decl(dep.d.ts, 0, 22))
17-
- }
18-
-}
19-
+
11+
+>Dep : Symbol(Dep, Decl(dep.d.ts, 0, 22))
12+
13+
=== /deps/dep/dep.d.ts ===
14+
declare namespace NS {

testdata/baselines/reference/submodule/compiler/declarationEmitHasTypesRefOnNamespaceUse.types

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,9 @@ class Src implements NS.Dep { }
55
>Src : Src
66
>NS : any
77

8+
=== /deps/dep/dep.d.ts ===
9+
10+
declare namespace NS {
11+
interface Dep {
12+
}
13+
}

0 commit comments

Comments
 (0)