-
Notifications
You must be signed in to change notification settings - Fork 996
compileopts: improve error reporting of unsupported flags #1073
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
Changes from 4 commits
be9e804
e85d31c
bdd53df
2e604f6
27da1cc
7d50725
5a60cd1
2b963e0
da72da3
9c1f171
49dac08
41e3a7b
688e741
0e30e81
a91f5b6
2c07a2c
8efe5d1
1430c6c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,25 @@ | ||
| package compileopts | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "strings" | ||
| ) | ||
|
|
||
| var ( | ||
| validGCOptions = []string{"none", "leaking", "extalloc", "conservative"} | ||
| validSchedulerOptions = []string{"tasks", "coroutines"} | ||
| validPrintSizeOptions = []string{"none", "short", "full"} | ||
| // ErrGCInvalidOption is an error raised if gc option is not valid | ||
| ErrGCInvalidOption = fmt.Errorf(`invalid gc option: valid values are %s`, | ||
| strings.Join(validGCOptions, ", ")) | ||
| // ErrSchedulerInvalidOption is an error raised if scheduler option is not valid | ||
| ErrSchedulerInvalidOption = fmt.Errorf(`invalid scheduler option: valid values are %s`, | ||
| strings.Join(validSchedulerOptions, ", ")) | ||
| //ErrPrintSizeInvalidOption is an error raised if size option is not valid | ||
niaow marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ErrPrintSizeInvalidOption = fmt.Errorf(`invalid size option: valid values are %s`, | ||
| strings.Join(validPrintSizeOptions, ", ")) | ||
| ) | ||
niaow marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // Options contains extra options to give to the compiler. These options are | ||
| // usually passed from the command line. | ||
| type Options struct { | ||
|
|
@@ -21,3 +41,42 @@ type Options struct { | |
| TestConfig TestConfig | ||
| Programmer string | ||
| } | ||
|
|
||
| // Verify performs a validation on the given options, raising an error is options are not valid | ||
niaow marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // In particular: | ||
| // ErrGCInvalidOption will be reised if gc is not valid | ||
niaow marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // ErrSchedulerInvalidOption will be reised if scheduler is not valid | ||
| // ErrPrintSizeInvalidOption will be reised if size is not valid | ||
niaow marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| func (o *Options) Verify() error { | ||
| if o.GC != "" { | ||
| valid := isInArray(validGCOptions, o.GC) | ||
| if !valid { | ||
| return ErrGCInvalidOption | ||
| } | ||
| } | ||
|
|
||
| if o.Scheduler != "" { | ||
| valid := isInArray(validSchedulerOptions, o.Scheduler) | ||
| if !valid { | ||
| return ErrSchedulerInvalidOption | ||
| } | ||
| } | ||
|
|
||
| if o.PrintSizes != "" { | ||
| valid := isInArray(validPrintSizeOptions, o.PrintSizes) | ||
| if !valid { | ||
| return ErrPrintSizeInvalidOption | ||
| } | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func isInArray(arr []string, item string) bool { | ||
| for _, i := range arr { | ||
| if i == item { | ||
| return true | ||
| } | ||
| } | ||
| return false | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| package compileopts_test | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/tinygo-org/tinygo/compileopts" | ||
| ) | ||
|
|
||
| func TestOptions_Verify(t *testing.T) { | ||
cebernardi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| testCases := []struct { | ||
| name string | ||
| opts compileopts.Options | ||
| expectedError error | ||
| }{ | ||
| { | ||
| name: "it returns no error if Options is empty", | ||
niaow marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| opts: compileopts.Options{}, | ||
| }, | ||
| { | ||
| name: "it returns an error if gc option is not valid", | ||
| opts: compileopts.Options{ | ||
| GC: "incorrect", | ||
| }, | ||
| expectedError: compileopts.ErrGCInvalidOption, | ||
| }, | ||
| { | ||
| name: "it returns no error if gc option is 'none'", | ||
| opts: compileopts.Options{ | ||
| GC: "none", | ||
| }, | ||
| }, | ||
| { | ||
| name: "it returns no error if gc option is 'leaking'", | ||
| opts: compileopts.Options{ | ||
| GC: "leaking", | ||
| }, | ||
| }, | ||
| { | ||
| name: "it returns no error if gc option is 'extalloc'", | ||
| opts: compileopts.Options{ | ||
| GC: "extalloc", | ||
| }, | ||
| }, | ||
| { | ||
| name: "it returns no error if gc option is 'conservative'", | ||
| opts: compileopts.Options{ | ||
| GC: "conservative", | ||
| }, | ||
| }, | ||
| { | ||
| name: "it returns no error if gc option is empty", | ||
niaow marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| opts: compileopts.Options{ | ||
| GC: "", | ||
| }, | ||
| }, | ||
| { | ||
| name: "it returns an error if scheduler option is not valid", | ||
| opts: compileopts.Options{ | ||
| Scheduler: "incorrect", | ||
| }, | ||
| expectedError: compileopts.ErrSchedulerInvalidOption, | ||
| }, | ||
| { | ||
| name: "it returns no error if scheduler option is 'tasks'", | ||
| opts: compileopts.Options{ | ||
| Scheduler: "tasks", | ||
| }, | ||
| }, | ||
| { | ||
| name: "it returns no error if scheduler option is 'coroutines'", | ||
| opts: compileopts.Options{ | ||
| Scheduler: "coroutines", | ||
| }, | ||
| }, | ||
| { | ||
| name: "it returns no error if scheduler option is empty", | ||
| opts: compileopts.Options{ | ||
| Scheduler: "", | ||
niaow marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| }, | ||
| }, | ||
| { | ||
| name: "it returns an error if printSize option is not valid", | ||
| opts: compileopts.Options{ | ||
| PrintSizes: "invalid", | ||
| }, | ||
| expectedError: compileopts.ErrPrintSizeInvalidOption, | ||
| }, | ||
| { | ||
| name: "it returns no error if printSize option is 'none'", | ||
| opts: compileopts.Options{ | ||
| PrintSizes: "none", | ||
| }, | ||
| }, | ||
| { | ||
| name: "it returns no error if printSize option is 'short'", | ||
| opts: compileopts.Options{ | ||
| PrintSizes: "short", | ||
| }, | ||
| }, | ||
| { | ||
| name: "it returns no error if printSize option is 'full'", | ||
| opts: compileopts.Options{ | ||
| PrintSizes: "full", | ||
| }, | ||
| }, | ||
| { | ||
| name: "it returns no error if printSize option is empty", | ||
| opts: compileopts.Options{ | ||
| PrintSizes: "", | ||
niaow marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| }, | ||
| }, | ||
| } | ||
|
|
||
| for _, tc := range testCases { | ||
| t.Run(tc.name, func(t *testing.T) { | ||
| err := tc.opts.Verify() | ||
| if tc.expectedError != err { | ||
| t.Errorf("expecting %v, got %v", tc.expectedError, err) | ||
cebernardi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| }) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -762,6 +762,13 @@ func main() { | |
| Programmer: *programmer, | ||
| } | ||
|
|
||
| err := options.Verify() | ||
|
||
| if err != nil { | ||
| fmt.Fprintln(os.Stderr, err.Error()) | ||
| usage() | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| if *cFlags != "" { | ||
| options.CFlags = strings.Split(*cFlags, " ") | ||
| } | ||
|
|
@@ -776,7 +783,6 @@ func main() { | |
| os.Exit(1) | ||
| } | ||
|
|
||
| var err error | ||
| if options.HeapSize, err = parseSize(*heapSize); err != nil { | ||
| fmt.Fprintln(os.Stderr, "Could not read heap size:", *heapSize) | ||
| usage() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"none" is also a valid scheduler option
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jaddr2line oh I see.. so I think I should also modify this line https://github.com/tinygo-org/tinygo/blob/master/main.go#L713 and this line: https://github.com/tinygo-org/tinygo/blob/master/compileopts/config.go#L132
can you please confirm?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes those should be updated. You could add it to this PR: even though it's somewhat separate it's a small and obvious fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jaddr2line @aykevl done!