func newBuildError(out string) error { matchs := ERRORRegexp.FindAllStringSubmatch(out, -1) if matchs == nil { return &peony.Error{ Title: "Complie error", Description: string(out), } } fileSources := map[string][]string{} for _, match := range matchs { filep, _ := filepath.Abs(match[1]) line, _ := strconv.Atoi(match[2]) filename := filep[len(filepath.Dir(filep)):] column := 0 if match[3] != "" { column, _ = strconv.Atoi(match[3]) } desc := match[4] var source []string var hasSource = false if source, hasSource = fileSources[filep]; !hasSource { source = peony.MustReadLines(filep) fileSources[filep] = source } //just get the first error return &peony.Error{ Title: "Complie error", FileName: filename, Path: filep, SourceLines: source, Line: line, Column: column, Description: desc, } } return nil }
func ProcessSources(roots []string) (*SourceInfo, error) { si := NewSourceInfo() for _, root := range roots { err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if err != nil { log.Println("error scan app source:", err) return nil } //if is normal file or name is temp skip //directory is needed if !info.IsDir() || info.Name() == "tmp" { return nil } fileSet := token.NewFileSet() astPkgs, err := parser.ParseDir(fileSet, path, func(info os.FileInfo) bool { name := info.Name() return !info.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") }, parser.ParseComments) if err != nil { //err is ErrorList if errList, ok := err.(scanner.ErrorList); ok { fileSources := map[string][]string{} for _, err := range errList { var hasSource = false var source []string if source, hasSource = fileSources[err.Pos.Filename]; !hasSource { source = peony.MustReadLines(err.Pos.Filename) fileSources[err.Pos.Filename] = source } return &peony.Error{ Title: "Compile error", FileName: err.Pos.Filename, Path: err.Pos.Filename, Description: err.Msg, Line: err.Pos.Line, Column: err.Pos.Column, SourceLines: source, } } } ast.Print(nil, err) } //parse the importPath importPath := importPathFromPath(root) if path != root { importPath = importPathFromPath(path) } //ignore the main package delete(astPkgs, "main") //ignore the empty package if len(astPkgs) == 0 { return nil } for _, pkg := range astPkgs { if err := processPackage(si, importPath, pkg, fileSet); err != nil { return err } } return nil }) if err != nil { return nil, err } } return si, nil }