d2ir: Implement lazy globs and triple glob
This finishes up the globs implementation! See tests for what I mean by lazy globs and what the triple glob does.
This commit is contained in:
parent
24a1e006d0
commit
bb6b176dee
10 changed files with 25522 additions and 741 deletions
|
|
@ -723,7 +723,43 @@ func (mk *Key) SetScalar(scalar ScalarBox) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mk *Key) HasQueryGlob() bool {
|
func (mk *Key) HasGlob() bool {
|
||||||
|
if mk.Key.HasGlob() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, e := range mk.Edges {
|
||||||
|
if e.Src.HasGlob() || e.Dst.HasGlob() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if mk.EdgeIndex != nil && mk.EdgeIndex.Glob {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if mk.EdgeKey.HasGlob() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mk *Key) HasTripleGlob() bool {
|
||||||
|
if mk.Key.HasTripleGlob() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, e := range mk.Edges {
|
||||||
|
if e.Src.HasTripleGlob() || e.Dst.HasTripleGlob() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if mk.EdgeIndex != nil && mk.EdgeIndex.Glob {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if mk.EdgeKey.HasTripleGlob() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mk *Key) SupportsGlobFilters() bool {
|
||||||
if mk.Key.HasGlob() && len(mk.Edges) == 0 {
|
if mk.Key.HasGlob() && len(mk.Edges) == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -736,6 +772,11 @@ func (mk *Key) HasQueryGlob() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mk *Key) Copy() *Key {
|
||||||
|
mk2 := *mk
|
||||||
|
return &mk2
|
||||||
|
}
|
||||||
|
|
||||||
type KeyPath struct {
|
type KeyPath struct {
|
||||||
Range Range `json:"range"`
|
Range Range `json:"range"`
|
||||||
Path []*StringBox `json:"path"`
|
Path []*StringBox `json:"path"`
|
||||||
|
|
@ -763,16 +804,12 @@ func (kp *KeyPath) Copy() *KeyPath {
|
||||||
return &kp2
|
return &kp2
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kp *KeyPath) HasDoubleGlob() bool {
|
func IsDoubleGlob(pattern []string) bool {
|
||||||
if kp == nil {
|
return len(pattern) == 3 && pattern[0] == "*" && pattern[1] == "" && pattern[2] == "*"
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
for _, el := range kp.Path {
|
|
||||||
if el.UnquotedString != nil && el.ScalarString() == "**" {
|
func IsTripleGlob(pattern []string) bool {
|
||||||
return true
|
return len(pattern) == 5 && pattern[0] == "*" && pattern[1] == "" && pattern[2] == "*" && pattern[3] == "" && pattern[4] == "*"
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kp *KeyPath) HasGlob() bool {
|
func (kp *KeyPath) HasGlob() bool {
|
||||||
|
|
@ -787,6 +824,30 @@ func (kp *KeyPath) HasGlob() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (kp *KeyPath) HasTripleGlob() bool {
|
||||||
|
if kp == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, el := range kp.Path {
|
||||||
|
if el.UnquotedString != nil && IsTripleGlob(el.UnquotedString.Pattern) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (kp *KeyPath) HasMultiGlob() bool {
|
||||||
|
if kp == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, el := range kp.Path {
|
||||||
|
if el.UnquotedString != nil && (IsDoubleGlob(el.UnquotedString.Pattern) || IsTripleGlob(el.UnquotedString.Pattern)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type Edge struct {
|
type Edge struct {
|
||||||
Range Range `json:"range"`
|
Range Range `json:"range"`
|
||||||
|
|
||||||
|
|
|
||||||
124
d2ir/compile.go
124
d2ir/compile.go
|
|
@ -5,14 +5,23 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/d2ast"
|
"oss.terrastruct.com/d2/d2ast"
|
||||||
"oss.terrastruct.com/d2/d2format"
|
"oss.terrastruct.com/d2/d2format"
|
||||||
"oss.terrastruct.com/d2/d2parser"
|
"oss.terrastruct.com/d2/d2parser"
|
||||||
"oss.terrastruct.com/d2/d2themes"
|
"oss.terrastruct.com/d2/d2themes"
|
||||||
"oss.terrastruct.com/d2/d2themes/d2themescatalog"
|
"oss.terrastruct.com/d2/d2themes/d2themescatalog"
|
||||||
"oss.terrastruct.com/util-go/go2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type globContext struct {
|
||||||
|
refctx *RefContext
|
||||||
|
// Set of BoardIDA that this glob has already applied to.
|
||||||
|
appliedFields map[string]struct{}
|
||||||
|
// Set of Edge IDs that this glob has already applied to.
|
||||||
|
appliedEdges map[string]struct{}
|
||||||
|
}
|
||||||
|
|
||||||
type compiler struct {
|
type compiler struct {
|
||||||
err *d2parser.ParseError
|
err *d2parser.ParseError
|
||||||
|
|
||||||
|
|
@ -23,7 +32,12 @@ type compiler struct {
|
||||||
importCache map[string]*Map
|
importCache map[string]*Map
|
||||||
utf16Pos bool
|
utf16Pos bool
|
||||||
|
|
||||||
globStack []bool
|
// Stack of globs that must be recomputed at each new object in and below the current scope.
|
||||||
|
globContextStack [][]*globContext
|
||||||
|
// Used to prevent field globs causing infinite loops.
|
||||||
|
globRefContextStack []*RefContext
|
||||||
|
// Used to check whether ampersands are allowed in the current map.
|
||||||
|
mapRefContextStack []*RefContext
|
||||||
}
|
}
|
||||||
|
|
||||||
type CompileOptions struct {
|
type CompileOptions struct {
|
||||||
|
|
@ -346,6 +360,52 @@ func (c *compiler) overlay(base *Map, f *Field) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *compiler) compileMap(dst *Map, ast, scopeAST *d2ast.Map) {
|
func (c *compiler) compileMap(dst *Map, ast, scopeAST *d2ast.Map) {
|
||||||
|
var globs []*globContext
|
||||||
|
if len(c.globContextStack) > 0 {
|
||||||
|
previousGlobs := c.globContextStack[len(c.globContextStack)-1]
|
||||||
|
if NodeBoardKind(dst) == BoardLayer {
|
||||||
|
for _, g := range previousGlobs {
|
||||||
|
if g.refctx.Key.HasTripleGlob() {
|
||||||
|
// Same as below but reset applied too.
|
||||||
|
g2 := *g
|
||||||
|
g2.refctx = g.refctx.Copy()
|
||||||
|
g2.appliedFields = make(map[string]struct{})
|
||||||
|
g2.appliedEdges = make(map[string]struct{})
|
||||||
|
prefix := d2ast.MakeKeyPath(RelIDA(g2.refctx.ScopeMap, dst))
|
||||||
|
g2.refctx.Key = g2.refctx.Key.Copy()
|
||||||
|
if g2.refctx.Key.Key != nil {
|
||||||
|
prefix.Path = append(prefix.Path, g2.refctx.Key.Key.Path...)
|
||||||
|
}
|
||||||
|
if len(prefix.Path) > 0 {
|
||||||
|
g2.refctx.Key.Key = prefix
|
||||||
|
}
|
||||||
|
globs = append(globs, &g2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if NodeBoardKind(dst) != "" {
|
||||||
|
// Make all globs relative to the scenario or step.
|
||||||
|
for _, g := range previousGlobs {
|
||||||
|
g2 := *g
|
||||||
|
g2.refctx = g.refctx.Copy()
|
||||||
|
prefix := d2ast.MakeKeyPath(RelIDA(g2.refctx.ScopeMap, dst))
|
||||||
|
g2.refctx.Key = g2.refctx.Key.Copy()
|
||||||
|
if g2.refctx.Key.Key != nil {
|
||||||
|
prefix.Path = append(prefix.Path, g2.refctx.Key.Key.Path...)
|
||||||
|
}
|
||||||
|
if len(prefix.Path) > 0 {
|
||||||
|
g2.refctx.Key.Key = prefix
|
||||||
|
}
|
||||||
|
globs = append(globs, &g2)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
globs = append(globs, previousGlobs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.globContextStack = append(c.globContextStack, globs)
|
||||||
|
defer func() {
|
||||||
|
c.globContextStack = c.globContextStack[:len(c.globContextStack)-1]
|
||||||
|
}()
|
||||||
|
|
||||||
for _, n := range ast.Nodes {
|
for _, n := range ast.Nodes {
|
||||||
switch {
|
switch {
|
||||||
case n.MapKey != nil:
|
case n.MapKey != nil:
|
||||||
|
|
@ -403,7 +463,47 @@ func (c *compiler) compileMap(dst *Map, ast, scopeAST *d2ast.Map) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *compiler) globContexts() []*globContext {
|
||||||
|
return c.globContextStack[len(c.globContextStack)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *compiler) getGlobContext(refctx *RefContext) *globContext {
|
||||||
|
for _, gctx := range c.globContexts() {
|
||||||
|
if gctx.refctx.Equal(refctx) {
|
||||||
|
return gctx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *compiler) ensureGlobContext(refctx *RefContext) *globContext {
|
||||||
|
gctx := c.getGlobContext(refctx)
|
||||||
|
if gctx != nil {
|
||||||
|
return gctx
|
||||||
|
}
|
||||||
|
gctx = &globContext{
|
||||||
|
refctx: refctx,
|
||||||
|
appliedFields: make(map[string]struct{}),
|
||||||
|
appliedEdges: make(map[string]struct{}),
|
||||||
|
}
|
||||||
|
c.globContextStack[len(c.globContextStack)-1] = append(c.globContexts(), gctx)
|
||||||
|
return gctx
|
||||||
|
}
|
||||||
|
|
||||||
func (c *compiler) compileKey(refctx *RefContext) {
|
func (c *compiler) compileKey(refctx *RefContext) {
|
||||||
|
if refctx.Key.HasGlob() {
|
||||||
|
for _, refctx2 := range c.globRefContextStack {
|
||||||
|
if refctx.Equal(refctx2) {
|
||||||
|
// Break the infinite loop.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.globRefContextStack = append(c.globRefContextStack, refctx)
|
||||||
|
defer func() {
|
||||||
|
c.globRefContextStack = c.globRefContextStack[:len(c.globRefContextStack)-1]
|
||||||
|
}()
|
||||||
|
c.ensureGlobContext(refctx)
|
||||||
|
}
|
||||||
if len(refctx.Key.Edges) == 0 {
|
if len(refctx.Key.Edges) == 0 {
|
||||||
c.compileField(refctx.ScopeMap, refctx.Key.Key, refctx)
|
c.compileField(refctx.ScopeMap, refctx.Key.Key, refctx)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -416,7 +516,7 @@ func (c *compiler) compileField(dst *Map, kp *d2ast.KeyPath, refctx *RefContext)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fa, err := dst.EnsureField(kp, refctx, true)
|
fa, err := dst.EnsureField(kp, refctx, true, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
|
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
|
||||||
return
|
return
|
||||||
|
|
@ -431,7 +531,7 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool {
|
||||||
if !refctx.Key.Ampersand {
|
if !refctx.Key.Ampersand {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if len(c.globStack) == 0 || !c.globStack[len(c.globStack)-1] {
|
if len(c.mapRefContextStack) == 0 || !c.mapRefContextStack[len(c.mapRefContextStack)-1].Key.SupportsGlobFilters() {
|
||||||
c.errorf(refctx.Key, "glob filters cannot be used outside globs")
|
c.errorf(refctx.Key, "glob filters cannot be used outside globs")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -439,7 +539,7 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fa, err := refctx.ScopeMap.EnsureField(refctx.Key.Key, refctx, false)
|
fa, err := refctx.ScopeMap.EnsureField(refctx.Key.Key, refctx, false, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
|
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
|
||||||
return false
|
return false
|
||||||
|
|
@ -532,9 +632,9 @@ func (c *compiler) _compileField(f *Field, refctx *RefContext) {
|
||||||
// If new board type, use that as the new scope AST, otherwise, carry on
|
// If new board type, use that as the new scope AST, otherwise, carry on
|
||||||
scopeAST = refctx.ScopeAST
|
scopeAST = refctx.ScopeAST
|
||||||
}
|
}
|
||||||
c.globStack = append(c.globStack, refctx.Key.HasQueryGlob())
|
c.mapRefContextStack = append(c.mapRefContextStack, refctx)
|
||||||
c.compileMap(f.Map(), refctx.Key.Value.Map, scopeAST)
|
c.compileMap(f.Map(), refctx.Key.Value.Map, scopeAST)
|
||||||
c.globStack = c.globStack[:len(c.globStack)-1]
|
c.mapRefContextStack = c.mapRefContextStack[:len(c.mapRefContextStack)-1]
|
||||||
switch NodeBoardKind(f) {
|
switch NodeBoardKind(f) {
|
||||||
case BoardScenario, BoardStep:
|
case BoardScenario, BoardStep:
|
||||||
c.overlayClasses(f.Map())
|
c.overlayClasses(f.Map())
|
||||||
|
|
@ -692,7 +792,7 @@ func (c *compiler) compileEdges(refctx *RefContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fa, err := refctx.ScopeMap.EnsureField(refctx.Key.Key, refctx, true)
|
fa, err := refctx.ScopeMap.EnsureField(refctx.Key.Key, refctx, true, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
|
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
|
||||||
return
|
return
|
||||||
|
|
@ -728,7 +828,9 @@ func (c *compiler) _compileEdges(refctx *RefContext) {
|
||||||
if eid.Index != nil || eid.Glob {
|
if eid.Index != nil || eid.Glob {
|
||||||
ea = refctx.ScopeMap.GetEdges(eid, refctx)
|
ea = refctx.ScopeMap.GetEdges(eid, refctx)
|
||||||
if len(ea) == 0 {
|
if len(ea) == 0 {
|
||||||
|
if !eid.Glob {
|
||||||
c.errorf(refctx.Edge, "indexed edge does not exist")
|
c.errorf(refctx.Edge, "indexed edge does not exist")
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, e := range ea {
|
for _, e := range ea {
|
||||||
|
|
@ -740,7 +842,7 @@ func (c *compiler) _compileEdges(refctx *RefContext) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
ea, err = refctx.ScopeMap.CreateEdge(eid, refctx)
|
ea, err = refctx.ScopeMap.CreateEdge(eid, refctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
|
c.err.Errors = append(c.err.Errors, err.(d2ast.Error))
|
||||||
continue
|
continue
|
||||||
|
|
@ -771,9 +873,9 @@ func (c *compiler) _compileEdges(refctx *RefContext) {
|
||||||
parent: e,
|
parent: e,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.globStack = append(c.globStack, refctx.Key.HasQueryGlob())
|
c.mapRefContextStack = append(c.mapRefContextStack, refctx)
|
||||||
c.compileMap(e.Map_, refctx.Key.Value.Map, refctx.ScopeAST)
|
c.compileMap(e.Map_, refctx.Key.Value.Map, refctx.ScopeAST)
|
||||||
c.globStack = c.globStack[:len(c.globStack)-1]
|
c.mapRefContextStack = c.mapRefContextStack[:len(c.mapRefContextStack)-1]
|
||||||
} else if refctx.Key.Value.ScalarBox().Unbox() != nil {
|
} else if refctx.Key.Value.ScalarBox().Unbox() != nil {
|
||||||
e.Primary_ = &Scalar{
|
e.Primary_ = &Scalar{
|
||||||
parent: e,
|
parent: e,
|
||||||
|
|
|
||||||
124
d2ir/d2ir.go
124
d2ir/d2ir.go
|
|
@ -245,7 +245,11 @@ func NodeBoardKind(n Node) BoardKind {
|
||||||
}
|
}
|
||||||
f = ParentField(n)
|
f = ParentField(n)
|
||||||
case *Map:
|
case *Map:
|
||||||
f = ParentField(n)
|
var ok bool
|
||||||
|
f, ok = n.parent.(*Field)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
if f.Root() {
|
if f.Root() {
|
||||||
return BoardLayer
|
return BoardLayer
|
||||||
}
|
}
|
||||||
|
|
@ -569,6 +573,10 @@ func (rc *RefContext) EdgeIndex() int {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rc *RefContext) Equal(rc2 *RefContext) bool {
|
||||||
|
return rc.Edge == rc2.Edge && rc.Key.Equals(rc2.Key) && rc.Scope == rc2.Scope && rc.ScopeMap == rc2.ScopeMap && rc.ScopeAST == rc2.ScopeAST
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Map) FieldCountRecursive() int {
|
func (m *Map) FieldCountRecursive() int {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return 0
|
return 0
|
||||||
|
|
@ -667,7 +675,7 @@ func (m *Map) getField(ida []string) *Field {
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnsureField is a bit of a misnomer. It's more of a Query/Ensure combination function at this point.
|
// EnsureField is a bit of a misnomer. It's more of a Query/Ensure combination function at this point.
|
||||||
func (m *Map) EnsureField(kp *d2ast.KeyPath, refctx *RefContext, create bool) ([]*Field, error) {
|
func (m *Map) EnsureField(kp *d2ast.KeyPath, refctx *RefContext, create bool, c *compiler) ([]*Field, error) {
|
||||||
i := 0
|
i := 0
|
||||||
for kp.Path[i].Unbox().ScalarString() == "_" {
|
for kp.Path[i].Unbox().ScalarString() == "_" {
|
||||||
m = ParentMap(m)
|
m = ParentMap(m)
|
||||||
|
|
@ -680,18 +688,47 @@ func (m *Map) EnsureField(kp *d2ast.KeyPath, refctx *RefContext, create bool) ([
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
var fa []*Field
|
var gctx *globContext
|
||||||
err := m.ensureField(i, kp, refctx, create, &fa)
|
if refctx != nil && refctx.Key.HasGlob() && c != nil {
|
||||||
return fa, err
|
gctx = c.getGlobContext(refctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
var fa []*Field
|
||||||
|
err := m.ensureField(i, kp, refctx, create, gctx, c, &fa)
|
||||||
|
if err != nil {
|
||||||
|
return fa, err
|
||||||
|
}
|
||||||
|
if len(fa) > 0 && create && c != nil {
|
||||||
|
for _, gctx2 := range c.globContexts() {
|
||||||
|
c.compileKey(gctx2.refctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fa, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Map) ensureField(i int, kp *d2ast.KeyPath, refctx *RefContext, create bool, gctx *globContext, c *compiler, fa *[]*Field) error {
|
||||||
|
faAppend := func(fa2 ...*Field) {
|
||||||
|
for _, f := range fa2 {
|
||||||
|
if gctx != nil {
|
||||||
|
// Always match all commons, sources and destinations for edge globs.
|
||||||
|
if len(refctx.Key.Edges) == 0 || kp == refctx.Key.EdgeKey {
|
||||||
|
ks := d2format.Format(d2ast.MakeKeyPath(BoardIDA(f)))
|
||||||
|
if _, ok := gctx.appliedFields[ks]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
gctx.appliedFields[ks] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*fa = append(*fa, f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Map) ensureField(i int, kp *d2ast.KeyPath, refctx *RefContext, create bool, fa *[]*Field) error {
|
|
||||||
us, ok := kp.Path[i].Unbox().(*d2ast.UnquotedString)
|
us, ok := kp.Path[i].Unbox().(*d2ast.UnquotedString)
|
||||||
if ok && us.Pattern != nil {
|
if ok && us.Pattern != nil {
|
||||||
fa2, ok := m.doubleGlob(us.Pattern)
|
fa2, ok := m.multiGlob(us.Pattern)
|
||||||
if ok {
|
if ok {
|
||||||
if i == len(kp.Path)-1 {
|
if i == len(kp.Path)-1 {
|
||||||
*fa = append(*fa, fa2...)
|
faAppend(fa2...)
|
||||||
} else {
|
} else {
|
||||||
for _, f := range fa2 {
|
for _, f := range fa2 {
|
||||||
if f.Map() == nil {
|
if f.Map() == nil {
|
||||||
|
|
@ -699,7 +736,7 @@ func (m *Map) ensureField(i int, kp *d2ast.KeyPath, refctx *RefContext, create b
|
||||||
parent: f,
|
parent: f,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := f.Map().ensureField(i+1, kp, refctx, create, fa)
|
err := f.Map().ensureField(i+1, kp, refctx, create, gctx, c, fa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -710,14 +747,14 @@ func (m *Map) ensureField(i int, kp *d2ast.KeyPath, refctx *RefContext, create b
|
||||||
for _, f := range m.Fields {
|
for _, f := range m.Fields {
|
||||||
if matchPattern(f.Name, us.Pattern) {
|
if matchPattern(f.Name, us.Pattern) {
|
||||||
if i == len(kp.Path)-1 {
|
if i == len(kp.Path)-1 {
|
||||||
*fa = append(*fa, f)
|
faAppend(f)
|
||||||
} else {
|
} else {
|
||||||
if f.Map() == nil {
|
if f.Map() == nil {
|
||||||
f.Composite = &Map{
|
f.Composite = &Map{
|
||||||
parent: f,
|
parent: f,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := f.Map().ensureField(i+1, kp, refctx, create, fa)
|
err := f.Map().ensureField(i+1, kp, refctx, create, gctx, c, fa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -763,7 +800,7 @@ func (m *Map) ensureField(i int, kp *d2ast.KeyPath, refctx *RefContext, create b
|
||||||
}
|
}
|
||||||
|
|
||||||
if i+1 == len(kp.Path) {
|
if i+1 == len(kp.Path) {
|
||||||
*fa = append(*fa, f)
|
faAppend(f)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if _, ok := f.Composite.(*Array); ok {
|
if _, ok := f.Composite.(*Array); ok {
|
||||||
|
|
@ -774,7 +811,7 @@ func (m *Map) ensureField(i int, kp *d2ast.KeyPath, refctx *RefContext, create b
|
||||||
parent: f,
|
parent: f,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return f.Map().ensureField(i+1, kp, refctx, create, fa)
|
return f.Map().ensureField(i+1, kp, refctx, create, gctx, c, fa)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !create {
|
if !create {
|
||||||
|
|
@ -797,10 +834,12 @@ func (m *Map) ensureField(i int, kp *d2ast.KeyPath, refctx *RefContext, create b
|
||||||
*fa = append(*fa, f)
|
*fa = append(*fa, f)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if f.Composite == nil {
|
||||||
f.Composite = &Map{
|
f.Composite = &Map{
|
||||||
parent: f,
|
parent: f,
|
||||||
}
|
}
|
||||||
return f.Map().ensureField(i+1, kp, refctx, create, fa)
|
}
|
||||||
|
return f.Map().ensureField(i+1, kp, refctx, create, gctx, c, fa)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Map) DeleteEdge(eid *EdgeID) *Edge {
|
func (m *Map) DeleteEdge(eid *EdgeID) *Edge {
|
||||||
|
|
@ -914,7 +953,7 @@ func (m *Map) getEdges(eid *EdgeID, refctx *RefContext, ea *[]*Edge) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fa, err := m.EnsureField(commonKP, nil, false)
|
fa, err := m.EnsureField(commonKP, nil, false, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -935,11 +974,11 @@ func (m *Map) getEdges(eid *EdgeID, refctx *RefContext, ea *[]*Edge) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
srcFA, err := refctx.ScopeMap.EnsureField(refctx.Edge.Src, nil, false)
|
srcFA, err := refctx.ScopeMap.EnsureField(refctx.Edge.Src, nil, false, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dstFA, err := refctx.ScopeMap.EnsureField(refctx.Edge.Dst, nil, false)
|
dstFA, err := refctx.ScopeMap.EnsureField(refctx.Edge.Dst, nil, false, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -957,12 +996,25 @@ func (m *Map) getEdges(eid *EdgeID, refctx *RefContext, ea *[]*Edge) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Map) CreateEdge(eid *EdgeID, refctx *RefContext) ([]*Edge, error) {
|
func (m *Map) CreateEdge(eid *EdgeID, refctx *RefContext, c *compiler) ([]*Edge, error) {
|
||||||
var ea []*Edge
|
var ea []*Edge
|
||||||
return ea, m.createEdge(eid, refctx, &ea)
|
var gctx *globContext
|
||||||
|
if refctx != nil && refctx.Key.HasGlob() && c != nil {
|
||||||
|
gctx = c.getGlobContext(refctx)
|
||||||
|
}
|
||||||
|
err := m.createEdge(eid, refctx, gctx, c, &ea)
|
||||||
|
if err != nil {
|
||||||
|
return ea, err
|
||||||
|
}
|
||||||
|
if len(ea) > 0 && c != nil {
|
||||||
|
for _, gctx2 := range c.globContexts() {
|
||||||
|
c.compileKey(gctx2.refctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ea, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Map) createEdge(eid *EdgeID, refctx *RefContext, ea *[]*Edge) error {
|
func (m *Map) createEdge(eid *EdgeID, refctx *RefContext, gctx *globContext, c *compiler, ea *[]*Edge) error {
|
||||||
if ParentEdge(m) != nil {
|
if ParentEdge(m) != nil {
|
||||||
return d2parser.Errorf(refctx.Edge, "cannot create edge inside edge")
|
return d2parser.Errorf(refctx.Edge, "cannot create edge inside edge")
|
||||||
}
|
}
|
||||||
|
|
@ -983,7 +1035,7 @@ func (m *Map) createEdge(eid *EdgeID, refctx *RefContext, ea *[]*Edge) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fa, err := m.EnsureField(commonKP, nil, true)
|
fa, err := m.EnsureField(commonKP, nil, true, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -996,7 +1048,7 @@ func (m *Map) createEdge(eid *EdgeID, refctx *RefContext, ea *[]*Edge) error {
|
||||||
parent: f,
|
parent: f,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = f.Map().createEdge(eid, refctx, ea)
|
err = f.Map().createEdge(eid, refctx, gctx, c, ea)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -1022,11 +1074,11 @@ func (m *Map) createEdge(eid *EdgeID, refctx *RefContext, ea *[]*Edge) error {
|
||||||
return d2parser.Errorf(refctx.Edge.Dst.Path[ij].Unbox(), "edge with board keyword alone doesn't make sense")
|
return d2parser.Errorf(refctx.Edge.Dst.Path[ij].Unbox(), "edge with board keyword alone doesn't make sense")
|
||||||
}
|
}
|
||||||
|
|
||||||
srcFA, err := refctx.ScopeMap.EnsureField(refctx.Edge.Src, refctx, true)
|
srcFA, err := refctx.ScopeMap.EnsureField(refctx.Edge.Src, refctx, true, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dstFA, err := refctx.ScopeMap.EnsureField(refctx.Edge.Dst, refctx, true)
|
dstFA, err := refctx.ScopeMap.EnsureField(refctx.Edge.Dst, refctx, true, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -1038,21 +1090,21 @@ func (m *Map) createEdge(eid *EdgeID, refctx *RefContext, ea *[]*Edge) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if refctx.Edge.Src.HasDoubleGlob() {
|
if refctx.Edge.Src.HasMultiGlob() {
|
||||||
// If src has a double glob we only select leafs, those without children.
|
// If src has a double glob we only select leafs, those without children.
|
||||||
if src.Map().IsContainer() {
|
if src.Map().IsContainer() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if ParentBoard(src) != ParentBoard(dst) {
|
if NodeBoardKind(src) != "" || ParentBoard(src) != ParentBoard(dst) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if refctx.Edge.Dst.HasDoubleGlob() {
|
if refctx.Edge.Dst.HasMultiGlob() {
|
||||||
// If dst has a double glob we only select leafs, those without children.
|
// If dst has a double glob we only select leafs, those without children.
|
||||||
if dst.Map().IsContainer() {
|
if dst.Map().IsContainer() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if ParentBoard(src) != ParentBoard(dst) {
|
if NodeBoardKind(dst) != "" || ParentBoard(src) != ParentBoard(dst) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1060,17 +1112,20 @@ func (m *Map) createEdge(eid *EdgeID, refctx *RefContext, ea *[]*Edge) error {
|
||||||
eid2 := eid.Copy()
|
eid2 := eid.Copy()
|
||||||
eid2.SrcPath = RelIDA(m, src)
|
eid2.SrcPath = RelIDA(m, src)
|
||||||
eid2.DstPath = RelIDA(m, dst)
|
eid2.DstPath = RelIDA(m, dst)
|
||||||
e, err := m.createEdge2(eid2, refctx, src, dst)
|
|
||||||
|
e, err := m.createEdge2(eid2, refctx, gctx, src, dst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if e != nil {
|
||||||
*ea = append(*ea, e)
|
*ea = append(*ea, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Map) createEdge2(eid *EdgeID, refctx *RefContext, src, dst *Field) (*Edge, error) {
|
func (m *Map) createEdge2(eid *EdgeID, refctx *RefContext, gctx *globContext, src, dst *Field) (*Edge, error) {
|
||||||
if NodeBoardKind(src) != "" {
|
if NodeBoardKind(src) != "" {
|
||||||
return nil, d2parser.Errorf(refctx.Edge.Src, "cannot create edges between boards")
|
return nil, d2parser.Errorf(refctx.Edge.Src, "cannot create edges between boards")
|
||||||
}
|
}
|
||||||
|
|
@ -1094,6 +1149,15 @@ func (m *Map) createEdge2(eid *EdgeID, refctx *RefContext, src, dst *Field) (*Ed
|
||||||
Context: refctx,
|
Context: refctx,
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if gctx != nil {
|
||||||
|
ks := e.String()
|
||||||
|
if _, ok := gctx.appliedEdges[ks]; ok {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
gctx.appliedEdges[ks] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
m.Edges = append(m.Edges, e)
|
m.Edges = append(m.Edges, e)
|
||||||
|
|
||||||
return e, nil
|
return e, nil
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,41 @@ package d2ir
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"oss.terrastruct.com/d2/d2ast"
|
||||||
"oss.terrastruct.com/d2/d2graph"
|
"oss.terrastruct.com/d2/d2graph"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *Map) doubleGlob(pattern []string) ([]*Field, bool) {
|
func (m *Map) multiGlob(pattern []string) ([]*Field, bool) {
|
||||||
if !(len(pattern) == 3 && pattern[0] == "*" && pattern[1] == "" && pattern[2] == "*") {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
var fa []*Field
|
var fa []*Field
|
||||||
|
if d2ast.IsDoubleGlob(pattern) {
|
||||||
m._doubleGlob(&fa)
|
m._doubleGlob(&fa)
|
||||||
return fa, true
|
return fa, true
|
||||||
}
|
}
|
||||||
|
if d2ast.IsTripleGlob(pattern) {
|
||||||
|
m._tripleGlob(&fa)
|
||||||
|
return fa, true
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Map) _doubleGlob(fa *[]*Field) {
|
func (m *Map) _doubleGlob(fa *[]*Field) {
|
||||||
|
for _, f := range m.Fields {
|
||||||
|
if _, ok := d2graph.ReservedKeywords[f.Name]; ok {
|
||||||
|
if f.Name == "layers" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := d2graph.BoardKeywords[f.Name]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*fa = append(*fa, f)
|
||||||
|
if f.Map() != nil {
|
||||||
|
f.Map()._doubleGlob(fa)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Map) _tripleGlob(fa *[]*Field) {
|
||||||
for _, f := range m.Fields {
|
for _, f := range m.Fields {
|
||||||
if _, ok := d2graph.ReservedKeywords[f.Name]; ok {
|
if _, ok := d2graph.ReservedKeywords[f.Name]; ok {
|
||||||
if _, ok := d2graph.BoardKeywords[f.Name]; !ok {
|
if _, ok := d2graph.BoardKeywords[f.Name]; !ok {
|
||||||
|
|
@ -24,7 +46,7 @@ func (m *Map) _doubleGlob(fa *[]*Field) {
|
||||||
}
|
}
|
||||||
*fa = append(*fa, f)
|
*fa = append(*fa, f)
|
||||||
if f.Map() != nil {
|
if f.Map() != nil {
|
||||||
f.Map()._doubleGlob(fa)
|
f.Map()._tripleGlob(fa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -285,6 +285,31 @@ d
|
||||||
assertQuery(t, m, 0, 0, nil, "(* -> *)[*]")
|
assertQuery(t, m, 0, 0, nil, "(* -> *)[*]")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "single-glob/defaults",
|
||||||
|
run: func(t testing.TB) {
|
||||||
|
m, err := compile(t, `wrapper.*: {
|
||||||
|
shape: page
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapper.a
|
||||||
|
wrapper.b
|
||||||
|
wrapper.c
|
||||||
|
wrapper.d
|
||||||
|
|
||||||
|
scenarios.x: { wrapper.p }
|
||||||
|
layers.x: { wrapper.p }
|
||||||
|
`)
|
||||||
|
assert.Success(t, err)
|
||||||
|
assertQuery(t, m, 26, 0, nil, "")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "wrapper.a.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "wrapper.b.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "wrapper.c.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "wrapper.d.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "scenarios.x.wrapper.p.shape")
|
||||||
|
assertQuery(t, m, 0, 0, nil, "layers.x.wrapper.p")
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "double-glob/edge/1",
|
name: "double-glob/edge/1",
|
||||||
run: func(t testing.TB) {
|
run: func(t testing.TB) {
|
||||||
|
|
@ -314,21 +339,81 @@ task.** -> fast
|
||||||
assertQuery(t, m, 3, 1, nil, "")
|
assertQuery(t, m, 3, 1, nil, "")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
|
||||||
|
|
||||||
runa(t, tca)
|
|
||||||
|
|
||||||
t.Run("errors", func(t *testing.T) {
|
|
||||||
tca := []testCase{
|
|
||||||
{
|
{
|
||||||
name: "glob-edge-glob-index",
|
name: "double-glob/defaults",
|
||||||
run: func(t testing.TB) {
|
run: func(t testing.TB) {
|
||||||
_, err := compile(t, `(* -> b)[*].style.fill: red
|
m, err := compile(t, `**: {
|
||||||
|
shape: page
|
||||||
|
}
|
||||||
|
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c
|
||||||
|
d
|
||||||
|
|
||||||
|
scenarios.x: { p }
|
||||||
|
layers.x: { p }
|
||||||
`)
|
`)
|
||||||
assert.ErrorString(t, err, `TestCompile/patterns/errors/glob-edge-glob-index.d2:1:2: indexed edge does not exist`)
|
assert.Success(t, err)
|
||||||
|
assertQuery(t, m, 25, 0, nil, "")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "a.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "b.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "c.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "d.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "scenarios.x.p.shape")
|
||||||
|
assertQuery(t, m, 0, 0, nil, "layers.x.p")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "triple-glob/defaults",
|
||||||
|
run: func(t testing.TB) {
|
||||||
|
m, err := compile(t, `***: {
|
||||||
|
shape: page
|
||||||
|
}
|
||||||
|
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c
|
||||||
|
d
|
||||||
|
|
||||||
|
scenarios.x: { p }
|
||||||
|
layers.x: { p }
|
||||||
|
`)
|
||||||
|
assert.Success(t, err)
|
||||||
|
assertQuery(t, m, 27, 0, nil, "")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "a.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "b.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "c.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "d.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "scenarios.x.p.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "page", "layers.x.p.shape")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "triple-glob/edge-defaults",
|
||||||
|
run: func(t testing.TB) {
|
||||||
|
m, err := compile(t, `(*** -> ***)[*]: {
|
||||||
|
target-arrowhead.shape: diamond
|
||||||
|
}
|
||||||
|
|
||||||
|
a -> b
|
||||||
|
c -> d
|
||||||
|
|
||||||
|
scenarios.x: { p -> q }
|
||||||
|
layers.x: { j -> f }
|
||||||
|
`)
|
||||||
|
assert.Success(t, err)
|
||||||
|
assertQuery(t, m, 28, 6, nil, "")
|
||||||
|
assertQuery(t, m, 0, 0, "diamond", "(a -> b)[0].target-arrowhead.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "diamond", "(c -> d)[0].target-arrowhead.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "diamond", "scenarios.x.(a -> b)[0].target-arrowhead.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "diamond", "scenarios.x.(c -> d)[0].target-arrowhead.shape")
|
||||||
|
assertQuery(t, m, 0, 0, "diamond", "scenarios.x.(p -> q)[0].target-arrowhead.shape")
|
||||||
|
assertQuery(t, m, 4, 1, nil, "layers.x")
|
||||||
|
assertQuery(t, m, 0, 0, "diamond", "layers.x.(j -> f)[0].target-arrowhead.shape")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
runa(t, tca)
|
runa(t, tca)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2909
testdata/d2ir/TestCompile/patterns/double-glob/defaults.exp.json
generated
vendored
Normal file
2909
testdata/d2ir/TestCompile/patterns/double-glob/defaults.exp.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
665
testdata/d2ir/TestCompile/patterns/errors/glob-edge-glob-index.exp.json
generated
vendored
665
testdata/d2ir/TestCompile/patterns/errors/glob-edge-glob-index.exp.json
generated
vendored
|
|
@ -1,667 +1,4 @@
|
||||||
{
|
{
|
||||||
"fields": [
|
"fields": null,
|
||||||
{
|
|
||||||
"name": "b",
|
|
||||||
"references": [
|
|
||||||
{
|
|
||||||
"string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "b",
|
|
||||||
"raw_string": "b"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"key_path": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "b",
|
|
||||||
"raw_string": "b"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"context": {
|
|
||||||
"edge": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:7:7",
|
|
||||||
"src": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "*",
|
|
||||||
"raw_string": "*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"pattern": [
|
|
||||||
"*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"src_arrow": "",
|
|
||||||
"dst": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "b",
|
|
||||||
"raw_string": "b"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"dst_arrow": ">"
|
|
||||||
},
|
|
||||||
"key": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:0:0-0:24:24",
|
|
||||||
"edges": [
|
|
||||||
{
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:7:7",
|
|
||||||
"src": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "*",
|
|
||||||
"raw_string": "*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"pattern": [
|
|
||||||
"*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"src_arrow": "",
|
|
||||||
"dst": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "b",
|
|
||||||
"raw_string": "b"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"dst_arrow": ">"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"edge_key": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:9:9-0:19:19",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:9:9-0:14:14",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "style",
|
|
||||||
"raw_string": "style"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:15:15-0:19:19",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "fill",
|
|
||||||
"raw_string": "fill"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"primary": {},
|
|
||||||
"value": {
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:21:21-0:24:24",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "red",
|
|
||||||
"raw_string": "red"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"edges": [
|
|
||||||
{
|
|
||||||
"edge_id": {
|
|
||||||
"src_path": [
|
|
||||||
"b"
|
|
||||||
],
|
|
||||||
"src_arrow": false,
|
|
||||||
"dst_path": [
|
|
||||||
"b"
|
|
||||||
],
|
|
||||||
"dst_arrow": true,
|
|
||||||
"index": 0,
|
|
||||||
"glob": false
|
|
||||||
},
|
|
||||||
"map": {
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "style",
|
|
||||||
"composite": {
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "fill",
|
|
||||||
"primary": {
|
|
||||||
"value": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:21:21-0:24:24",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "red",
|
|
||||||
"raw_string": "red"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"references": [
|
|
||||||
{
|
|
||||||
"string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:15:15-0:19:19",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "fill",
|
|
||||||
"raw_string": "fill"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"key_path": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:9:9-0:19:19",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:9:9-0:14:14",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "style",
|
|
||||||
"raw_string": "style"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:15:15-0:19:19",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "fill",
|
|
||||||
"raw_string": "fill"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"context": {
|
|
||||||
"edge": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:7:7",
|
|
||||||
"src": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "*",
|
|
||||||
"raw_string": "*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"pattern": [
|
|
||||||
"*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"src_arrow": "",
|
|
||||||
"dst": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "b",
|
|
||||||
"raw_string": "b"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"dst_arrow": ">"
|
|
||||||
},
|
|
||||||
"key": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:0:0-0:24:24",
|
|
||||||
"edges": [
|
|
||||||
{
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:7:7",
|
|
||||||
"src": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "*",
|
|
||||||
"raw_string": "*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"pattern": [
|
|
||||||
"*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"src_arrow": "",
|
|
||||||
"dst": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "b",
|
|
||||||
"raw_string": "b"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"dst_arrow": ">"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"edge_key": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:9:9-0:19:19",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:9:9-0:14:14",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "style",
|
|
||||||
"raw_string": "style"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:15:15-0:19:19",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "fill",
|
|
||||||
"raw_string": "fill"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"primary": {},
|
|
||||||
"value": {
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:21:21-0:24:24",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "red",
|
|
||||||
"raw_string": "red"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"edges": null
|
"edges": null
|
||||||
},
|
|
||||||
"references": [
|
|
||||||
{
|
|
||||||
"string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:9:9-0:14:14",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "style",
|
|
||||||
"raw_string": "style"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"key_path": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:9:9-0:19:19",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:9:9-0:14:14",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "style",
|
|
||||||
"raw_string": "style"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:15:15-0:19:19",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "fill",
|
|
||||||
"raw_string": "fill"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"context": {
|
|
||||||
"edge": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:7:7",
|
|
||||||
"src": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "*",
|
|
||||||
"raw_string": "*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"pattern": [
|
|
||||||
"*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"src_arrow": "",
|
|
||||||
"dst": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "b",
|
|
||||||
"raw_string": "b"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"dst_arrow": ">"
|
|
||||||
},
|
|
||||||
"key": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:0:0-0:24:24",
|
|
||||||
"edges": [
|
|
||||||
{
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:7:7",
|
|
||||||
"src": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "*",
|
|
||||||
"raw_string": "*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"pattern": [
|
|
||||||
"*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"src_arrow": "",
|
|
||||||
"dst": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "b",
|
|
||||||
"raw_string": "b"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"dst_arrow": ">"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"edge_key": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:9:9-0:19:19",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:9:9-0:14:14",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "style",
|
|
||||||
"raw_string": "style"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:15:15-0:19:19",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "fill",
|
|
||||||
"raw_string": "fill"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"primary": {},
|
|
||||||
"value": {
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:21:21-0:24:24",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "red",
|
|
||||||
"raw_string": "red"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"edges": null
|
|
||||||
},
|
|
||||||
"references": [
|
|
||||||
{
|
|
||||||
"context": {
|
|
||||||
"edge": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:7:7",
|
|
||||||
"src": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "*",
|
|
||||||
"raw_string": "*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"pattern": [
|
|
||||||
"*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"src_arrow": "",
|
|
||||||
"dst": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "b",
|
|
||||||
"raw_string": "b"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"dst_arrow": ">"
|
|
||||||
},
|
|
||||||
"key": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:0:0-0:24:24",
|
|
||||||
"edges": [
|
|
||||||
{
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:7:7",
|
|
||||||
"src": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:1:1-0:2:2",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "*",
|
|
||||||
"raw_string": "*"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"pattern": [
|
|
||||||
"*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"src_arrow": "",
|
|
||||||
"dst": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:6:6-0:7:7",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "b",
|
|
||||||
"raw_string": "b"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"dst_arrow": ">"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"edge_key": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:9:9-0:19:19",
|
|
||||||
"path": [
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:9:9-0:14:14",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "style",
|
|
||||||
"raw_string": "style"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:15:15-0:19:19",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "fill",
|
|
||||||
"raw_string": "fill"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"primary": {},
|
|
||||||
"value": {
|
|
||||||
"unquoted_string": {
|
|
||||||
"range": "TestCompile/patterns/errors/glob-edge-glob-index.d2,0:21:21-0:24:24",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"string": "red",
|
|
||||||
"raw_string": "red"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4781
testdata/d2ir/TestCompile/patterns/single-glob/defaults.exp.json
generated
vendored
Normal file
4781
testdata/d2ir/TestCompile/patterns/single-glob/defaults.exp.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
3370
testdata/d2ir/TestCompile/patterns/triple-glob/defaults.exp.json
generated
vendored
Normal file
3370
testdata/d2ir/TestCompile/patterns/triple-glob/defaults.exp.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
14050
testdata/d2ir/TestCompile/patterns/triple-glob/edge-defaults.exp.json
generated
vendored
Normal file
14050
testdata/d2ir/TestCompile/patterns/triple-glob/edge-defaults.exp.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue