Skip to content

Commit a08810b

Browse files
committed
Ast dump Comprehension structs properly
1 parent 69f12ff commit a08810b

File tree

2 files changed

+45
-34
lines changed

2 files changed

+45
-34
lines changed

ast/dump.go

+42-34
Original file line numberDiff line numberDiff line change
@@ -8,59 +8,67 @@ import (
88
"github.com/ncw/gpython/py"
99
)
1010

11-
// Dump an Ast node as a string
12-
func Dump(ast Ast) string {
13-
if ast == nil {
14-
return "<nil>"
15-
}
16-
name := ast.Type().Name
17-
if name == "ExprStmt" {
18-
name = "Expr"
11+
func dumpItem(v interface{}) string {
12+
switch x := v.(type) {
13+
case py.String:
14+
return fmt.Sprintf("'%s'", string(x))
15+
case py.Bytes:
16+
return fmt.Sprintf("b'%s'", string(x))
17+
case Identifier:
18+
return fmt.Sprintf("'%s'", string(x))
19+
case ModBase:
20+
case StmtBase:
21+
case ExprBase:
22+
case SliceBase:
23+
case Pos:
24+
case Ast:
25+
return Dump(x)
26+
case py.I__str__:
27+
return string(x.M__str__().(py.String))
28+
case Comprehension:
29+
return dump(v, "comprehension")
1930
}
31+
return fmt.Sprintf("%v", v)
32+
}
33+
34+
// Dump ast as a string with name
35+
func dump(ast interface{}, name string) string {
2036
astValue := reflect.Indirect(reflect.ValueOf(ast))
2137
astType := astValue.Type()
2238
args := make([]string, 0)
2339
for i := 0; i < astType.NumField(); i++ {
2440
fieldType := astType.Field(i)
2541
fieldValue := astValue.Field(i)
2642
fname := strings.ToLower(fieldType.Name)
43+
if fname == "stmtbase" || fname == "exprbase" || fname == "modbase" {
44+
continue
45+
}
2746
if fieldValue.Kind() == reflect.Slice && fieldValue.Type().Elem().Kind() != reflect.Uint8 {
2847
strs := make([]string, fieldValue.Len())
2948
for i := 0; i < fieldValue.Len(); i++ {
3049
element := fieldValue.Index(i)
3150
if element.CanInterface() {
32-
if x, ok := element.Interface().(Ast); ok {
33-
strs[i] = Dump(x)
34-
} else {
35-
strs[i] = fmt.Sprintf("%v", element)
36-
}
37-
} else {
38-
strs[i] = fmt.Sprintf("%v", element)
51+
v := element.Interface()
52+
strs[i] = dumpItem(v)
3953
}
4054
}
4155
args = append(args, fmt.Sprintf("%s=[%s]", fname, strings.Join(strs, ", ")))
4256
} else if fieldValue.CanInterface() {
4357
v := fieldValue.Interface()
44-
switch x := v.(type) {
45-
case py.String:
46-
args = append(args, fmt.Sprintf("%s='%s'", fname, string(x)))
47-
case py.Bytes:
48-
args = append(args, fmt.Sprintf("%s=b'%s'", fname, string(x)))
49-
case Identifier:
50-
args = append(args, fmt.Sprintf("%s='%s'", fname, string(x)))
51-
case ModBase:
52-
case StmtBase:
53-
case ExprBase:
54-
case SliceBase:
55-
case Pos:
56-
case Ast:
57-
args = append(args, fmt.Sprintf("%s=%s", fname, Dump(x)))
58-
case py.I__str__:
59-
args = append(args, fmt.Sprintf("%s=%s", fname, x.M__str__()))
60-
default:
61-
args = append(args, fmt.Sprintf("%s=%v", fname, x))
62-
}
58+
args = append(args, fmt.Sprintf("%s=%s", fname, dumpItem(v)))
6359
}
6460
}
6561
return fmt.Sprintf("%s(%s)", name, strings.Join(args, ", "))
6662
}
63+
64+
// Dump an Ast node as a string
65+
func Dump(ast Ast) string {
66+
if ast == nil {
67+
return "<nil>"
68+
}
69+
name := ast.Type().Name
70+
if name == "ExprStmt" {
71+
name = "Expr"
72+
}
73+
return dump(ast, name)
74+
}

ast/dump_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ func TestDump(t *testing.T) {
2323
{&Module{Body: []Stmt{&ExprStmt{Value: &Tuple{}}}}, `Module(body=[Expr(value=Tuple(elts=[], ctx=UnknownExprContext(0)))])`},
2424
{&NameConstant{Value: py.True}, `NameConstant(value=True)`},
2525
{&Name{Id: Identifier("hello"), Ctx: Load}, `Name(id='hello', ctx=Load())`},
26+
{&ListComp{Elt: &Str{S: py.String("potato")}, Generators: []Comprehension{{
27+
Target: &Name{Id: Identifier("hello"), Ctx: Load},
28+
}}}, `ListComp(elt=Str(s='potato'), generators=[comprehension(target=Name(id='hello', ctx=Load()), iter=<nil>, ifs=[])])`},
2629
} {
2730
out := Dump(test.in)
2831
if out != test.out {

0 commit comments

Comments
 (0)