mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-03 23:40:03 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			424 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			424 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
Copyright 2016 Google Inc. All Rights Reserved.
 | 
						|
 | 
						|
Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
you may not use this file except in compliance with the License.
 | 
						|
You may obtain a copy of the License at
 | 
						|
 | 
						|
    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 | 
						|
Unless required by applicable law or agreed to in writing, software
 | 
						|
distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
 See the License for the specific language governing permissions and
 | 
						|
 limitations under the License.
 | 
						|
*/
 | 
						|
 | 
						|
// Package build implements parsing and printing of BUILD files.
 | 
						|
package build
 | 
						|
 | 
						|
// Syntax data structure definitions.
 | 
						|
 | 
						|
import (
 | 
						|
	"strings"
 | 
						|
	"unicode/utf8"
 | 
						|
)
 | 
						|
 | 
						|
// A Position describes the position between two bytes of input.
 | 
						|
type Position struct {
 | 
						|
	Line     int // line in input (starting at 1)
 | 
						|
	LineRune int // rune in line (starting at 1)
 | 
						|
	Byte     int // byte in input (starting at 0)
 | 
						|
}
 | 
						|
 | 
						|
// add returns the position at the end of s, assuming it starts at p.
 | 
						|
func (p Position) add(s string) Position {
 | 
						|
	p.Byte += len(s)
 | 
						|
	if n := strings.Count(s, "\n"); n > 0 {
 | 
						|
		p.Line += n
 | 
						|
		s = s[strings.LastIndex(s, "\n")+1:]
 | 
						|
		p.LineRune = 1
 | 
						|
	}
 | 
						|
	p.LineRune += utf8.RuneCountInString(s)
 | 
						|
	return p
 | 
						|
}
 | 
						|
 | 
						|
// An Expr represents an input element.
 | 
						|
type Expr interface {
 | 
						|
	// Span returns the start and end position of the expression,
 | 
						|
	// excluding leading or trailing comments.
 | 
						|
	Span() (start, end Position)
 | 
						|
 | 
						|
	// Comment returns the comments attached to the expression.
 | 
						|
	// This method would normally be named 'Comments' but that
 | 
						|
	// would interfere with embedding a type of the same name.
 | 
						|
	Comment() *Comments
 | 
						|
}
 | 
						|
 | 
						|
// A Comment represents a single # comment.
 | 
						|
type Comment struct {
 | 
						|
	Start  Position
 | 
						|
	Token  string // without trailing newline
 | 
						|
	Suffix bool   // an end of line (not whole line) comment
 | 
						|
}
 | 
						|
 | 
						|
// Comments collects the comments associated with an expression.
 | 
						|
type Comments struct {
 | 
						|
	Before []Comment // whole-line comments before this expression
 | 
						|
	Suffix []Comment // end-of-line comments after this expression
 | 
						|
 | 
						|
	// For top-level expressions only, After lists whole-line
 | 
						|
	// comments following the expression.
 | 
						|
	After []Comment
 | 
						|
}
 | 
						|
 | 
						|
// Comment returns the receiver. This isn't useful by itself, but
 | 
						|
// a Comments struct is embedded into all the expression
 | 
						|
// implementation types, and this gives each of those a Comment
 | 
						|
// method to satisfy the Expr interface.
 | 
						|
func (c *Comments) Comment() *Comments {
 | 
						|
	return c
 | 
						|
}
 | 
						|
 | 
						|
// A File represents an entire BUILD file.
 | 
						|
type File struct {
 | 
						|
	Path string // file path, relative to workspace directory
 | 
						|
	Comments
 | 
						|
	Stmt []Expr
 | 
						|
}
 | 
						|
 | 
						|
func (x *File) Span() (start, end Position) {
 | 
						|
	if len(x.Stmt) == 0 {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	start, _ = x.Stmt[0].Span()
 | 
						|
	_, end = x.Stmt[len(x.Stmt)-1].Span()
 | 
						|
	return start, end
 | 
						|
}
 | 
						|
 | 
						|
// A CommentBlock represents a top-level block of comments separate
 | 
						|
// from any rule.
 | 
						|
type CommentBlock struct {
 | 
						|
	Comments
 | 
						|
	Start Position
 | 
						|
}
 | 
						|
 | 
						|
func (x *CommentBlock) Span() (start, end Position) {
 | 
						|
	return x.Start, x.Start
 | 
						|
}
 | 
						|
 | 
						|
// A PythonBlock represents a blob of Python code, typically a def or for loop.
 | 
						|
type PythonBlock struct {
 | 
						|
	Comments
 | 
						|
	Start Position
 | 
						|
	Token string // raw Python code, including final newline
 | 
						|
}
 | 
						|
 | 
						|
func (x *PythonBlock) Span() (start, end Position) {
 | 
						|
	return x.Start, x.Start.add(x.Token)
 | 
						|
}
 | 
						|
 | 
						|
// A LiteralExpr represents a literal identifier or number.
 | 
						|
type LiteralExpr struct {
 | 
						|
	Comments
 | 
						|
	Start Position
 | 
						|
	Token string // identifier token
 | 
						|
}
 | 
						|
 | 
						|
func (x *LiteralExpr) Span() (start, end Position) {
 | 
						|
	return x.Start, x.Start.add(x.Token)
 | 
						|
}
 | 
						|
 | 
						|
// A StringExpr represents a single literal string.
 | 
						|
type StringExpr struct {
 | 
						|
	Comments
 | 
						|
	Start       Position
 | 
						|
	Value       string // string value (decoded)
 | 
						|
	TripleQuote bool   // triple quote output
 | 
						|
	End         Position
 | 
						|
 | 
						|
	// To allow specific formatting of string literals,
 | 
						|
	// at least within our requirements, record the
 | 
						|
	// preferred form of Value. This field is a hint:
 | 
						|
	// it is only used if it is a valid quoted form for Value.
 | 
						|
	Token string
 | 
						|
}
 | 
						|
 | 
						|
func (x *StringExpr) Span() (start, end Position) {
 | 
						|
	return x.Start, x.End
 | 
						|
}
 | 
						|
 | 
						|
// An End represents the end of a parenthesized or bracketed expression.
 | 
						|
// It is a place to hang comments.
 | 
						|
type End struct {
 | 
						|
	Comments
 | 
						|
	Pos Position
 | 
						|
}
 | 
						|
 | 
						|
func (x *End) Span() (start, end Position) {
 | 
						|
	return x.Pos, x.Pos.add(")")
 | 
						|
}
 | 
						|
 | 
						|
// A CallExpr represents a function call expression: X(List).
 | 
						|
type CallExpr struct {
 | 
						|
	Comments
 | 
						|
	X              Expr
 | 
						|
	ListStart      Position // position of (
 | 
						|
	List           []Expr
 | 
						|
	End                 // position of )
 | 
						|
	ForceCompact   bool // force compact (non-multiline) form when printing
 | 
						|
	ForceMultiLine bool // force multiline form when printing
 | 
						|
}
 | 
						|
 | 
						|
func (x *CallExpr) Span() (start, end Position) {
 | 
						|
	start, _ = x.X.Span()
 | 
						|
	return start, x.End.Pos.add(")")
 | 
						|
}
 | 
						|
 | 
						|
// A DotExpr represents a field selector: X.Name.
 | 
						|
type DotExpr struct {
 | 
						|
	Comments
 | 
						|
	X       Expr
 | 
						|
	Dot     Position
 | 
						|
	NamePos Position
 | 
						|
	Name    string
 | 
						|
}
 | 
						|
 | 
						|
func (x *DotExpr) Span() (start, end Position) {
 | 
						|
	start, _ = x.X.Span()
 | 
						|
	return start, x.NamePos.add(x.Name)
 | 
						|
}
 | 
						|
 | 
						|
// A ListForExpr represents a list comprehension expression: [X for ... if ...].
 | 
						|
type ListForExpr struct {
 | 
						|
	Comments
 | 
						|
	ForceMultiLine bool   // split expression across multiple lines
 | 
						|
	Brack          string // "", "()", or "[]"
 | 
						|
	Start          Position
 | 
						|
	X              Expr
 | 
						|
	For            []*ForClauseWithIfClausesOpt
 | 
						|
	End
 | 
						|
}
 | 
						|
 | 
						|
func (x *ListForExpr) Span() (start, end Position) {
 | 
						|
	return x.Start, x.End.Pos.add("]")
 | 
						|
}
 | 
						|
 | 
						|
// A ForClause represents a for clause in a list comprehension: for Var in Expr.
 | 
						|
type ForClause struct {
 | 
						|
	Comments
 | 
						|
	For  Position
 | 
						|
	Var  []Expr
 | 
						|
	In   Position
 | 
						|
	Expr Expr
 | 
						|
}
 | 
						|
 | 
						|
func (x *ForClause) Span() (start, end Position) {
 | 
						|
	_, end = x.Expr.Span()
 | 
						|
	return x.For, end
 | 
						|
}
 | 
						|
 | 
						|
// An IfClause represents an if clause in a list comprehension: if Cond.
 | 
						|
type IfClause struct {
 | 
						|
	Comments
 | 
						|
	If   Position
 | 
						|
	Cond Expr
 | 
						|
}
 | 
						|
 | 
						|
func (x *IfClause) Span() (start, end Position) {
 | 
						|
	_, end = x.Cond.Span()
 | 
						|
	return x.If, end
 | 
						|
}
 | 
						|
 | 
						|
// A ForClauseWithIfClausesOpt represents a for clause in a list comprehension followed by optional
 | 
						|
// if expressions: for ... in ... [if ... if ...]
 | 
						|
type ForClauseWithIfClausesOpt struct {
 | 
						|
	Comments
 | 
						|
	For *ForClause
 | 
						|
	Ifs []*IfClause
 | 
						|
}
 | 
						|
 | 
						|
func (x *ForClauseWithIfClausesOpt) Span() (start, end Position) {
 | 
						|
	start, end = x.For.Span()
 | 
						|
	if len(x.Ifs) > 0 {
 | 
						|
		_, end = x.Ifs[len(x.Ifs)-1].Span()
 | 
						|
	}
 | 
						|
 | 
						|
	return start, end
 | 
						|
}
 | 
						|
 | 
						|
// A KeyValueExpr represents a dictionary entry: Key: Value.
 | 
						|
type KeyValueExpr struct {
 | 
						|
	Comments
 | 
						|
	Key   Expr
 | 
						|
	Colon Position
 | 
						|
	Value Expr
 | 
						|
}
 | 
						|
 | 
						|
func (x *KeyValueExpr) Span() (start, end Position) {
 | 
						|
	start, _ = x.Key.Span()
 | 
						|
	_, end = x.Value.Span()
 | 
						|
	return start, end
 | 
						|
}
 | 
						|
 | 
						|
// A DictExpr represents a dictionary literal: { List }.
 | 
						|
type DictExpr struct {
 | 
						|
	Comments
 | 
						|
	Start Position
 | 
						|
	List  []Expr   // all *KeyValueExprs
 | 
						|
	Comma Position // position of trailing comma, if any
 | 
						|
	End
 | 
						|
	ForceMultiLine bool // force multiline form when printing
 | 
						|
}
 | 
						|
 | 
						|
func (x *DictExpr) Span() (start, end Position) {
 | 
						|
	return x.Start, x.End.Pos.add("}")
 | 
						|
}
 | 
						|
 | 
						|
// A ListExpr represents a list literal: [ List ].
 | 
						|
type ListExpr struct {
 | 
						|
	Comments
 | 
						|
	Start Position
 | 
						|
	List  []Expr
 | 
						|
	Comma Position // position of trailing comma, if any
 | 
						|
	End
 | 
						|
	ForceMultiLine bool // force multiline form when printing
 | 
						|
}
 | 
						|
 | 
						|
func (x *ListExpr) Span() (start, end Position) {
 | 
						|
	return x.Start, x.End.Pos.add("]")
 | 
						|
}
 | 
						|
 | 
						|
// A SetExpr represents a set literal: { List }.
 | 
						|
type SetExpr struct {
 | 
						|
	Comments
 | 
						|
	Start Position
 | 
						|
	List  []Expr
 | 
						|
	Comma Position // position of trailing comma, if any
 | 
						|
	End
 | 
						|
	ForceMultiLine bool // force multiline form when printing
 | 
						|
}
 | 
						|
 | 
						|
func (x *SetExpr) Span() (start, end Position) {
 | 
						|
	return x.Start, x.End.Pos.add("}")
 | 
						|
}
 | 
						|
 | 
						|
// A TupleExpr represents a tuple literal: (List)
 | 
						|
type TupleExpr struct {
 | 
						|
	Comments
 | 
						|
	Start Position
 | 
						|
	List  []Expr
 | 
						|
	Comma Position // position of trailing comma, if any
 | 
						|
	End
 | 
						|
	ForceCompact   bool // force compact (non-multiline) form when printing
 | 
						|
	ForceMultiLine bool // force multiline form when printing
 | 
						|
}
 | 
						|
 | 
						|
func (x *TupleExpr) Span() (start, end Position) {
 | 
						|
	return x.Start, x.End.Pos.add(")")
 | 
						|
}
 | 
						|
 | 
						|
// A UnaryExpr represents a unary expression: Op X.
 | 
						|
type UnaryExpr struct {
 | 
						|
	Comments
 | 
						|
	OpStart Position
 | 
						|
	Op      string
 | 
						|
	X       Expr
 | 
						|
}
 | 
						|
 | 
						|
func (x *UnaryExpr) Span() (start, end Position) {
 | 
						|
	_, end = x.X.Span()
 | 
						|
	return x.OpStart, end
 | 
						|
}
 | 
						|
 | 
						|
// A BinaryExpr represents a binary expression: X Op Y.
 | 
						|
type BinaryExpr struct {
 | 
						|
	Comments
 | 
						|
	X         Expr
 | 
						|
	OpStart   Position
 | 
						|
	Op        string
 | 
						|
	LineBreak bool // insert line break between Op and Y
 | 
						|
	Y         Expr
 | 
						|
}
 | 
						|
 | 
						|
func (x *BinaryExpr) Span() (start, end Position) {
 | 
						|
	start, _ = x.X.Span()
 | 
						|
	_, end = x.Y.Span()
 | 
						|
	return start, end
 | 
						|
}
 | 
						|
 | 
						|
// A ParenExpr represents a parenthesized expression: (X).
 | 
						|
type ParenExpr struct {
 | 
						|
	Comments
 | 
						|
	Start Position
 | 
						|
	X     Expr
 | 
						|
	End
 | 
						|
	ForceMultiLine bool // insert line break after opening ( and before closing )
 | 
						|
}
 | 
						|
 | 
						|
func (x *ParenExpr) Span() (start, end Position) {
 | 
						|
	return x.Start, x.End.Pos.add(")")
 | 
						|
}
 | 
						|
 | 
						|
// A SliceExpr represents a slice expression: X[Y:Z].
 | 
						|
type SliceExpr struct {
 | 
						|
	Comments
 | 
						|
	X          Expr
 | 
						|
	SliceStart Position
 | 
						|
	Y          Expr
 | 
						|
	Colon      Position
 | 
						|
	Z          Expr
 | 
						|
	End        Position
 | 
						|
}
 | 
						|
 | 
						|
func (x *SliceExpr) Span() (start, end Position) {
 | 
						|
	start, _ = x.X.Span()
 | 
						|
	return start, x.End
 | 
						|
}
 | 
						|
 | 
						|
// An IndexExpr represents an index expression: X[Y].
 | 
						|
type IndexExpr struct {
 | 
						|
	Comments
 | 
						|
	X          Expr
 | 
						|
	IndexStart Position
 | 
						|
	Y          Expr
 | 
						|
	End        Position
 | 
						|
}
 | 
						|
 | 
						|
func (x *IndexExpr) Span() (start, end Position) {
 | 
						|
	start, _ = x.X.Span()
 | 
						|
	return start, x.End
 | 
						|
}
 | 
						|
 | 
						|
// A LambdaExpr represents a lambda expression: lambda Var: Expr.
 | 
						|
type LambdaExpr struct {
 | 
						|
	Comments
 | 
						|
	Lambda Position
 | 
						|
	Var    []Expr
 | 
						|
	Colon  Position
 | 
						|
	Expr   Expr
 | 
						|
}
 | 
						|
 | 
						|
func (x *LambdaExpr) Span() (start, end Position) {
 | 
						|
	_, end = x.Expr.Span()
 | 
						|
	return x.Lambda, end
 | 
						|
}
 | 
						|
 | 
						|
// ConditionalExpr represents the conditional: X if TEST else ELSE.
 | 
						|
type ConditionalExpr struct {
 | 
						|
	Comments
 | 
						|
	Then      Expr
 | 
						|
	IfStart   Position
 | 
						|
	Test      Expr
 | 
						|
	ElseStart Position
 | 
						|
	Else      Expr
 | 
						|
}
 | 
						|
 | 
						|
// Span returns the start and end position of the expression,
 | 
						|
// excluding leading or trailing comments.
 | 
						|
func (x *ConditionalExpr) Span() (start, end Position) {
 | 
						|
	start, _ = x.Then.Span()
 | 
						|
	_, end = x.Else.Span()
 | 
						|
	return start, end
 | 
						|
}
 |