Skip to content

Commit 950f7fb

Browse files
committed
internal/astinternal: add IncludePointers
This has been very useful for me when debugging ASTs to tally pointers in log messages with nodes in the final AST. Signed-off-by: Roger Peppe <[email protected]> Change-Id: Icdc564619069120aa425a16990c99c2faff2906f Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1205771 TryBot-Result: CUEcueckoo <[email protected]> Reviewed-by: Daniel Martí <[email protected]> Unity-Result: CUE porcuepine <[email protected]>
1 parent 6e34b9e commit 950f7fb

File tree

3 files changed

+111
-3
lines changed

3 files changed

+111
-3
lines changed

Diff for: internal/astinternal/debug.go

+21-3
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ type DebugConfig struct {
5656
// IncludeNodeRefs causes a Node reference in an identifier
5757
// to indicate which (if any) ast.Node it refers to.
5858
IncludeNodeRefs bool
59+
60+
// IncludePointers causes all nodes to be printed with their pointer
61+
// values; setting this also implies [DebugConfig.IncludeNodeRefs]
62+
// and references will be printed as pointers.
63+
IncludePointers bool
5964
}
6065

6166
type debugPrinter struct {
@@ -82,6 +87,7 @@ func (d *debugPrinter) value0(v reflect.Value, impliedType reflect.Type) {
8287
// Skip over interfaces and pointers, stopping early if nil.
8388
concreteType := v.Type()
8489
refName := ""
90+
ptrVal := uintptr(0)
8591
for {
8692
k := v.Kind()
8793
if k != reflect.Interface && k != reflect.Pointer {
@@ -95,6 +101,7 @@ func (d *debugPrinter) value0(v reflect.Value, impliedType reflect.Type) {
95101
}
96102
if k == reflect.Pointer {
97103
if n, ok := v.Interface().(ast.Node); ok {
104+
ptrVal = v.Pointer()
98105
if id, ok := d.nodeRefs[n]; ok {
99106
refName = refIDToName(id)
100107
}
@@ -143,7 +150,11 @@ func (d *debugPrinter) value0(v reflect.Value, impliedType reflect.Type) {
143150
if concreteType != impliedType {
144151
d.printf("%s", concreteType)
145152
}
146-
if refName != "" {
153+
if d.cfg.IncludePointers {
154+
if ptrVal != 0 {
155+
d.printf("@%#x", ptrVal)
156+
}
157+
} else if refName != "" {
147158
d.printf("@%s", refName)
148159
}
149160
d.printf("{")
@@ -192,11 +203,18 @@ func (d *debugPrinter) structFields(v reflect.Value) (anyElems bool) {
192203
}
193204
if f.Name == "Node" {
194205
nodeVal := v.Field(i)
195-
if !d.cfg.IncludeNodeRefs || nodeVal.IsNil() {
206+
if (!d.cfg.IncludeNodeRefs && !d.cfg.IncludePointers) || nodeVal.IsNil() {
196207
continue
197208
}
198209
d.newline()
199-
d.printf("Node: @%s (%v)", refIDToName(d.nodeRefs[nodeVal.Interface().(ast.Node)]), nodeVal.Elem().Type())
210+
if d.cfg.IncludePointers {
211+
if nodeVal.Kind() == reflect.Interface {
212+
nodeVal = nodeVal.Elem()
213+
}
214+
d.printf("Node: @%#v (%v)", nodeVal.Pointer(), nodeVal.Elem().Type())
215+
} else {
216+
d.printf("Node: @%s (%v)", refIDToName(d.nodeRefs[nodeVal.Interface().(ast.Node)]), nodeVal.Elem().Type())
217+
}
200218
continue
201219
}
202220
switch f.Name {

Diff for: internal/astinternal/debug_test.go

+11
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package astinternal_test
1717
import (
1818
"path"
1919
"reflect"
20+
"regexp"
2021
"strings"
2122
"testing"
2223

@@ -28,17 +29,21 @@ import (
2829
"github.com/go-quicktest/qt"
2930
)
3031

32+
var ptrPat = regexp.MustCompile(`0x[0-9a-z]+`)
33+
3134
func TestDebugPrint(t *testing.T) {
3235
test := cuetxtar.TxTarTest{
3336
Root: "testdata",
3437
Name: "debugprint",
3538
}
3639

3740
test.Run(t, func(t *cuetxtar.Test) {
41+
includePointers := t.HasTag("includePointers")
3842
for _, file := range t.Archive.Files {
3943
if strings.HasPrefix(file.Name, "out/") {
4044
continue
4145
}
46+
4247
f, err := parser.ParseFile(file.Name, file.Data, parser.ParseComments)
4348
qt.Assert(t, qt.IsNil(err))
4449

@@ -49,7 +54,13 @@ func TestDebugPrint(t *testing.T) {
4954
// the generated reference names should be deterministic.
5055
full := astinternal.AppendDebug(nil, f, astinternal.DebugConfig{
5156
IncludeNodeRefs: true,
57+
IncludePointers: includePointers,
5258
})
59+
if includePointers {
60+
// Pointer values change between runs. Replace with a constant
61+
// string so that we can test stable output.
62+
full = ptrPat.ReplaceAll(full, []byte("XXXX"))
63+
}
5364
t.Writer(file.Name).Write(full)
5465

5566
// A syntax tree which omits any empty values,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#includePointers
2+
-- file.cue --
3+
package p
4+
5+
a: b
6+
b: 3
7+
-- out/debugprint/file.cue --
8+
*ast.File@XXXX{
9+
Filename: "file.cue"
10+
Decls: []ast.Decl{
11+
*ast.Package@XXXX{
12+
PackagePos: token.Pos("file.cue:1:1", nospace)
13+
Name: *ast.Ident@XXXX{
14+
NamePos: token.Pos("file.cue:1:9", blank)
15+
Name: "p"
16+
}
17+
}
18+
*ast.Field@XXXX{
19+
Label: *ast.Ident@XXXX{
20+
NamePos: token.Pos("file.cue:3:1", section)
21+
Name: "a"
22+
}
23+
Optional: token.Pos("-")
24+
Constraint: token.Token("ILLEGAL")
25+
TokenPos: token.Pos("file.cue:3:2", nospace)
26+
Token: token.Token(":")
27+
Value: *ast.Ident@XXXX{
28+
NamePos: token.Pos("file.cue:3:4", blank)
29+
Name: "b"
30+
Node: @XXXX (ast.BasicLit)
31+
}
32+
Attrs: []*ast.Attribute{}
33+
}
34+
*ast.Field@XXXX{
35+
Label: *ast.Ident@XXXX{
36+
NamePos: token.Pos("file.cue:4:1", newline)
37+
Name: "b"
38+
}
39+
Optional: token.Pos("-")
40+
Constraint: token.Token("ILLEGAL")
41+
TokenPos: token.Pos("file.cue:4:2", nospace)
42+
Token: token.Token(":")
43+
Value: *ast.BasicLit@XXXX{
44+
ValuePos: token.Pos("file.cue:4:4", blank)
45+
Kind: token.Token("INT")
46+
Value: "3"
47+
}
48+
Attrs: []*ast.Attribute{}
49+
}
50+
}
51+
Imports: []*ast.ImportSpec{}
52+
}
53+
-- out/debugprint/file.cue/omitempty-strings --
54+
*ast.File{
55+
Filename: "file.cue"
56+
Decls: []ast.Decl{
57+
*ast.Package{
58+
Name: *ast.Ident{
59+
Name: "p"
60+
}
61+
}
62+
*ast.Field{
63+
Label: *ast.Ident{
64+
Name: "a"
65+
}
66+
Value: *ast.Ident{
67+
Name: "b"
68+
}
69+
}
70+
*ast.Field{
71+
Label: *ast.Ident{
72+
Name: "b"
73+
}
74+
Value: *ast.BasicLit{
75+
Value: "3"
76+
}
77+
}
78+
}
79+
}

0 commit comments

Comments
 (0)