mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-04 02:57:46 +00:00
loader: report all type and syntax errors possible
Previously the loader would only report the first error. With this change, all syntax and type errors will be reported.
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
||||
func TestErrors(t *testing.T) {
|
||||
for _, name := range []string{
|
||||
"cgo",
|
||||
"multi",
|
||||
"loader-importcycle",
|
||||
"loader-invaliddep",
|
||||
"loader-invalidpackage",
|
||||
|
||||
+39
-5
@@ -318,18 +318,34 @@ func (p *Program) MainPkg() *Package {
|
||||
func (p *Program) Parse() error {
|
||||
// Parse all packages.
|
||||
// TODO: do this in parallel.
|
||||
var errors []error
|
||||
for _, pkg := range p.sorted {
|
||||
err := pkg.Parse()
|
||||
if err != nil {
|
||||
return err
|
||||
errors = append(errors, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Typecheck all packages.
|
||||
for _, pkg := range p.sorted {
|
||||
if !pkg.isParsed() || !pkg.allImportsChecked() {
|
||||
if len(errors) == 0 {
|
||||
// Sanity check.
|
||||
// If there are no errors, all packages should have been parsed.
|
||||
panic("unreachable")
|
||||
}
|
||||
continue
|
||||
}
|
||||
err := pkg.Check()
|
||||
if err != nil {
|
||||
return err
|
||||
errors = append(errors, err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(errors) != 0 {
|
||||
// TODO: use errors.Join in Go 1.20.
|
||||
return Errors{
|
||||
Errs: errors,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,12 +370,12 @@ func (p *Package) parseFile(path string, mode parser.Mode) (*ast.File, error) {
|
||||
return parser.ParseFile(p.program.fset, originalPath, data, mode)
|
||||
}
|
||||
|
||||
// Parse parses and typechecks this package.
|
||||
// Parse parses this package.
|
||||
//
|
||||
// Idempotent.
|
||||
func (p *Package) Parse() error {
|
||||
if len(p.Files) != 0 {
|
||||
return nil // nothing to do (?)
|
||||
if p.isParsed() {
|
||||
return nil // nothing to do
|
||||
}
|
||||
|
||||
// Load the AST.
|
||||
@@ -379,6 +395,24 @@ func (p *Package) Parse() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// isParsed returns whether this package has been parsed.
|
||||
func (p *Package) isParsed() bool {
|
||||
// Special case: the unsafe package doesn't have files to parse but does
|
||||
// have p.Pkg set once it is parsed.
|
||||
return len(p.Files) != 0 || p.Pkg != nil
|
||||
}
|
||||
|
||||
// allImportsChecked returns whether all imports of this package have been
|
||||
// type-checked.
|
||||
func (p *Package) allImportsChecked() bool {
|
||||
for _, dep := range p.Imports {
|
||||
if p.program.Packages[dep].Pkg == nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Check runs the package through the typechecker. The package must already be
|
||||
// loaded and all dependencies must have been checked already.
|
||||
//
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
package typesmulti3
|
||||
|
||||
var _ int = 3.14
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
package syntaxmulti2
|
||||
|
||||
func Foo2(type) {
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
package syntaxmulti1
|
||||
|
||||
func Foo1(import) {
|
||||
}
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "github.com/tinygo-org/tinygo/testdata/errors/multi-1"
|
||||
_ "github.com/tinygo-org/tinygo/testdata/errors/multi-2"
|
||||
_ "github.com/tinygo-org/tinygo/testdata/errors/multi-3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
}
|
||||
|
||||
// ERROR: # github.com/tinygo-org/tinygo/testdata/errors/multi-2
|
||||
// ERROR: multi-2/syntax.go:3:11: expected ')', found 'type'
|
||||
// ERROR: # github.com/tinygo-org/tinygo/testdata/errors/multi-3
|
||||
// ERROR: multi-3/syntax.go:3:11: expected ')', found 'import'
|
||||
// ERROR: # github.com/tinygo-org/tinygo/testdata/errors/multi-1
|
||||
// ERROR: multi-1/types.go:3:13: cannot use 3.14 (untyped float constant) as int value in variable declaration (truncated)
|
||||
Reference in New Issue
Block a user