loader: better error message on import cycles
Этот коммит содержится в:
		
							родитель
							
								
									4f4d7976c6
								
							
						
					
					
						коммит
						e6d90d89fa
					
				
					 2 изменённых файлов: 24 добавлений и 7 удалений
				
			
		| 
						 | 
				
			
			@ -1,5 +1,10 @@
 | 
			
		|||
package loader
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"go/token"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Errors contains a list of parser errors or a list of typechecker errors for
 | 
			
		||||
// the given package.
 | 
			
		||||
type Errors struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -15,13 +20,20 @@ func (e Errors) Error() string {
 | 
			
		|||
// packages is a list from the root package to the leaf package that imports one
 | 
			
		||||
// of the packages in the list.
 | 
			
		||||
type ImportCycleError struct {
 | 
			
		||||
	Packages []string
 | 
			
		||||
	Packages        []string
 | 
			
		||||
	ImportPositions []token.Position
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *ImportCycleError) Error() string {
 | 
			
		||||
	msg := "import cycle: " + e.Packages[0]
 | 
			
		||||
	for _, path := range e.Packages[1:] {
 | 
			
		||||
		msg += " → " + path
 | 
			
		||||
	var msg strings.Builder
 | 
			
		||||
	msg.WriteString("import cycle:\n\t")
 | 
			
		||||
	msg.WriteString(strings.Join(e.Packages, "\n\t"))
 | 
			
		||||
	msg.WriteString("\n at ")
 | 
			
		||||
	for i, pos := range e.ImportPositions {
 | 
			
		||||
		if i > 0 {
 | 
			
		||||
			msg.WriteString(", ")
 | 
			
		||||
		}
 | 
			
		||||
		msg.WriteString(pos.String())
 | 
			
		||||
	}
 | 
			
		||||
	return msg
 | 
			
		||||
	return msg.String()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -166,7 +166,9 @@ func (p *Program) Parse() error {
 | 
			
		|||
		err := pkg.importRecursively()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if err, ok := err.(*ImportCycleError); ok {
 | 
			
		||||
				err.Packages = append([]string{pkg.ImportPath}, err.Packages...)
 | 
			
		||||
				if pkg.ImportPath != err.Packages[0] {
 | 
			
		||||
					err.Packages = append([]string{pkg.ImportPath}, err.Packages...)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -339,10 +341,13 @@ func (p *Package) importRecursively() error {
 | 
			
		|||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if importedPkg.Importing {
 | 
			
		||||
			return &ImportCycleError{[]string{p.ImportPath, importedPkg.ImportPath}}
 | 
			
		||||
			return &ImportCycleError{[]string{p.ImportPath, importedPkg.ImportPath}, p.ImportPos[to]}
 | 
			
		||||
		}
 | 
			
		||||
		err = importedPkg.importRecursively()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if err, ok := err.(*ImportCycleError); ok {
 | 
			
		||||
				err.Packages = append([]string{p.ImportPath}, err.Packages...)
 | 
			
		||||
			}
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		p.Imports[to] = importedPkg
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче