& is only special if it begins a key. - is only special if followed by another - in a key. ' " and | are only special if they begin an unquoted key or value.
var UnquotedKeySpecials = string([]rune{'#', ';', '\n', '\\', '{', '}', '[', ']', '\'', '"', '|', ':', '.', '-', '<', '>', '*', '&', '(', ')', '@', '&'})
var UnquotedValueSpecials = string([]rune{'#', ';', '\n', '\\', '{', '}', '[', ']', '\'', '"', '|', '$', '@'})
func IsDoubleGlob(pattern []string) bool
func IsTripleGlob(pattern []string) bool
type Array struct { Range Range `json:"range"` Nodes []ArrayNodeBox `json:"nodes"` }
func (a *Array) GetRange() Range
func (a *Array) Type() string
ArrayNode is implemented by nodes that may be children of Arrays.
type ArrayNode interface { Node // contains filtered or unexported methods }
ArrayNodeBox is used to box ArrayNode for JSON persistence.
type ArrayNodeBox struct { Comment *Comment `json:"comment,omitempty"` BlockComment *BlockComment `json:"block_comment,omitempty"` Substitution *Substitution `json:"substitution,omitempty"` Import *Import `json:"import,omitempty"` Null *Null `json:"null,omitempty"` Boolean *Boolean `json:"boolean,omitempty"` Number *Number `json:"number,omitempty"` UnquotedString *UnquotedString `json:"unquoted_string,omitempty"` DoubleQuotedString *DoubleQuotedString `json:"double_quoted_string,omitempty"` SingleQuotedString *SingleQuotedString `json:"single_quoted_string,omitempty"` BlockString *BlockString `json:"block_string,omitempty"` Array *Array `json:"array,omitempty"` Map *Map `json:"map,omitempty"` }
func MakeArrayNodeBox(an ArrayNode) ArrayNodeBox
func (ab ArrayNodeBox) Unbox() ArrayNode
type BlockComment struct { Range Range `json:"range"` Value string `json:"value"` }
func (c *BlockComment) GetRange() Range
func (c *BlockComment) Type() string
type BlockString struct { Range Range `json:"range"` // Quote contains the pipe delimiter for the block string. // e.g. if 5 pipes were used to begin a block string, then Quote == "||||". // The tag is not included. Quote string `json:"quote"` Tag string `json:"tag"` Value string `json:"value"` }
func (s *BlockString) Copy() String
func (s *BlockString) GetRange() Range
func (s *BlockString) ScalarString() string
func (s *BlockString) SetString(s2 string)
func (s *BlockString) Type() string
type Boolean struct { Range Range `json:"range"` Value bool `json:"value"` }
func (b *Boolean) GetRange() Range
func (b *Boolean) ScalarString() string
func (b *Boolean) Type() string
type Comment struct { Range Range `json:"range"` Value string `json:"value"` }
func (c *Comment) GetRange() Range
func (c *Comment) Type() string
type DoubleQuotedString struct { Range Range `json:"range"` Value []InterpolationBox `json:"value"` }
func FlatDoubleQuotedString(s string) *DoubleQuotedString
func (s *DoubleQuotedString) Coalesce()
func (s *DoubleQuotedString) Copy() String
func (s *DoubleQuotedString) GetRange() Range
func (s *DoubleQuotedString) ScalarString() string
func (s *DoubleQuotedString) SetString(s2 string)
func (s *DoubleQuotedString) Type() string
type Edge struct { Range Range `json:"range"` Src *KeyPath `json:"src"` // empty, < or * SrcArrow string `json:"src_arrow"` Dst *KeyPath `json:"dst"` // empty, > or * DstArrow string `json:"dst_arrow"` }
func (e1 *Edge) Equals(e2 *Edge) bool
func (e *Edge) GetRange() Range
func (e *Edge) Type() string
type EdgeIndex struct { Range Range `json:"range"` // [n] or [*] Int *int `json:"int"` Glob bool `json:"glob"` }
func (ei1 *EdgeIndex) Equals(ei2 *EdgeIndex) bool
func (i *EdgeIndex) GetRange() Range
func (i *EdgeIndex) Type() string
TODO: Right now this is here to be available in both the Parser and Compiler but eventually we should make this a real part of the AST so that autofmt works on files with parse errors and semantically it makes more sense. Compile would continue to maintain a separate set of errors and then we'd do a merge & sort to get the final list of errors for user display.
type Error struct { Range Range `json:"range"` Message string `json:"errmsg"` }
func (e Error) Error() string
type Import struct { Range Range `json:"range"` Spread bool `json:"spread"` Pre string `json:"pre"` Path []*StringBox `json:"path"` }
func (i *Import) GetRange() Range
func (i *Import) IDA() (ida []string)
func (i *Import) PathWithPre() string
func (i *Import) Type() string
InterpolationBox is used to select between strings and substitutions in unquoted and double quoted strings. There is no corresponding interface to avoid unnecessary abstraction.
type InterpolationBox struct { String *string `json:"string,omitempty"` StringRaw *string `json:"raw_string,omitempty"` Substitution *Substitution `json:"substitution,omitempty"` }
TODO: require @ on import values for readability
type Key struct { Range Range `json:"range"` // Indicates this MapKey is a filter selector. Ampersand bool `json:"ampersand,omitempty"` // Indicates this MapKey is a not filter selector. NotAmpersand bool `json:"not_ampersand,omitempty"` // At least one of Key and Edges will be set but all four can also be set. // The following are all valid MapKeys: // Key: // x // Edges: // x -> y // Edges and EdgeIndex: // (x -> y)[*] // Edges and EdgeKey: // (x -> y).label // Key and Edges: // container.(x -> y) // Key, Edges and EdgeKey: // container.(x -> y -> z).label // Key, Edges, EdgeIndex EdgeKey: // container.(x -> y -> z)[4].label Key *KeyPath `json:"key,omitempty"` Edges []*Edge `json:"edges,omitempty"` EdgeIndex *EdgeIndex `json:"edge_index,omitempty"` EdgeKey *KeyPath `json:"edge_key,omitempty"` Primary ScalarBox `json:"primary,omitempty"` Value ValueBox `json:"value"` }
func (mk *Key) Copy() *Key
func (mk1 *Key) D2OracleEquals(mk2 *Key) bool
func (mk1 *Key) Equals(mk2 *Key) bool
func (k *Key) GetRange() Range
func (mk *Key) HasGlob() bool
func (mk *Key) HasTripleGlob() bool
func (mk *Key) SetScalar(scalar ScalarBox)
func (mk *Key) SupportsGlobFilters() bool
func (k *Key) Type() string
type KeyPath struct { Range Range `json:"range"` Path []*StringBox `json:"path"` }
func MakeKeyPath(a []string) *KeyPath
func (kp *KeyPath) Copy() *KeyPath
func (kp1 *KeyPath) Equals(kp2 *KeyPath) bool
func (kp *KeyPath) FirstGlob() int
func (k *KeyPath) GetRange() Range
func (kp *KeyPath) HasGlob() bool
func (kp *KeyPath) HasMultiGlob() bool
func (kp *KeyPath) HasTripleGlob() bool
func (kp *KeyPath) IDA() (ida []string)
func (kp *KeyPath) Last() *StringBox
func (k *KeyPath) Type() string
type Map struct { Range Range `json:"range"` Nodes []MapNodeBox `json:"nodes"` }
func (m *Map) GetRange() Range
func (m *Map) HasFilter() bool
func (m *Map) InsertAfter(cursor, n MapNode)
func (m *Map) InsertBefore(cursor, n MapNode)
func (m *Map) IsFileMap() bool
func (m *Map) Type() string
MapNode is implemented by nodes that may be children of Maps.
type MapNode interface { Node // contains filtered or unexported methods }
MapNodeBox is used to box MapNode for JSON persistence.
type MapNodeBox struct { Comment *Comment `json:"comment,omitempty"` BlockComment *BlockComment `json:"block_comment,omitempty"` Substitution *Substitution `json:"substitution,omitempty"` Import *Import `json:"import,omitempty"` MapKey *Key `json:"map_key,omitempty"` }
func MakeMapNodeBox(n MapNode) MapNodeBox
func (mb MapNodeBox) IsBoardNode() bool
func (mb MapNodeBox) Unbox() MapNode
Node is the base interface implemented by all d2 AST nodes. TODO: add error node for autofmt of incomplete AST
type Node interface { // Type returns the user friendly name of the node. Type() string // GetRange returns the range a node occupies in its file. GetRange() Range // contains filtered or unexported methods }
type Null struct { Range Range `json:"range"` }
func (n *Null) GetRange() Range
func (n *Null) ScalarString() string
TODO: mistake, move into parse.go
func (n *Null) Type() string
type Number struct { Range Range `json:"range"` Raw string `json:"raw"` Value *big.Rat `json:"value"` }
func (n *Number) GetRange() Range
func (n *Number) ScalarString() string
func (n *Number) Type() string
Position represents a line:column and byte position in a file.
note: Line and Column are zero indexed. note: Column and Byte are UTF-8 byte indexes unless byUTF16 was passed to Position.Advance in . which they are UTF-16 code unit indexes. . If intended for Javascript consumption like in the browser or via LSP, byUTF16 is . set to true.
type Position struct { Line int Column int Byte int }
func (p Position) Advance(r rune, byUTF16 bool) Position
Advance advances p's Line, Column and Byte by r and returns the new Position. Set byUTF16 to advance the position as though r represents a UTF-16 codepoint.
func (p Position) AdvanceString(s string, byUTF16 bool) Position
func (p Position) Before(p2 Position) bool
func (p Position) Debug() string
func (p *Position) From(src *Position)
From copies src into p. It's used in the d2parser package to set a node's Range.End to the parser's current pos on all return paths with defer.
func (p Position) MarshalText() ([]byte, error)
See docs on Range.
func (p Position) String() string
String returns a line:column representation of the position suitable for error messages.
note: Should not normally be used directly, see Range.String()
func (p Position) Subtract(r rune, byUTF16 bool) Position
func (p Position) SubtractString(s string, byUTF16 bool) Position
func (p *Position) UnmarshalText(b []byte) (err error)
See docs on Range.
Range represents a range between Start and End in Path. It's also used in the d2parser package to represent the range of an error.
note: See docs on Position.
It has a custom JSON string encoding with encoding.TextMarshaler and encoding.TextUnmarshaler to keep it compact as the JSON struct encoding is too verbose, especially with json.MarshalIndent.
It looks like path,start-end
type Range struct { Path string Start Position End Position }
func MakeRange(s string) Range
func (r Range) Before(r2 Range) bool
func (r Range) MarshalText() ([]byte, error)
See docs on Range.
func (r Range) OneLine() bool
OneLine returns true if the Range starts and ends on the same line.
func (r Range) String() string
String returns a string representation of the range including only the path and start.
If path is empty, it will be omitted.
The format is path:start
func (r *Range) UnmarshalText(b []byte) (err error)
See docs on Range.
Scalar is implemented by nodes that represent scalar values.
type Scalar interface { Value ScalarString() string // contains filtered or unexported methods }
ScalarBox is used to box Scalar for JSON persistence. TODO: implement ScalarString()
type ScalarBox struct { Null *Null `json:"null,omitempty"` Boolean *Boolean `json:"boolean,omitempty"` Number *Number `json:"number,omitempty"` UnquotedString *UnquotedString `json:"unquoted_string,omitempty"` DoubleQuotedString *DoubleQuotedString `json:"double_quoted_string,omitempty"` SingleQuotedString *SingleQuotedString `json:"single_quoted_string,omitempty"` BlockString *BlockString `json:"block_string,omitempty"` }
func (sb ScalarBox) ScalarString() string
func (sb ScalarBox) Unbox() Scalar
type SingleQuotedString struct { Range Range `json:"range"` Raw string `json:"raw"` Value string `json:"value"` }
func (s *SingleQuotedString) Copy() String
func (s *SingleQuotedString) GetRange() Range
func (s *SingleQuotedString) ScalarString() string
func (s *SingleQuotedString) SetString(s2 string)
func (s *SingleQuotedString) Type() string
String is implemented by nodes that represent strings.
type String interface { Scalar SetString(string) Copy() String // contains filtered or unexported methods }
func RawString(s string, inKey bool) String
RawString returns s in a AST String node that can format s in the most aesthetically pleasing way.
StringBox is used to box String for JSON persistence.
type StringBox struct { UnquotedString *UnquotedString `json:"unquoted_string,omitempty"` DoubleQuotedString *DoubleQuotedString `json:"double_quoted_string,omitempty"` SingleQuotedString *SingleQuotedString `json:"single_quoted_string,omitempty"` BlockString *BlockString `json:"block_string,omitempty"` }
func RawStringBox(s string, inKey bool) *StringBox
func (sb *StringBox) ScalarString() string
func (sb *StringBox) Unbox() String
type Substitution struct { Range Range `json:"range"` Spread bool `json:"spread"` Path []*StringBox `json:"path"` }
func (s *Substitution) GetRange() Range
func (s *Substitution) IDA() (ida []string)
func (s *Substitution) Type() string
type UnquotedString struct { Range Range `json:"range"` Value []InterpolationBox `json:"value"` // Pattern holds the parsed glob pattern if in a key and the unquoted string represents a valid pattern. Pattern []string `json:"pattern,omitempty"` }
func FlatUnquotedString(s string) *UnquotedString
func (s *UnquotedString) Coalesce()
func (s *UnquotedString) Copy() String
func (s *UnquotedString) GetRange() Range
func (s *UnquotedString) ScalarString() string
func (s *UnquotedString) SetString(s2 string)
func (s *UnquotedString) Type() string
Value is implemented by nodes that may be values of a key.
type Value interface { ArrayNode // contains filtered or unexported methods }
ValueBox is used to box Value for JSON persistence.
type ValueBox struct { Null *Null `json:"null,omitempty"` Boolean *Boolean `json:"boolean,omitempty"` Number *Number `json:"number,omitempty"` UnquotedString *UnquotedString `json:"unquoted_string,omitempty"` DoubleQuotedString *DoubleQuotedString `json:"double_quoted_string,omitempty"` SingleQuotedString *SingleQuotedString `json:"single_quoted_string,omitempty"` BlockString *BlockString `json:"block_string,omitempty"` Array *Array `json:"array,omitempty"` Map *Map `json:"map,omitempty"` Import *Import `json:"import,omitempty"` }
func MakeValueBox(v Value) ValueBox
func (vb ValueBox) ScalarBox() ScalarBox
func (vb ValueBox) StringBox() *StringBox
func (vb ValueBox) Unbox() Value