Documentation ¶
Overview ¶
Package starlarkgen provides Starlark code generation methods from go.starlark.net (https://go.starlark.net) syntax tree primitives
Example ¶
// Parse source file f, err := syntax.Parse("testdata/import.star", nil, 0) if err != nil { log.Fatal(err) } // rename all the functions and function calls syntax.Walk(f, func(n syntax.Node) bool { switch t := n.(type) { case *syntax.DefStmt: t.Name.Name = "new_" + t.Name.Name case *syntax.CallExpr: if ident, ok := t.Fn.(*syntax.Ident); ok { ident.Name = "new_" + ident.Name } } return true }) // Build the Starlark source back from the AST tree // // Note that node positions will be ignored var sb strings.Builder sep := "" for _, s := range f.Stmts { sb.WriteString(sep) st, err := StarlarkStmt(s) if err != nil { log.Fatal(err) } sb.WriteString(st) sep = "\n" } fmt.Println(sb.String())
Output: """test import file""" def new_foo(n): pass def new_bar(x): new_foo(x * 2)
Index ¶
- func StarlarkExpr(input syntax.Expr, options ...Option) (string, error)
- func StarlarkStmt(input syntax.Stmt, options ...Option) (string, error)
- func WriteExpr(output io.StringWriter, input syntax.Expr, options ...Option) error
- func WriteStmt(output io.StringWriter, input syntax.Stmt, options ...Option) error
- type CallOption
- type DictOption
- type ListOption
- type Option
- type TupleOption
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func StarlarkExpr ¶
StarlarkExpr produces Starlark source code for a single expression using the options supplied. In case of an error the string output is always empty.
func StarlarkStmt ¶
StarlarkStmt produces Starlark source code for a single statement using the options supplied. In case of an error the string output is always empty.
Example ¶
stm := &syntax.DefStmt{ Name: &syntax.Ident{Name: "foo"}, Params: []syntax.Expr{ &syntax.Ident{Name: "bar"}, &syntax.BinaryExpr{X: &syntax.Ident{Name: "foo"}, Op: syntax.EQ, Y: &syntax.Literal{Value: 2}}, }, Body: []syntax.Stmt{ &syntax.ReturnStmt{Result: &syntax.BinaryExpr{X: &syntax.Ident{Name: "bar"}, Op: syntax.MINUS, Y: &syntax.Literal{Value: 2}}}, }, } st, err := StarlarkStmt(stm) if err != nil { log.Fatal(err) } fmt.Println(st)
Output: def foo(bar, foo=2): return bar - 2
func WriteExpr ¶
WriteExpr writes the Starlark expression to the provided writer using the options supplied. In case of an error incomplete results might be written to the output, use StarlarkStmt to avoid handling partial input.
Types ¶
type CallOption ¶
type CallOption renderOption
CallOption controls how the function calls are rendered. See examples for details on each specific option.
const ( // CallOptionSingleLine is the default, render as single line. CallOptionSingleLine CallOption = iota // CallOptionSingleLineComma will render call as single line, with comma after last argument. CallOptionSingleLineComma // CallOptionSingleLineCommaTwoAndMore will render call as single line, with comma after last argument, if there are two or more arguments. CallOptionSingleLineCommaTwoAndMore // CallOptionMultilineMultiple will render single argument calls as single line, // and two and more arguments as multiline. CallOptionMultilineMultiple // CallOptionMultilineMultipleComma will render single argument calls as single line, // and two and more arguments as multiline, with comma after last argument. CallOptionMultilineMultipleComma // CallOptionMultilineMultipleCommaTwoAndMore will render single argument calls as single line, // and two and more arguments as multiline, with comma after last argument if two or more argument are present. CallOptionMultilineMultipleCommaTwoAndMore // CallOptionMultiline will render call as multiline. CallOptionMultiline // CallOptionMultilineComma will render call as multiline, with comma after last argument. CallOptionMultilineComma // CallOptionMultilineCommaTwoAndMore will render call as multiline, with comma after last argument, if there are two or more argument. CallOptionMultilineCommaTwoAndMore )
type DictOption ¶
type DictOption renderOption
DictOption controls how the dict literals are rendered. See examples for details on each specific option.
const ( // DictOptionSingleLine is the default, render as single line. DictOptionSingleLine DictOption = iota // DictOptionSingleLineComma will render dict as single line, with comma after last item. DictOptionSingleLineComma // DictOptionSingleLineCommaTwoAndMore will render dict as single line, with comma after last item, if there are two or more items. DictOptionSingleLineCommaTwoAndMore // DictOptionMultilineMultiple will render single element dictionaries as single line, // and two and more elements as multiline. DictOptionMultilineMultiple // DictOptionMultilineMultipleComma will render single element dictionaries as single line, // and two and more elements as multiline, with comma after last item. DictOptionMultilineMultipleComma // DictOptionMultilineMultipleCommaTwoAndMore will render single element dictionaries as single line, // and two and more elements as multiline, with comma after last item if two or more elements are present. DictOptionMultilineMultipleCommaTwoAndMore // DictOptionMultiline will render dict as multiline. DictOptionMultiline // DictOptionMultilineComma will render dict as multiline, with comma after last item. DictOptionMultilineComma // DictOptionMultilineCommaTwoAndMore will render dict as multiline, with comma after last item, if there are two or more items. DictOptionMultilineCommaTwoAndMore )
type ListOption ¶
type ListOption renderOption
ListOption controls how the list literals are rendered. See examples for details on each specific option.
const ( // ListOptionSingleLine is the default, render as single line. ListOptionSingleLine ListOption = iota // ListOptionSingleLineComma will render list as single line, with comma after last item. ListOptionSingleLineComma // ListOptionSingleLineCommaTwoAndMore will render list as single line, with comma after last item, if there are two or more items. ListOptionSingleLineCommaTwoAndMore // ListOptionMultilineMultiple will render single element lists as single line, // and two and more elements as multiline. ListOptionMultilineMultiple // ListOptionMultilineMultipleComma will render single element lists as single line, // and two and more elements as multiline, with comma after last item. ListOptionMultilineMultipleComma // ListOptionMultilineMultipleCommaTwoAndMore will render single element lists as single line, // and two and more elements as multiline, with comma after last item if two or more elements are present. ListOptionMultilineMultipleCommaTwoAndMore // ListOptionMultiline will render list as multiline. ListOptionMultiline // ListOptionMultilineComma will render list as multiline, with comma after last item. ListOptionMultilineComma // ListOptionMultilineCommaTwoAndMore will render list as multiline, with comma after last item, if there are two or more items. ListOptionMultilineCommaTwoAndMore )
type Option ¶
type Option func(*outputOpts) (*outputOpts, error)
Option represents Starlark code rendering option.
func WithCallOption ¶
func WithCallOption(value CallOption) Option
WithCallOption sets the option to render function calls.
Example ¶
matrix := map[CallOption]string{ CallOptionMultiline: "CallOptionMultiline", CallOptionMultilineComma: "CallOptionMultilineComma", CallOptionMultilineCommaTwoAndMore: "CallOptionMultilineCommaTwoAndMore", CallOptionMultilineMultiple: "CallOptionMultilineMultiple", CallOptionMultilineMultipleComma: "CallOptionMultilineMultipleComma", CallOptionMultilineMultipleCommaTwoAndMore: "CallOptionMultilineMultipleCommaTwoAndMore", CallOptionSingleLine: "CallOptionSingleLine", CallOptionSingleLineComma: "CallOptionSingleLineComma", CallOptionSingleLineCommaTwoAndMore: "CallOptionSingleLineCommaTwoAndMore", } for i := 0; i < len(matrix); i++ { opt, name := CallOption(i), matrix[CallOption(i)] call := &syntax.CallExpr{ Fn: &syntax.Ident{Name: "some_func"}, Args: []syntax.Expr{ &syntax.Ident{Name: "foo"}, &syntax.Ident{Name: "bar"}, }, } fmt.Println(name) for { exp, err := StarlarkExpr(call, WithCallOption(opt)) if err != nil { log.Fatal(err) } fmt.Println(exp) if len(call.Args) == 0 { break } call.Args = call.Args[:len(call.Args)-1] } }
Output: CallOptionSingleLine some_func(foo, bar) some_func(foo) some_func() CallOptionSingleLineComma some_func(foo, bar,) some_func(foo,) some_func() CallOptionSingleLineCommaTwoAndMore some_func(foo, bar,) some_func(foo) some_func() CallOptionMultilineMultiple some_func( foo, bar ) some_func(foo) some_func() CallOptionMultilineMultipleComma some_func( foo, bar, ) some_func(foo,) some_func() CallOptionMultilineMultipleCommaTwoAndMore some_func( foo, bar, ) some_func(foo) some_func() CallOptionMultiline some_func( foo, bar ) some_func( foo ) some_func() CallOptionMultilineComma some_func( foo, bar, ) some_func( foo, ) some_func() CallOptionMultilineCommaTwoAndMore some_func( foo, bar, ) some_func( foo ) some_func()
func WithDepth ¶
WithDepth sets the initial indentation depth.
Example ¶
st, err := StarlarkStmt(&syntax.BranchStmt{Token: syntax.PASS}, WithDepth(10)) if err != nil { log.Fatal(err) } fmt.Println(len(st) - len(strings.TrimLeft(st, " "))) // 10 * 4
Output: 40
func WithDictOption ¶
func WithDictOption(value DictOption) Option
WithDictOption sets the option to render dictionary literals.
Example ¶
matrix := map[DictOption]string{ DictOptionMultiline: "DictOptionMultiline", DictOptionMultilineComma: "DictOptionMultilineComma", DictOptionMultilineCommaTwoAndMore: "DictOptionMultilineCommaTwoAndMore", DictOptionMultilineMultiple: "DictOptionMultilineMultiple", DictOptionMultilineMultipleComma: "DictOptionMultilineMultipleComma", DictOptionMultilineMultipleCommaTwoAndMore: "DictOptionMultilineMultipleCommaTwoAndMore", DictOptionSingleLine: "DictOptionSingleLine", DictOptionSingleLineComma: "DictOptionSingleLineComma", DictOptionSingleLineCommaTwoAndMore: "DictOptionSingleLineCommaTwoAndMore", } for i := 0; i < len(matrix); i++ { opt, name := DictOption(i), matrix[DictOption(i)] dict := &syntax.DictExpr{ List: []syntax.Expr{ &syntax.DictEntry{Key: &syntax.Ident{Name: "foo"}, Value: &syntax.Literal{Value: 1}}, &syntax.DictEntry{Key: &syntax.Ident{Name: "bar"}, Value: &syntax.Literal{Value: 2}}, }, } fmt.Println(name) for { exp, err := StarlarkExpr(dict, WithDictOption(opt)) if err != nil { log.Fatal(err) } fmt.Println(exp) if len(dict.List) == 0 { break } dict.List = dict.List[:len(dict.List)-1] } }
Output: DictOptionSingleLine {foo: 1, bar: 2} {foo: 1} {} DictOptionSingleLineComma {foo: 1, bar: 2,} {foo: 1,} {} DictOptionSingleLineCommaTwoAndMore {foo: 1, bar: 2,} {foo: 1} {} DictOptionMultilineMultiple { foo: 1, bar: 2 } {foo: 1} {} DictOptionMultilineMultipleComma { foo: 1, bar: 2, } {foo: 1,} {} DictOptionMultilineMultipleCommaTwoAndMore { foo: 1, bar: 2, } {foo: 1} {} DictOptionMultiline { foo: 1, bar: 2 } { foo: 1 } {} DictOptionMultilineComma { foo: 1, bar: 2, } { foo: 1, } {} DictOptionMultilineCommaTwoAndMore { foo: 1, bar: 2, } { foo: 1 } {}
func WithIndent ¶
WithIndent replaces the default indentation sequence.
Example ¶
st, err := StarlarkStmt(&syntax.IfStmt{ Cond: &syntax.BinaryExpr{Op: syntax.LT, X: &syntax.Ident{Name: "foo"}, Y: &syntax.Ident{Name: "bar"}}, True: []syntax.Stmt{&syntax.BranchStmt{Token: syntax.PASS}}, }, WithIndent("____")) if err != nil { log.Fatal(err) } fmt.Println(st)
Output: if foo < bar: ____pass
func WithListOption ¶
func WithListOption(value ListOption) Option
WithListOption sets the option to render list literals.
Example ¶
matrix := map[ListOption]string{ ListOptionMultiline: "ListOptionMultiline", ListOptionMultilineComma: "ListOptionMultilineComma", ListOptionMultilineCommaTwoAndMore: "ListOptionMultilineCommaTwoAndMore", ListOptionMultilineMultiple: "ListOptionMultilineMultiple", ListOptionMultilineMultipleComma: "ListOptionMultilineMultipleComma", ListOptionMultilineMultipleCommaTwoAndMore: "ListOptionMultilineMultipleCommaTwoAndMore", ListOptionSingleLine: "ListOptionSingleLine", ListOptionSingleLineComma: "ListOptionSingleLineComma", ListOptionSingleLineCommaTwoAndMore: "ListOptionSingleLineCommaTwoAndMore", } for i := 0; i < len(matrix); i++ { opt, name := ListOption(i), matrix[ListOption(i)] list := &syntax.ListExpr{ List: []syntax.Expr{ &syntax.Ident{Name: "foo"}, &syntax.Ident{Name: "bar"}, }, } fmt.Println(name) for { exp, err := StarlarkExpr(list, WithListOption(opt)) if err != nil { log.Fatal(err) } fmt.Println(exp) if len(list.List) == 0 { break } list.List = list.List[:len(list.List)-1] } }
Output: ListOptionSingleLine [foo, bar] [foo] [] ListOptionSingleLineComma [foo, bar,] [foo,] [] ListOptionSingleLineCommaTwoAndMore [foo, bar,] [foo] [] ListOptionMultilineMultiple [ foo, bar ] [foo] [] ListOptionMultilineMultipleComma [ foo, bar, ] [foo,] [] ListOptionMultilineMultipleCommaTwoAndMore [ foo, bar, ] [foo] [] ListOptionMultiline [ foo, bar ] [ foo ] [] ListOptionMultilineComma [ foo, bar, ] [ foo, ] [] ListOptionMultilineCommaTwoAndMore [ foo, bar, ] [ foo ] []
func WithSpaceEqBinary ¶
WithSpaceEqBinary sets the behavior of how the binary pairs foo=bar are rendered. when set to true, render results are
foo(bar = 1, baz = "z")
when set to false, render results are
foo(bar=1, baz="z")
This setting also applies to aliases in load(...) statement. The default value is false.
This setting does not affect the behavior of assignments, which always have the spaces around equality sign.
Example ¶
// foo=bar ex := &syntax.BinaryExpr{Op: syntax.EQ, X: &syntax.Ident{Name: "foo"}, Y: &syntax.Ident{Name: "bar"}} exWithSpace, err := StarlarkExpr(ex, WithSpaceEqBinary(true)) if err != nil { log.Fatal(err) } exWithoutSpace, err := StarlarkExpr(ex, WithSpaceEqBinary(false)) // can be omitted, false is default if err != nil { log.Fatal(err) } fmt.Println(exWithSpace) fmt.Println(exWithoutSpace)
Output: foo = bar foo=bar
func WithTupleOption ¶
func WithTupleOption(value TupleOption) Option
WithTupleOption sets the option to render tuple literals.
Example ¶
matrix := map[TupleOption]string{ TupleOptionMultiline: "TupleOptionMultiline", TupleOptionMultilineComma: "TupleOptionMultilineComma", TupleOptionMultilineCommaTwoAndMore: "TupleOptionMultilineCommaTwoAndMore", TupleOptionMultilineMultiple: "TupleOptionMultilineMultiple", TupleOptionMultilineMultipleComma: "TupleOptionMultilineMultipleComma", TupleOptionMultilineMultipleCommaTwoAndMore: "TupleOptionMultilineMultipleCommaTwoAndMore", TupleOptionSingleLine: "TupleOptionSingleLine", TupleOptionSingleLineComma: "TupleOptionSingleLineComma", TupleOptionSingleLineCommaTwoAndMore: "TupleOptionSingleLineCommaTwoAndMore", } for i := 0; i < len(matrix); i++ { opt, name := TupleOption(i), matrix[TupleOption(i)] tuple := &syntax.TupleExpr{ List: []syntax.Expr{ &syntax.Ident{Name: "foo"}, &syntax.Ident{Name: "bar"}, }, } paren := &syntax.ParenExpr{X: tuple} fmt.Println(name) for { exp, err := StarlarkExpr(paren, WithTupleOption(opt)) if err != nil { log.Fatal(err) } fmt.Println(exp) if len(tuple.List) == 0 { break } tuple.List = tuple.List[:len(tuple.List)-1] } }
Output: TupleOptionSingleLine (foo, bar) (foo) () TupleOptionSingleLineComma (foo, bar,) (foo,) () TupleOptionSingleLineCommaTwoAndMore (foo, bar,) (foo) () TupleOptionMultilineMultiple ( foo, bar ) (foo) () TupleOptionMultilineMultipleComma ( foo, bar, ) (foo,) () TupleOptionMultilineMultipleCommaTwoAndMore ( foo, bar, ) (foo) () TupleOptionMultiline ( foo, bar ) ( foo ) () TupleOptionMultilineComma ( foo, bar, ) ( foo, ) () TupleOptionMultilineCommaTwoAndMore ( foo, bar, ) ( foo ) ()
type TupleOption ¶
type TupleOption renderOption
TupleOption controls how the tuple literals are rendered. See examples for details on each specific option.
const ( // TupleOptionSingleLine is the default, render as single line. TupleOptionSingleLine TupleOption = iota // TupleOptionSingleLineComma will render tuple as single line, with comma after last item. TupleOptionSingleLineComma // TupleOptionSingleLineCommaTwoAndMore will render tuple as single line, with comma after last item, if there are two or more items. TupleOptionSingleLineCommaTwoAndMore // TupleOptionMultilineMultiple will render single element tuples as single line, // and two and more elements as multiline. TupleOptionMultilineMultiple // TupleOptionMultilineMultipleComma will render single element tuples as single line, // and two and more elements as multiline, with comma after last item. TupleOptionMultilineMultipleComma // TupleOptionMultilineMultipleCommaTwoAndMore will render single element tuples as single line, // and two and more elements as multiline, with comma after last item if two or more elements are present. TupleOptionMultilineMultipleCommaTwoAndMore // TupleOptionMultiline will render tuple as multiline. TupleOptionMultiline // TupleOptionMultilineComma will render tuple as multiline, with comma after last item. TupleOptionMultilineComma // TupleOptionMultilineCommaTwoAndMore will render tuple as multiline, with comma after last item, if there are two or more items. TupleOptionMultilineCommaTwoAndMore )