@@ -11,47 +11,29 @@ import (
11
11
"github.com/microsoft/typescript-go/internal/vfs"
12
12
)
13
13
14
- func (p * CommandLineParser ) AlternateMode () * AlternateModeDiagnostics {
14
+ func (p * commandLineParser ) AlternateMode () * AlternateModeDiagnostics {
15
15
return p .workerDiagnostics .didYouMean .alternateMode
16
16
}
17
17
18
- func (p * CommandLineParser ) OptionsDeclarations () []* CommandLineOption {
18
+ func (p * commandLineParser ) OptionsDeclarations () []* CommandLineOption {
19
19
return p .workerDiagnostics .didYouMean .OptionDeclarations
20
20
}
21
21
22
- func (p * CommandLineParser ) UnknownOptionDiagnostic () * diagnostics.Message {
22
+ func (p * commandLineParser ) UnknownOptionDiagnostic () * diagnostics.Message {
23
23
return p .workerDiagnostics .didYouMean .UnknownOptionDiagnostic
24
24
}
25
25
26
- func (p * CommandLineParser ) UnknownDidYouMeanDiagnostic () * diagnostics.Message {
26
+ func (p * commandLineParser ) UnknownDidYouMeanDiagnostic () * diagnostics.Message {
27
27
return p .workerDiagnostics .didYouMean .UnknownDidYouMeanDiagnostic
28
28
}
29
29
30
- func (p * CommandLineParser ) GetOptionsNameMap () * NameMap {
31
- p .workerDiagnostics .optionsNameMapOnce .Do (func () {
32
- optionsNames := map [string ]* CommandLineOption {}
33
- shortOptionNames := map [string ]string {}
34
- for _ , option := range p .workerDiagnostics .didYouMean .OptionDeclarations {
35
- optionsNames [strings .ToLower (option .Name )] = option
36
- if option .shortName != "" {
37
- shortOptionNames [option .shortName ] = option .Name
38
- }
39
- }
40
- p .workerDiagnostics .optionsNameMap = & NameMap {
41
- optionsNames : optionsNames ,
42
- shortOptionNames : shortOptionNames ,
43
- }
44
- })
45
- return p .workerDiagnostics .optionsNameMap
46
- }
47
-
48
- type CommandLineParser struct {
30
+ type commandLineParser struct {
49
31
workerDiagnostics * ParseCommandLineWorkerDiagnostics
32
+ optionsMap * NameMap
50
33
fs vfs.FS
51
34
options map [string ]any
52
- // todo: watchOptions map[string]any
53
- fileNames []string
54
- errors []* ast.Diagnostic
35
+ fileNames []string
36
+ errors []* ast.Diagnostic
55
37
}
56
38
57
39
func ParseCommandLine (
@@ -63,14 +45,16 @@ func ParseCommandLine(
63
45
}
64
46
parser := parseCommandLineWorker (CompilerOptionsDidYouMeanDiagnostics , commandLine , host .FS ())
65
47
optionsWithAbsolutePaths := convertToOptionsWithAbsolutePaths (parser .options , commandLineCompilerOptionsMap , host .GetCurrentDirectory ())
66
- o , d := convertOptionsFromJson (commandLineCompilerOptionsMap , optionsWithAbsolutePaths , host .GetCurrentDirectory (), & core.CompilerOptions {})
48
+ compilerOptions , d1 := convertOptionsFromJson (commandLineCompilerOptionsMap , optionsWithAbsolutePaths , host .GetCurrentDirectory (), & compilerOptionsParser {& core.CompilerOptions {}, true })
49
+ watchOptions , d2 := convertOptionsFromJson (commandLineCompilerOptionsMap , optionsWithAbsolutePaths , host .GetCurrentDirectory (), & watchOptionsParser {& core.WatchOptions {}, true })
67
50
return & ParsedCommandLine {
68
51
ParsedConfig : & core.ParsedOptions {
69
- CompilerOptions : o ,
52
+ CompilerOptions : compilerOptions .CompilerOptions ,
53
+ WatchOptions : watchOptions .WatchOptions ,
70
54
FileNames : parser .fileNames ,
71
55
},
72
56
ConfigFile : nil ,
73
- Errors : append (parser .errors , d ... ),
57
+ Errors : append (append ( parser .errors , d1 ... ), d2 ... ),
74
58
Raw : parser .options , // todo: keep optionsBase incase needed later
75
59
CompileOnSave : nil ,
76
60
}
@@ -80,19 +64,20 @@ func parseCommandLineWorker(
80
64
parseCommandLineWithDiagnostics * ParseCommandLineWorkerDiagnostics ,
81
65
commandLine []string ,
82
66
fs vfs.FS ,
83
- ) * CommandLineParser {
84
- parser := & CommandLineParser {
67
+ ) * commandLineParser {
68
+ parser := & commandLineParser {
85
69
fs : fs ,
86
70
workerDiagnostics : parseCommandLineWithDiagnostics ,
87
71
fileNames : []string {},
88
72
options : map [string ]any {},
89
73
errors : []* ast.Diagnostic {},
90
74
}
75
+ parser .optionsMap = GetNameMapFromList (parser .OptionsDeclarations ())
91
76
parser .parseStrings (commandLine )
92
77
return parser
93
78
}
94
79
95
- func (p * CommandLineParser ) parseStrings (args []string ) {
80
+ func (p * commandLineParser ) parseStrings (args []string ) {
96
81
i := 0
97
82
for i < len (args ) {
98
83
s := args [i ]
@@ -105,17 +90,16 @@ func (p *CommandLineParser) parseStrings(args []string) {
105
90
p .parseResponseFile (s [1 :])
106
91
case '-' :
107
92
inputOptionName := getInputOptionName (s )
108
- opt := p .GetOptionsNameMap () .GetOptionDeclarationFromName (inputOptionName , true /*allowShort*/ )
93
+ opt := p .optionsMap .GetOptionDeclarationFromName (inputOptionName , true /*allowShort*/ )
109
94
if opt != nil {
110
- i = p .parseOptionValue (args , i , opt )
95
+ i = p .parseOptionValue (args , i , opt , nil )
111
96
} else {
112
- // todo: watch options not yet implemented
113
- // watchOpt := getOptionDeclarationFromName(watchOptionsDidYouMeanDiagnostics.getOptionsNameMap, inputOptionName, /*allowShort*/ true);
114
- // if (watchOpt != nil) {
115
- // i := parser.parseOptionValue(args, i, watchOptionsDidYouMeanDiagnostics, watchOpt, watchOptions, errors);
116
- // } else {
117
- p .errors = append (p .errors , p .createUnknownOptionError (inputOptionName , s , nil , nil ))
118
- // }
97
+ watchOpt := WatchNameMap .GetOptionDeclarationFromName (inputOptionName , true /*allowShort*/ )
98
+ if watchOpt != nil {
99
+ i = p .parseOptionValue (args , i , watchOpt , watchOptionsDidYouMeanDiagnostics .OptionTypeMismatchDiagnostic )
100
+ } else {
101
+ p .errors = append (p .errors , p .createUnknownOptionError (inputOptionName , s , nil , nil ))
102
+ }
119
103
}
120
104
default :
121
105
p .fileNames = append (p .fileNames , s )
@@ -128,7 +112,7 @@ func getInputOptionName(input string) string {
128
112
return strings .ToLower (strings .TrimLeft (strings .TrimLeft (input , "-" ), "-" ))
129
113
}
130
114
131
- func (p * CommandLineParser ) parseResponseFile (fileName string ) {
115
+ func (p * commandLineParser ) parseResponseFile (fileName string ) {
132
116
fileContents , errors := TryReadFile (fileName , func (fileName string ) (string , bool ) {
133
117
if p .fs == nil {
134
118
return "" , false
@@ -188,12 +172,13 @@ func TryReadFile(fileName string, readFile func(string) (string, bool), errors [
188
172
return text , errors
189
173
}
190
174
191
- func (p * CommandLineParser ) parseOptionValue (
175
+ func (p * commandLineParser ) parseOptionValue (
192
176
args []string ,
193
177
i int ,
194
178
opt * CommandLineOption ,
179
+ diag * diagnostics.Message ,
195
180
) int {
196
- if opt .isTSConfigOnly && i <= len (args ) {
181
+ if opt .IsTSConfigOnly && i <= len (args ) {
197
182
optValue := ""
198
183
if i < len (args ) {
199
184
optValue = args [i ]
@@ -221,7 +206,10 @@ func (p *CommandLineParser) parseOptionValue(
221
206
// Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
222
207
if i >= len (args ) {
223
208
if opt .Kind != "boolean" {
224
- p .errors = append (p .errors , ast .NewCompilerDiagnostic (p .workerDiagnostics .OptionTypeMismatchDiagnostic , opt .Name , getCompilerOptionValueTypeString (opt )))
209
+ if diag == nil {
210
+ diag = p .workerDiagnostics .OptionTypeMismatchDiagnostic
211
+ }
212
+ p .errors = append (p .errors , ast .NewCompilerDiagnostic (diag , opt .Name , getCompilerOptionValueTypeString (opt )))
225
213
if opt .Kind == "list" {
226
214
p .options [opt .Name ] = []string {}
227
215
} else if opt .Kind == "enum" {
@@ -257,13 +245,17 @@ func (p *CommandLineParser) parseOptionValue(
257
245
}
258
246
case "string" :
259
247
val , err := validateJsonOptionValue (opt , args [i ], nil , nil )
260
- p .options [opt .Name ] = val
261
- p .errors = append (p .errors , err ... )
248
+ if err == nil {
249
+ p .options [opt .Name ] = val
250
+ } else {
251
+ p .errors = append (p .errors , err ... )
252
+ }
262
253
i ++
263
254
case "list" :
264
- result := p .parseListTypeOption (opt , args [i ])
255
+ result , err := p .parseListTypeOption (opt , args [i ])
265
256
p .options [opt .Name ] = result
266
- if len (result ) != 0 {
257
+ p .errors = append (p .errors , err ... )
258
+ if len (result ) > 0 || len (err ) > 0 {
267
259
i ++
268
260
}
269
261
case "listOrElement" :
@@ -283,10 +275,8 @@ func (p *CommandLineParser) parseOptionValue(
283
275
return i
284
276
}
285
277
286
- func (p * CommandLineParser ) parseListTypeOption (opt * CommandLineOption , value string ) []string {
287
- elements , errors := ParseListTypeOption (opt , value )
288
- p .errors = append (p .errors , errors ... )
289
- return elements
278
+ func (p * commandLineParser ) parseListTypeOption (opt * CommandLineOption , value string ) ([]string , []* ast.Diagnostic ) {
279
+ return ParseListTypeOption (opt , value )
290
280
}
291
281
292
282
func ParseListTypeOption (opt * CommandLineOption , value string ) ([]string , []* ast.Diagnostic ) {
@@ -297,7 +287,9 @@ func ParseListTypeOption(opt *CommandLineOption, value string) ([]string, []*ast
297
287
}
298
288
if opt .Kind == "listOrElement" && ! strings .ContainsRune (value , ',' ) {
299
289
val , err := validateJsonOptionValue (opt , value , nil , nil )
300
- errors = append (errors , err ... )
290
+ if err != nil {
291
+ return []string {}, err
292
+ }
301
293
return []string {val .(string )}, errors
302
294
}
303
295
if value == "" {
@@ -308,30 +300,27 @@ func ParseListTypeOption(opt *CommandLineOption, value string) ([]string, []*ast
308
300
case "string" :
309
301
elements := core .Filter (core .Map (values , func (v string ) string {
310
302
val , err := validateJsonOptionValue (opt .Elements (), v , nil , nil )
303
+ if _ , ok := val .(string ); ok {
304
+ return val .(string )
305
+ }
311
306
errors = append (errors , err ... )
312
- return val .( string )
307
+ return ""
313
308
}), isDefined )
314
309
return elements , errors
315
310
case "boolean" , "object" , "number" :
316
311
// do nothing: only string and enum/object types currently allowed as list entries
317
312
// !!! we don't actually have number list options, so I didn't implement number list parsing
318
313
panic ("List of " + opt .Elements ().Kind + " is not yet supported." )
319
314
default :
320
- result := core .Map (values , func (v string ) string {
315
+ result := core .Filter ( core . Map (values , func (v string ) string {
321
316
val , err := convertJsonOptionOfEnumType (opt .Elements (), strings .TrimFunc (v , stringutil .IsWhiteSpaceLike ), nil , nil )
322
317
if _ , ok := val .(string ); ok {
323
318
return val .(string )
324
319
}
325
320
errors = append (errors , err ... )
326
321
return ""
327
- })
328
- var mappedValues []string
329
- for _ , v := range result {
330
- if isDefined (v ) {
331
- mappedValues = append (mappedValues , v )
332
- }
333
- }
334
- return mappedValues , errors
322
+ }), isDefined )
323
+ return result , errors
335
324
}
336
325
}
337
326
0 commit comments