package gust import ( "bufio" "math" "os" "sort" "strconv" ) type Fs map[string]Lines type Lines map[int]string func BuildFs(messages []CompilerMessage) Fs { files := make(Fs) for _, msg := range messages { if msg.Location.File != "" { files[msg.Location.File] = nil } } for f := range files { fd, err := os.Open(f) if err != nil { // failed to open file continue } lines := make(Lines) scanner := bufio.NewScanner(fd) nr := 1 for scanner.Scan() { lines[nr] = scanner.Text() nr++ } if err := scanner.Err(); err != nil { continue } files[f] = lines } return files } func (lines Lines) Start() int { start := math.MaxInt for lineNum := range lines { start = min(start, lineNum) } return start } func (lines Lines) Ordered() []string { lineNumbers := make([]int, 0, len(lines)) for lineNum := range lines { lineNumbers = append(lineNumbers, lineNum) } sort.Ints(lineNumbers) ordered := []string{} for _, nr := range lineNumbers { ordered = append(ordered, lines[nr]) } return ordered } func (fs *Fs) PopulateContext(msgs []CompilerMessage, ctxSize int) { for i, m := range msgs { path := m.Location.File file, _ := (*fs)[path] line := m.Location.Line if path != "" && line != "" { nr, _ := strconv.Atoi(line) ctx := make(Lines) for i := nr - ctxSize; i <= nr+ctxSize; i++ { if l, ok := file[i]; ok { ctx[i] = l } } // extract lines msgs[i].Context = ctx } } }