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  }