github.com/elves/Elvish@v0.12.0/parse/error.go (about) 1 package parse 2 3 import ( 4 "bytes" 5 "fmt" 6 7 "github.com/elves/elvish/util" 8 ) 9 10 // ErrorEntry represents one parse error. 11 type ErrorEntry struct { 12 Message string 13 Context util.SourceRange 14 } 15 16 // Error stores multiple ErrorEntry's and can pretty print them. 17 type Error struct { 18 Entries []*ErrorEntry 19 } 20 21 func (pe *Error) Add(msg string, ctx *util.SourceRange) { 22 pe.Entries = append(pe.Entries, &ErrorEntry{msg, *ctx}) 23 } 24 25 func (pe *Error) Error() string { 26 switch len(pe.Entries) { 27 case 0: 28 return "no parse error" 29 case 1: 30 e := pe.Entries[0] 31 return fmt.Sprintf("parse error: %d-%d in %s: %s", 32 e.Context.Begin, e.Context.End, e.Context.Name, e.Message) 33 default: 34 buf := new(bytes.Buffer) 35 // Contexts of parse error entries all have the same name 36 fmt.Fprintf(buf, "multiple parse errors in %s: ", pe.Entries[0].Context.Name) 37 for i, e := range pe.Entries { 38 if i > 0 { 39 fmt.Fprint(buf, "; ") 40 } 41 fmt.Fprintf(buf, "%d-%d: %s", e.Context.Begin, e.Context.End, e.Message) 42 } 43 return buf.String() 44 } 45 } 46 47 func (pe *Error) Pprint(indent string) string { 48 buf := new(bytes.Buffer) 49 50 switch len(pe.Entries) { 51 case 0: 52 return "no parse error" 53 case 1: 54 e := pe.Entries[0] 55 fmt.Fprintf(buf, "Parse error: \033[31;1m%s\033[m\n", e.Message) 56 buf.WriteString(e.Context.PprintCompact(indent + " ")) 57 default: 58 fmt.Fprint(buf, "Multiple parse errors:") 59 for _, e := range pe.Entries { 60 buf.WriteString("\n" + indent + " ") 61 fmt.Fprintf(buf, "\033[31;1m%s\033[m\n", e.Message) 62 buf.WriteString(indent + " ") 63 buf.WriteString(e.Context.Pprint(indent + " ")) 64 } 65 } 66 67 return buf.String() 68 }