switch glide to govendor (#43)
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
		
							
								
								
									
										785
									
								
								vendor/github.com/aymerick/raymond/ast/node.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										785
									
								
								vendor/github.com/aymerick/raymond/ast/node.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,785 @@ | ||||
| // Package ast provides structures to represent a handlebars Abstract Syntax Tree, and a Visitor interface to visit that tree. | ||||
| package ast | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| ) | ||||
|  | ||||
| // References: | ||||
| //   - https://github.com/wycats/handlebars.js/blob/master/lib/handlebars/compiler/ast.js | ||||
| //   - https://github.com/wycats/handlebars.js/blob/master/docs/compiler-api.md | ||||
| //   - https://github.com/golang/go/blob/master/src/text/template/parse/node.go | ||||
|  | ||||
| // Node is an element in the AST. | ||||
| type Node interface { | ||||
| 	// node type | ||||
| 	Type() NodeType | ||||
|  | ||||
| 	// location of node in original input string | ||||
| 	Location() Loc | ||||
|  | ||||
| 	// string representation, used for debugging | ||||
| 	String() string | ||||
|  | ||||
| 	// accepts visitor | ||||
| 	Accept(Visitor) interface{} | ||||
| } | ||||
|  | ||||
| // Visitor is the interface to visit an AST. | ||||
| type Visitor interface { | ||||
| 	VisitProgram(*Program) interface{} | ||||
|  | ||||
| 	// statements | ||||
| 	VisitMustache(*MustacheStatement) interface{} | ||||
| 	VisitBlock(*BlockStatement) interface{} | ||||
| 	VisitPartial(*PartialStatement) interface{} | ||||
| 	VisitContent(*ContentStatement) interface{} | ||||
| 	VisitComment(*CommentStatement) interface{} | ||||
|  | ||||
| 	// expressions | ||||
| 	VisitExpression(*Expression) interface{} | ||||
| 	VisitSubExpression(*SubExpression) interface{} | ||||
| 	VisitPath(*PathExpression) interface{} | ||||
|  | ||||
| 	// literals | ||||
| 	VisitString(*StringLiteral) interface{} | ||||
| 	VisitBoolean(*BooleanLiteral) interface{} | ||||
| 	VisitNumber(*NumberLiteral) interface{} | ||||
|  | ||||
| 	// miscellaneous | ||||
| 	VisitHash(*Hash) interface{} | ||||
| 	VisitHashPair(*HashPair) interface{} | ||||
| } | ||||
|  | ||||
| // NodeType represents an AST Node type. | ||||
| type NodeType int | ||||
|  | ||||
| // Type returns itself, and permits struct includers to satisfy that part of Node interface. | ||||
| func (t NodeType) Type() NodeType { | ||||
| 	return t | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	// NodeProgram is the program node | ||||
| 	NodeProgram NodeType = iota | ||||
|  | ||||
| 	// NodeMustache is the mustache statement node | ||||
| 	NodeMustache | ||||
|  | ||||
| 	// NodeBlock is the block statement node | ||||
| 	NodeBlock | ||||
|  | ||||
| 	// NodePartial is the partial statement node | ||||
| 	NodePartial | ||||
|  | ||||
| 	// NodeContent is the content statement node | ||||
| 	NodeContent | ||||
|  | ||||
| 	// NodeComment is the comment statement node | ||||
| 	NodeComment | ||||
|  | ||||
| 	// NodeExpression is the expression node | ||||
| 	NodeExpression | ||||
|  | ||||
| 	// NodeSubExpression is the subexpression node | ||||
| 	NodeSubExpression | ||||
|  | ||||
| 	// NodePath is the expression path node | ||||
| 	NodePath | ||||
|  | ||||
| 	// NodeBoolean is the literal boolean node | ||||
| 	NodeBoolean | ||||
|  | ||||
| 	// NodeNumber is the literal number node | ||||
| 	NodeNumber | ||||
|  | ||||
| 	// NodeString is the literal string node | ||||
| 	NodeString | ||||
|  | ||||
| 	// NodeHash is the hash node | ||||
| 	NodeHash | ||||
|  | ||||
| 	// NodeHashPair is the hash pair node | ||||
| 	NodeHashPair | ||||
| ) | ||||
|  | ||||
| // Loc represents the position of a parsed node in source file. | ||||
| type Loc struct { | ||||
| 	Pos  int // Byte position | ||||
| 	Line int // Line number | ||||
| } | ||||
|  | ||||
| // Location returns itself, and permits struct includers to satisfy that part of Node interface. | ||||
| func (l Loc) Location() Loc { | ||||
| 	return l | ||||
| } | ||||
|  | ||||
| // Strip describes node whitespace management. | ||||
| type Strip struct { | ||||
| 	Open  bool | ||||
| 	Close bool | ||||
|  | ||||
| 	OpenStandalone   bool | ||||
| 	CloseStandalone  bool | ||||
| 	InlineStandalone bool | ||||
| } | ||||
|  | ||||
| // NewStrip instanciates a Strip for given open and close mustaches. | ||||
| func NewStrip(openStr, closeStr string) *Strip { | ||||
| 	return &Strip{ | ||||
| 		Open:  (len(openStr) > 2) && openStr[2] == '~', | ||||
| 		Close: (len(closeStr) > 2) && closeStr[len(closeStr)-3] == '~', | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // NewStripForStr instanciates a Strip for given tag. | ||||
| func NewStripForStr(str string) *Strip { | ||||
| 	return &Strip{ | ||||
| 		Open:  (len(str) > 2) && str[2] == '~', | ||||
| 		Close: (len(str) > 2) && str[len(str)-3] == '~', | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (s *Strip) String() string { | ||||
| 	return fmt.Sprintf("Open: %t, Close: %t, OpenStandalone: %t, CloseStandalone: %t, InlineStandalone: %t", s.Open, s.Close, s.OpenStandalone, s.CloseStandalone, s.InlineStandalone) | ||||
| } | ||||
|  | ||||
| // | ||||
| // Program | ||||
| // | ||||
|  | ||||
| // Program represents a program node. | ||||
| type Program struct { | ||||
| 	NodeType | ||||
| 	Loc | ||||
|  | ||||
| 	Body        []Node // [ Statement ... ] | ||||
| 	BlockParams []string | ||||
| 	Chained     bool | ||||
|  | ||||
| 	// whitespace management | ||||
| 	Strip *Strip | ||||
| } | ||||
|  | ||||
| // NewProgram instanciates a new program node. | ||||
| func NewProgram(pos int, line int) *Program { | ||||
| 	return &Program{ | ||||
| 		NodeType: NodeProgram, | ||||
| 		Loc:      Loc{pos, line}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (node *Program) String() string { | ||||
| 	return fmt.Sprintf("Program{Pos: %d}", node.Loc.Pos) | ||||
| } | ||||
|  | ||||
| // Accept is the receiver entry point for visitors. | ||||
| func (node *Program) Accept(visitor Visitor) interface{} { | ||||
| 	return visitor.VisitProgram(node) | ||||
| } | ||||
|  | ||||
| // AddStatement adds given statement to program. | ||||
| func (node *Program) AddStatement(statement Node) { | ||||
| 	node.Body = append(node.Body, statement) | ||||
| } | ||||
|  | ||||
| // | ||||
| // Mustache Statement | ||||
| // | ||||
|  | ||||
| // MustacheStatement represents a mustache node. | ||||
| type MustacheStatement struct { | ||||
| 	NodeType | ||||
| 	Loc | ||||
|  | ||||
| 	Unescaped  bool | ||||
| 	Expression *Expression | ||||
|  | ||||
| 	// whitespace management | ||||
| 	Strip *Strip | ||||
| } | ||||
|  | ||||
| // NewMustacheStatement instanciates a new mustache node. | ||||
| func NewMustacheStatement(pos int, line int, unescaped bool) *MustacheStatement { | ||||
| 	return &MustacheStatement{ | ||||
| 		NodeType:  NodeMustache, | ||||
| 		Loc:       Loc{pos, line}, | ||||
| 		Unescaped: unescaped, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (node *MustacheStatement) String() string { | ||||
| 	return fmt.Sprintf("Mustache{Pos: %d}", node.Loc.Pos) | ||||
| } | ||||
|  | ||||
| // Accept is the receiver entry point for visitors. | ||||
| func (node *MustacheStatement) Accept(visitor Visitor) interface{} { | ||||
| 	return visitor.VisitMustache(node) | ||||
| } | ||||
|  | ||||
| // | ||||
| // Block Statement | ||||
| // | ||||
|  | ||||
| // BlockStatement represents a block node. | ||||
| type BlockStatement struct { | ||||
| 	NodeType | ||||
| 	Loc | ||||
|  | ||||
| 	Expression *Expression | ||||
|  | ||||
| 	Program *Program | ||||
| 	Inverse *Program | ||||
|  | ||||
| 	// whitespace management | ||||
| 	OpenStrip    *Strip | ||||
| 	InverseStrip *Strip | ||||
| 	CloseStrip   *Strip | ||||
| } | ||||
|  | ||||
| // NewBlockStatement instanciates a new block node. | ||||
| func NewBlockStatement(pos int, line int) *BlockStatement { | ||||
| 	return &BlockStatement{ | ||||
| 		NodeType: NodeBlock, | ||||
| 		Loc:      Loc{pos, line}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (node *BlockStatement) String() string { | ||||
| 	return fmt.Sprintf("Block{Pos: %d}", node.Loc.Pos) | ||||
| } | ||||
|  | ||||
| // Accept is the receiver entry point for visitors. | ||||
| func (node *BlockStatement) Accept(visitor Visitor) interface{} { | ||||
| 	return visitor.VisitBlock(node) | ||||
| } | ||||
|  | ||||
| // | ||||
| // Partial Statement | ||||
| // | ||||
|  | ||||
| // PartialStatement represents a partial node. | ||||
| type PartialStatement struct { | ||||
| 	NodeType | ||||
| 	Loc | ||||
|  | ||||
| 	Name   Node   // PathExpression | SubExpression | ||||
| 	Params []Node // [ Expression ... ] | ||||
| 	Hash   *Hash | ||||
|  | ||||
| 	// whitespace management | ||||
| 	Strip  *Strip | ||||
| 	Indent string | ||||
| } | ||||
|  | ||||
| // NewPartialStatement instanciates a new partial node. | ||||
| func NewPartialStatement(pos int, line int) *PartialStatement { | ||||
| 	return &PartialStatement{ | ||||
| 		NodeType: NodePartial, | ||||
| 		Loc:      Loc{pos, line}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (node *PartialStatement) String() string { | ||||
| 	return fmt.Sprintf("Partial{Name:%s, Pos:%d}", node.Name, node.Loc.Pos) | ||||
| } | ||||
|  | ||||
| // Accept is the receiver entry point for visitors. | ||||
| func (node *PartialStatement) Accept(visitor Visitor) interface{} { | ||||
| 	return visitor.VisitPartial(node) | ||||
| } | ||||
|  | ||||
| // | ||||
| // Content Statement | ||||
| // | ||||
|  | ||||
| // ContentStatement represents a content node. | ||||
| type ContentStatement struct { | ||||
| 	NodeType | ||||
| 	Loc | ||||
|  | ||||
| 	Value    string | ||||
| 	Original string | ||||
|  | ||||
| 	// whitespace management | ||||
| 	RightStripped bool | ||||
| 	LeftStripped  bool | ||||
| } | ||||
|  | ||||
| // NewContentStatement instanciates a new content node. | ||||
| func NewContentStatement(pos int, line int, val string) *ContentStatement { | ||||
| 	return &ContentStatement{ | ||||
| 		NodeType: NodeContent, | ||||
| 		Loc:      Loc{pos, line}, | ||||
|  | ||||
| 		Value:    val, | ||||
| 		Original: val, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (node *ContentStatement) String() string { | ||||
| 	return fmt.Sprintf("Content{Value:'%s', Pos:%d}", node.Value, node.Loc.Pos) | ||||
| } | ||||
|  | ||||
| // Accept is the receiver entry point for visitors. | ||||
| func (node *ContentStatement) Accept(visitor Visitor) interface{} { | ||||
| 	return visitor.VisitContent(node) | ||||
| } | ||||
|  | ||||
| // | ||||
| // Comment Statement | ||||
| // | ||||
|  | ||||
| // CommentStatement represents a comment node. | ||||
| type CommentStatement struct { | ||||
| 	NodeType | ||||
| 	Loc | ||||
|  | ||||
| 	Value string | ||||
|  | ||||
| 	// whitespace management | ||||
| 	Strip *Strip | ||||
| } | ||||
|  | ||||
| // NewCommentStatement instanciates a new comment node. | ||||
| func NewCommentStatement(pos int, line int, val string) *CommentStatement { | ||||
| 	return &CommentStatement{ | ||||
| 		NodeType: NodeComment, | ||||
| 		Loc:      Loc{pos, line}, | ||||
|  | ||||
| 		Value: val, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (node *CommentStatement) String() string { | ||||
| 	return fmt.Sprintf("Comment{Value:'%s', Pos:%d}", node.Value, node.Loc.Pos) | ||||
| } | ||||
|  | ||||
| // Accept is the receiver entry point for visitors. | ||||
| func (node *CommentStatement) Accept(visitor Visitor) interface{} { | ||||
| 	return visitor.VisitComment(node) | ||||
| } | ||||
|  | ||||
| // | ||||
| // Expression | ||||
| // | ||||
|  | ||||
| // Expression represents an expression node. | ||||
| type Expression struct { | ||||
| 	NodeType | ||||
| 	Loc | ||||
|  | ||||
| 	Path   Node   // PathExpression | StringLiteral | BooleanLiteral | NumberLiteral | ||||
| 	Params []Node // [ Expression ... ] | ||||
| 	Hash   *Hash | ||||
| } | ||||
|  | ||||
| // NewExpression instanciates a new expression node. | ||||
| func NewExpression(pos int, line int) *Expression { | ||||
| 	return &Expression{ | ||||
| 		NodeType: NodeExpression, | ||||
| 		Loc:      Loc{pos, line}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (node *Expression) String() string { | ||||
| 	return fmt.Sprintf("Expr{Path:%s, Pos:%d}", node.Path, node.Loc.Pos) | ||||
| } | ||||
|  | ||||
| // Accept is the receiver entry point for visitors. | ||||
| func (node *Expression) Accept(visitor Visitor) interface{} { | ||||
| 	return visitor.VisitExpression(node) | ||||
| } | ||||
|  | ||||
| // HelperName returns helper name, or an empty string if this expression can't be a helper. | ||||
| func (node *Expression) HelperName() string { | ||||
| 	path, ok := node.Path.(*PathExpression) | ||||
| 	if !ok { | ||||
| 		return "" | ||||
| 	} | ||||
|  | ||||
| 	if path.Data || (len(path.Parts) != 1) || (path.Depth > 0) || path.Scoped { | ||||
| 		return "" | ||||
| 	} | ||||
|  | ||||
| 	return path.Parts[0] | ||||
| } | ||||
|  | ||||
| // FieldPath returns path expression representing a field path, or nil if this is not a field path. | ||||
| func (node *Expression) FieldPath() *PathExpression { | ||||
| 	path, ok := node.Path.(*PathExpression) | ||||
| 	if !ok { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	return path | ||||
| } | ||||
|  | ||||
| // LiteralStr returns the string representation of literal value, with a boolean set to false if this is not a literal. | ||||
| func (node *Expression) LiteralStr() (string, bool) { | ||||
| 	return LiteralStr(node.Path) | ||||
| } | ||||
|  | ||||
| // Canonical returns the canonical form of expression node as a string. | ||||
| func (node *Expression) Canonical() string { | ||||
| 	if str, ok := HelperNameStr(node.Path); ok { | ||||
| 		return str | ||||
| 	} | ||||
|  | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| // HelperNameStr returns the string representation of a helper name, with a boolean set to false if this is not a valid helper name. | ||||
| // | ||||
| // helperName : path | dataName | STRING | NUMBER | BOOLEAN | UNDEFINED | NULL | ||||
| func HelperNameStr(node Node) (string, bool) { | ||||
| 	// PathExpression | ||||
| 	if str, ok := PathExpressionStr(node); ok { | ||||
| 		return str, ok | ||||
| 	} | ||||
|  | ||||
| 	// Literal | ||||
| 	if str, ok := LiteralStr(node); ok { | ||||
| 		return str, ok | ||||
| 	} | ||||
|  | ||||
| 	return "", false | ||||
| } | ||||
|  | ||||
| // PathExpressionStr returns the string representation of path expression value, with a boolean set to false if this is not a path expression. | ||||
| func PathExpressionStr(node Node) (string, bool) { | ||||
| 	if path, ok := node.(*PathExpression); ok { | ||||
| 		result := path.Original | ||||
|  | ||||
| 		// "[foo bar]"" => "foo bar" | ||||
| 		if (len(result) >= 2) && (result[0] == '[') && (result[len(result)-1] == ']') { | ||||
| 			result = result[1 : len(result)-1] | ||||
| 		} | ||||
|  | ||||
| 		return result, true | ||||
| 	} | ||||
|  | ||||
| 	return "", false | ||||
| } | ||||
|  | ||||
| // LiteralStr returns the string representation of literal value, with a boolean set to false if this is not a literal. | ||||
| func LiteralStr(node Node) (string, bool) { | ||||
| 	if lit, ok := node.(*StringLiteral); ok { | ||||
| 		return lit.Value, true | ||||
| 	} | ||||
|  | ||||
| 	if lit, ok := node.(*BooleanLiteral); ok { | ||||
| 		return lit.Canonical(), true | ||||
| 	} | ||||
|  | ||||
| 	if lit, ok := node.(*NumberLiteral); ok { | ||||
| 		return lit.Canonical(), true | ||||
| 	} | ||||
|  | ||||
| 	return "", false | ||||
| } | ||||
|  | ||||
| // | ||||
| // SubExpression | ||||
| // | ||||
|  | ||||
| // SubExpression represents a subexpression node. | ||||
| type SubExpression struct { | ||||
| 	NodeType | ||||
| 	Loc | ||||
|  | ||||
| 	Expression *Expression | ||||
| } | ||||
|  | ||||
| // NewSubExpression instanciates a new subexpression node. | ||||
| func NewSubExpression(pos int, line int) *SubExpression { | ||||
| 	return &SubExpression{ | ||||
| 		NodeType: NodeSubExpression, | ||||
| 		Loc:      Loc{pos, line}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (node *SubExpression) String() string { | ||||
| 	return fmt.Sprintf("Sexp{Path:%s, Pos:%d}", node.Expression.Path, node.Loc.Pos) | ||||
| } | ||||
|  | ||||
| // Accept is the receiver entry point for visitors. | ||||
| func (node *SubExpression) Accept(visitor Visitor) interface{} { | ||||
| 	return visitor.VisitSubExpression(node) | ||||
| } | ||||
|  | ||||
| // | ||||
| // Path Expression | ||||
| // | ||||
|  | ||||
| // PathExpression represents a path expression node. | ||||
| type PathExpression struct { | ||||
| 	NodeType | ||||
| 	Loc | ||||
|  | ||||
| 	Original string | ||||
| 	Depth    int | ||||
| 	Parts    []string | ||||
| 	Data     bool | ||||
| 	Scoped   bool | ||||
| } | ||||
|  | ||||
| // NewPathExpression instanciates a new path expression node. | ||||
| func NewPathExpression(pos int, line int, data bool) *PathExpression { | ||||
| 	result := &PathExpression{ | ||||
| 		NodeType: NodePath, | ||||
| 		Loc:      Loc{pos, line}, | ||||
|  | ||||
| 		Data: data, | ||||
| 	} | ||||
|  | ||||
| 	if data { | ||||
| 		result.Original = "@" | ||||
| 	} | ||||
|  | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (node *PathExpression) String() string { | ||||
| 	return fmt.Sprintf("Path{Original:'%s', Pos:%d}", node.Original, node.Loc.Pos) | ||||
| } | ||||
|  | ||||
| // Accept is the receiver entry point for visitors. | ||||
| func (node *PathExpression) Accept(visitor Visitor) interface{} { | ||||
| 	return visitor.VisitPath(node) | ||||
| } | ||||
|  | ||||
| // Part adds path part. | ||||
| func (node *PathExpression) Part(part string) { | ||||
| 	node.Original += part | ||||
|  | ||||
| 	switch part { | ||||
| 	case "..": | ||||
| 		node.Depth++ | ||||
| 		node.Scoped = true | ||||
| 	case ".", "this": | ||||
| 		node.Scoped = true | ||||
| 	default: | ||||
| 		node.Parts = append(node.Parts, part) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Sep adds path separator. | ||||
| func (node *PathExpression) Sep(separator string) { | ||||
| 	node.Original += separator | ||||
| } | ||||
|  | ||||
| // IsDataRoot returns true if path expression is @root. | ||||
| func (node *PathExpression) IsDataRoot() bool { | ||||
| 	return node.Data && (node.Parts[0] == "root") | ||||
| } | ||||
|  | ||||
| // | ||||
| // String Literal | ||||
| // | ||||
|  | ||||
| // StringLiteral represents a string node. | ||||
| type StringLiteral struct { | ||||
| 	NodeType | ||||
| 	Loc | ||||
|  | ||||
| 	Value string | ||||
| } | ||||
|  | ||||
| // NewStringLiteral instanciates a new string node. | ||||
| func NewStringLiteral(pos int, line int, val string) *StringLiteral { | ||||
| 	return &StringLiteral{ | ||||
| 		NodeType: NodeString, | ||||
| 		Loc:      Loc{pos, line}, | ||||
|  | ||||
| 		Value: val, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (node *StringLiteral) String() string { | ||||
| 	return fmt.Sprintf("String{Value:'%s', Pos:%d}", node.Value, node.Loc.Pos) | ||||
| } | ||||
|  | ||||
| // Accept is the receiver entry point for visitors. | ||||
| func (node *StringLiteral) Accept(visitor Visitor) interface{} { | ||||
| 	return visitor.VisitString(node) | ||||
| } | ||||
|  | ||||
| // | ||||
| // Boolean Literal | ||||
| // | ||||
|  | ||||
| // BooleanLiteral represents a boolean node. | ||||
| type BooleanLiteral struct { | ||||
| 	NodeType | ||||
| 	Loc | ||||
|  | ||||
| 	Value    bool | ||||
| 	Original string | ||||
| } | ||||
|  | ||||
| // NewBooleanLiteral instanciates a new boolean node. | ||||
| func NewBooleanLiteral(pos int, line int, val bool, original string) *BooleanLiteral { | ||||
| 	return &BooleanLiteral{ | ||||
| 		NodeType: NodeBoolean, | ||||
| 		Loc:      Loc{pos, line}, | ||||
|  | ||||
| 		Value:    val, | ||||
| 		Original: original, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (node *BooleanLiteral) String() string { | ||||
| 	return fmt.Sprintf("Boolean{Value:%s, Pos:%d}", node.Canonical(), node.Loc.Pos) | ||||
| } | ||||
|  | ||||
| // Accept is the receiver entry point for visitors. | ||||
| func (node *BooleanLiteral) Accept(visitor Visitor) interface{} { | ||||
| 	return visitor.VisitBoolean(node) | ||||
| } | ||||
|  | ||||
| // Canonical returns the canonical form of boolean node as a string (ie. "true" | "false"). | ||||
| func (node *BooleanLiteral) Canonical() string { | ||||
| 	if node.Value { | ||||
| 		return "true" | ||||
| 	} | ||||
|  | ||||
| 	return "false" | ||||
| } | ||||
|  | ||||
| // | ||||
| // Number Literal | ||||
| // | ||||
|  | ||||
| // NumberLiteral represents a number node. | ||||
| type NumberLiteral struct { | ||||
| 	NodeType | ||||
| 	Loc | ||||
|  | ||||
| 	Value    float64 | ||||
| 	IsInt    bool | ||||
| 	Original string | ||||
| } | ||||
|  | ||||
| // NewNumberLiteral instanciates a new number node. | ||||
| func NewNumberLiteral(pos int, line int, val float64, isInt bool, original string) *NumberLiteral { | ||||
| 	return &NumberLiteral{ | ||||
| 		NodeType: NodeNumber, | ||||
| 		Loc:      Loc{pos, line}, | ||||
|  | ||||
| 		Value:    val, | ||||
| 		IsInt:    isInt, | ||||
| 		Original: original, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (node *NumberLiteral) String() string { | ||||
| 	return fmt.Sprintf("Number{Value:%s, Pos:%d}", node.Canonical(), node.Loc.Pos) | ||||
| } | ||||
|  | ||||
| // Accept is the receiver entry point for visitors. | ||||
| func (node *NumberLiteral) Accept(visitor Visitor) interface{} { | ||||
| 	return visitor.VisitNumber(node) | ||||
| } | ||||
|  | ||||
| // Canonical returns the canonical form of number node as a string (eg: "12", "-1.51"). | ||||
| func (node *NumberLiteral) Canonical() string { | ||||
| 	prec := -1 | ||||
| 	if node.IsInt { | ||||
| 		prec = 0 | ||||
| 	} | ||||
| 	return strconv.FormatFloat(node.Value, 'f', prec, 64) | ||||
| } | ||||
|  | ||||
| // Number returns an integer or a float. | ||||
| func (node *NumberLiteral) Number() interface{} { | ||||
| 	if node.IsInt { | ||||
| 		return int(node.Value) | ||||
| 	} | ||||
|  | ||||
| 	return node.Value | ||||
| } | ||||
|  | ||||
| // | ||||
| // Hash | ||||
| // | ||||
|  | ||||
| // Hash represents a hash node. | ||||
| type Hash struct { | ||||
| 	NodeType | ||||
| 	Loc | ||||
|  | ||||
| 	Pairs []*HashPair | ||||
| } | ||||
|  | ||||
| // NewHash instanciates a new hash node. | ||||
| func NewHash(pos int, line int) *Hash { | ||||
| 	return &Hash{ | ||||
| 		NodeType: NodeHash, | ||||
| 		Loc:      Loc{pos, line}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (node *Hash) String() string { | ||||
| 	result := fmt.Sprintf("Hash{[%d", node.Loc.Pos) | ||||
|  | ||||
| 	for i, p := range node.Pairs { | ||||
| 		if i > 0 { | ||||
| 			result += ", " | ||||
| 		} | ||||
| 		result += p.String() | ||||
| 	} | ||||
|  | ||||
| 	return result + fmt.Sprintf("], Pos:%d}", node.Loc.Pos) | ||||
| } | ||||
|  | ||||
| // Accept is the receiver entry point for visitors. | ||||
| func (node *Hash) Accept(visitor Visitor) interface{} { | ||||
| 	return visitor.VisitHash(node) | ||||
| } | ||||
|  | ||||
| // | ||||
| // HashPair | ||||
| // | ||||
|  | ||||
| // HashPair represents a hash pair node. | ||||
| type HashPair struct { | ||||
| 	NodeType | ||||
| 	Loc | ||||
|  | ||||
| 	Key string | ||||
| 	Val Node // Expression | ||||
| } | ||||
|  | ||||
| // NewHashPair instanciates a new hash pair node. | ||||
| func NewHashPair(pos int, line int) *HashPair { | ||||
| 	return &HashPair{ | ||||
| 		NodeType: NodeHashPair, | ||||
| 		Loc:      Loc{pos, line}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // String returns a string representation of receiver that can be used for debugging. | ||||
| func (node *HashPair) String() string { | ||||
| 	return node.Key + "=" + node.Val.String() | ||||
| } | ||||
|  | ||||
| // Accept is the receiver entry point for visitors. | ||||
| func (node *HashPair) Accept(visitor Visitor) interface{} { | ||||
| 	return visitor.VisitHashPair(node) | ||||
| } | ||||
							
								
								
									
										279
									
								
								vendor/github.com/aymerick/raymond/ast/print.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										279
									
								
								vendor/github.com/aymerick/raymond/ast/print.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,279 @@ | ||||
| package ast | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // printVisitor implements the Visitor interface to print a AST. | ||||
| type printVisitor struct { | ||||
| 	buf   string | ||||
| 	depth int | ||||
|  | ||||
| 	original bool | ||||
| 	inBlock  bool | ||||
| } | ||||
|  | ||||
| func newPrintVisitor() *printVisitor { | ||||
| 	return &printVisitor{} | ||||
| } | ||||
|  | ||||
| // Print returns a string representation of given AST, that can be used for debugging purpose. | ||||
| func Print(node Node) string { | ||||
| 	visitor := newPrintVisitor() | ||||
| 	node.Accept(visitor) | ||||
| 	return visitor.output() | ||||
| } | ||||
|  | ||||
| func (v *printVisitor) output() string { | ||||
| 	return v.buf | ||||
| } | ||||
|  | ||||
| func (v *printVisitor) indent() { | ||||
| 	for i := 0; i < v.depth; { | ||||
| 		v.buf += "  " | ||||
| 		i++ | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (v *printVisitor) str(val string) { | ||||
| 	v.buf += val | ||||
| } | ||||
|  | ||||
| func (v *printVisitor) nl() { | ||||
| 	v.str("\n") | ||||
| } | ||||
|  | ||||
| func (v *printVisitor) line(val string) { | ||||
| 	v.indent() | ||||
| 	v.str(val) | ||||
| 	v.nl() | ||||
| } | ||||
|  | ||||
| // | ||||
| // Visitor interface | ||||
| // | ||||
|  | ||||
| // Statements | ||||
|  | ||||
| // VisitProgram implements corresponding Visitor interface method | ||||
| func (v *printVisitor) VisitProgram(node *Program) interface{} { | ||||
| 	if len(node.BlockParams) > 0 { | ||||
| 		v.line("BLOCK PARAMS: [ " + strings.Join(node.BlockParams, " ") + " ]") | ||||
| 	} | ||||
|  | ||||
| 	for _, n := range node.Body { | ||||
| 		n.Accept(v) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // VisitMustache implements corresponding Visitor interface method | ||||
| func (v *printVisitor) VisitMustache(node *MustacheStatement) interface{} { | ||||
| 	v.indent() | ||||
| 	v.str("{{ ") | ||||
|  | ||||
| 	node.Expression.Accept(v) | ||||
|  | ||||
| 	v.str(" }}") | ||||
| 	v.nl() | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // VisitBlock implements corresponding Visitor interface method | ||||
| func (v *printVisitor) VisitBlock(node *BlockStatement) interface{} { | ||||
| 	v.inBlock = true | ||||
|  | ||||
| 	v.line("BLOCK:") | ||||
| 	v.depth++ | ||||
|  | ||||
| 	node.Expression.Accept(v) | ||||
|  | ||||
| 	if node.Program != nil { | ||||
| 		v.line("PROGRAM:") | ||||
| 		v.depth++ | ||||
| 		node.Program.Accept(v) | ||||
| 		v.depth-- | ||||
| 	} | ||||
|  | ||||
| 	if node.Inverse != nil { | ||||
| 		// if node.Program != nil { | ||||
| 		// 	v.depth++ | ||||
| 		// } | ||||
|  | ||||
| 		v.line("{{^}}") | ||||
| 		v.depth++ | ||||
| 		node.Inverse.Accept(v) | ||||
| 		v.depth-- | ||||
|  | ||||
| 		// if node.Program != nil { | ||||
| 		// 	v.depth-- | ||||
| 		// } | ||||
| 	} | ||||
|  | ||||
| 	v.inBlock = false | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // VisitPartial implements corresponding Visitor interface method | ||||
| func (v *printVisitor) VisitPartial(node *PartialStatement) interface{} { | ||||
| 	v.indent() | ||||
| 	v.str("{{> PARTIAL:") | ||||
|  | ||||
| 	v.original = true | ||||
| 	node.Name.Accept(v) | ||||
| 	v.original = false | ||||
|  | ||||
| 	if len(node.Params) > 0 { | ||||
| 		v.str(" ") | ||||
| 		node.Params[0].Accept(v) | ||||
| 	} | ||||
|  | ||||
| 	// hash | ||||
| 	if node.Hash != nil { | ||||
| 		v.str(" ") | ||||
| 		node.Hash.Accept(v) | ||||
| 	} | ||||
|  | ||||
| 	v.str(" }}") | ||||
| 	v.nl() | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // VisitContent implements corresponding Visitor interface method | ||||
| func (v *printVisitor) VisitContent(node *ContentStatement) interface{} { | ||||
| 	v.line("CONTENT[ '" + node.Value + "' ]") | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // VisitComment implements corresponding Visitor interface method | ||||
| func (v *printVisitor) VisitComment(node *CommentStatement) interface{} { | ||||
| 	v.line("{{! '" + node.Value + "' }}") | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Expressions | ||||
|  | ||||
| // VisitExpression implements corresponding Visitor interface method | ||||
| func (v *printVisitor) VisitExpression(node *Expression) interface{} { | ||||
| 	if v.inBlock { | ||||
| 		v.indent() | ||||
| 	} | ||||
|  | ||||
| 	// path | ||||
| 	node.Path.Accept(v) | ||||
|  | ||||
| 	// params | ||||
| 	v.str(" [") | ||||
| 	for i, n := range node.Params { | ||||
| 		if i > 0 { | ||||
| 			v.str(", ") | ||||
| 		} | ||||
| 		n.Accept(v) | ||||
| 	} | ||||
| 	v.str("]") | ||||
|  | ||||
| 	// hash | ||||
| 	if node.Hash != nil { | ||||
| 		v.str(" ") | ||||
| 		node.Hash.Accept(v) | ||||
| 	} | ||||
|  | ||||
| 	if v.inBlock { | ||||
| 		v.nl() | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // VisitSubExpression implements corresponding Visitor interface method | ||||
| func (v *printVisitor) VisitSubExpression(node *SubExpression) interface{} { | ||||
| 	node.Expression.Accept(v) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // VisitPath implements corresponding Visitor interface method | ||||
| func (v *printVisitor) VisitPath(node *PathExpression) interface{} { | ||||
| 	if v.original { | ||||
| 		v.str(node.Original) | ||||
| 	} else { | ||||
| 		path := strings.Join(node.Parts, "/") | ||||
|  | ||||
| 		result := "" | ||||
| 		if node.Data { | ||||
| 			result += "@" | ||||
| 		} | ||||
|  | ||||
| 		v.str(result + "PATH:" + path) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Literals | ||||
|  | ||||
| // VisitString implements corresponding Visitor interface method | ||||
| func (v *printVisitor) VisitString(node *StringLiteral) interface{} { | ||||
| 	if v.original { | ||||
| 		v.str(node.Value) | ||||
| 	} else { | ||||
| 		v.str("\"" + node.Value + "\"") | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // VisitBoolean implements corresponding Visitor interface method | ||||
| func (v *printVisitor) VisitBoolean(node *BooleanLiteral) interface{} { | ||||
| 	if v.original { | ||||
| 		v.str(node.Original) | ||||
| 	} else { | ||||
| 		v.str(fmt.Sprintf("BOOLEAN{%s}", node.Canonical())) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // VisitNumber implements corresponding Visitor interface method | ||||
| func (v *printVisitor) VisitNumber(node *NumberLiteral) interface{} { | ||||
| 	if v.original { | ||||
| 		v.str(node.Original) | ||||
| 	} else { | ||||
| 		v.str(fmt.Sprintf("NUMBER{%s}", node.Canonical())) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Miscellaneous | ||||
|  | ||||
| // VisitHash implements corresponding Visitor interface method | ||||
| func (v *printVisitor) VisitHash(node *Hash) interface{} { | ||||
| 	v.str("HASH{") | ||||
|  | ||||
| 	for i, p := range node.Pairs { | ||||
| 		if i > 0 { | ||||
| 			v.str(", ") | ||||
| 		} | ||||
| 		p.Accept(v) | ||||
| 	} | ||||
|  | ||||
| 	v.str("}") | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // VisitHashPair implements corresponding Visitor interface method | ||||
| func (v *printVisitor) VisitHashPair(node *HashPair) interface{} { | ||||
| 	v.str(node.Key + "=") | ||||
| 	node.Val.Accept(v) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
		Reference in New Issue
	
	Block a user