diff --git a/go.mod b/go.mod index e1ce64f0db..76f3a5b57c 100644 --- a/go.mod +++ b/go.mod @@ -63,7 +63,7 @@ require ( go.opentelemetry.io/otel v1.19.0 go.opentelemetry.io/otel/sdk v1.19.0 go.opentelemetry.io/otel/trace v1.19.0 - go.starlark.net v0.0.0-20230525235612-a134d8f9ddca + go.starlark.net v0.0.0-20240510163022-f457c4c2b267 go.uber.org/atomic v1.10.0 golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 golang.org/x/mod v0.15.0 diff --git a/go.sum b/go.sum index 05d858d786..ef928ea9ac 100644 --- a/go.sum +++ b/go.sum @@ -314,7 +314,6 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -335,8 +334,6 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -869,8 +866,8 @@ go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1 go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= -go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= -go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= +go.starlark.net v0.0.0-20240510163022-f457c4c2b267 h1:nHGP5vKtg2WaXA/AozoZWx/DI9wvwxCeikONJbdKdFo= +go.starlark.net v0.0.0-20240510163022-f457c4c2b267/go.mod h1:YKMCv9b1WrfWmeqdV5MAuEHWsu5iC+fe6kYl2sQjdI8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= @@ -1068,7 +1065,6 @@ golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -1169,7 +1165,6 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e h1:z3vDksarJxsAKM5dmEGv0GHwE2hKJ096wZra71Vs4sw= @@ -1193,10 +1188,7 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= diff --git a/vendor/go.starlark.net/internal/compile/compile.go b/vendor/go.starlark.net/internal/compile/compile.go index 888d95c560..b257d70d35 100644 --- a/vendor/go.starlark.net/internal/compile/compile.go +++ b/vendor/go.starlark.net/internal/compile/compile.go @@ -23,7 +23,6 @@ // // Operands, logically uint32s, are encoded using little-endian 7-bit // varints, the top bit indicating that more bytes follow. -// package compile // import "go.starlark.net/internal/compile" import ( @@ -47,7 +46,7 @@ var Disassemble = false const debug = false // make code generation verbose, for debugging the compiler // Increment this to force recompilation of saved bytecode files. -const Version = 13 +const Version = 14 type Opcode uint8 @@ -317,6 +316,7 @@ type Program struct { Functions []*Funcode Globals []Binding // for error messages and tracing Toplevel *Funcode // module initialization function + Recursion bool // disable recursion check for functions in this file } // The type of a bytes literal value, to distinguish from text string. @@ -335,7 +335,7 @@ type Funcode struct { pclinetab []uint16 // mapping from pc to linenum Locals []Binding // locals, parameters first Cells []int // indices of Locals that require cells - Freevars []Binding // for tracing + FreeVars []Binding // for tracing MaxStack int NumParams int NumKwonlyParams int @@ -486,17 +486,20 @@ func bindings(bindings []*resolve.Binding) []Binding { } // Expr compiles an expression to a program whose toplevel function evaluates it. -func Expr(expr syntax.Expr, name string, locals []*resolve.Binding) *Program { +// The options must be consistent with those used when parsing expr. +func Expr(opts *syntax.FileOptions, expr syntax.Expr, name string, locals []*resolve.Binding) *Program { pos := syntax.Start(expr) stmts := []syntax.Stmt{&syntax.ReturnStmt{Result: expr}} - return File(stmts, pos, name, locals, nil) + return File(opts, stmts, pos, name, locals, nil) } // File compiles the statements of a file into a program. -func File(stmts []syntax.Stmt, pos syntax.Position, name string, locals, globals []*resolve.Binding) *Program { +// The options must be consistent with those used when parsing stmts. +func File(opts *syntax.FileOptions, stmts []syntax.Stmt, pos syntax.Position, name string, locals, globals []*resolve.Binding) *Program { pcomp := &pcomp{ prog: &Program{ - Globals: bindings(globals), + Globals: bindings(globals), + Recursion: opts.Recursion, }, names: make(map[string]uint32), constants: make(map[interface{}]uint32), @@ -517,7 +520,7 @@ func (pcomp *pcomp) function(name string, pos syntax.Position, stmts []syntax.St Name: name, Doc: docStringFromBody(stmts), Locals: bindings(locals), - Freevars: bindings(freevars), + FreeVars: bindings(freevars), }, } @@ -884,7 +887,7 @@ func PrintOp(fn *Funcode, pc uint32, op Opcode, arg uint32) { case ATTR, SETFIELD, PREDECLARED, UNIVERSAL: comment = fn.Prog.Names[arg] case FREE: - comment = fn.Freevars[arg].Name + comment = fn.FreeVars[arg].Name case CALL, CALL_VAR, CALL_KW, CALL_VAR_KW: comment = fmt.Sprintf("%d pos, %d named", arg>>8, arg&0xff) default: diff --git a/vendor/go.starlark.net/internal/compile/serial.go b/vendor/go.starlark.net/internal/compile/serial.go index adadabfc22..0dbae47c28 100644 --- a/vendor/go.starlark.net/internal/compile/serial.go +++ b/vendor/go.starlark.net/internal/compile/serial.go @@ -25,6 +25,7 @@ package compile // toplevel Funcode // numfuncs varint // funcs []Funcode +// recursion varint (0 or 1) // []byte # concatenation of all referenced strings // EOF // @@ -130,6 +131,7 @@ func (prog *Program) Encode() []byte { for _, fn := range prog.Functions { e.function(fn) } + e.int(b2i(prog.Recursion)) // Patch in the offset of the string data section. binary.LittleEndian.PutUint32(e.p[4:8], uint32(len(e.p))) @@ -193,7 +195,7 @@ func (e *encoder) function(fn *Funcode) { for _, index := range fn.Cells { e.int(index) } - e.bindings(fn.Freevars) + e.bindings(fn.FreeVars) e.int(fn.MaxStack) e.int(fn.NumParams) e.int(fn.NumKwonlyParams) @@ -270,6 +272,7 @@ func DecodeProgram(data []byte) (_ *Program, err error) { for i := range funcs { funcs[i] = d.function() } + recursion := d.int() != 0 prog := &Program{ Loads: loads, @@ -278,6 +281,7 @@ func DecodeProgram(data []byte) (_ *Program, err error) { Globals: globals, Functions: funcs, Toplevel: toplevel, + Recursion: recursion, } toplevel.Prog = prog for _, f := range funcs { @@ -385,7 +389,7 @@ func (d *decoder) function() *Funcode { pclinetab: pclinetab, Locals: locals, Cells: cells, - Freevars: freevars, + FreeVars: freevars, MaxStack: maxStack, NumParams: numParams, NumKwonlyParams: numKwonlyParams, diff --git a/vendor/go.starlark.net/resolve/binding.go b/vendor/go.starlark.net/resolve/binding.go index 6b99f4b973..8507e64c71 100644 --- a/vendor/go.starlark.net/resolve/binding.go +++ b/vendor/go.starlark.net/resolve/binding.go @@ -10,7 +10,7 @@ import "go.starlark.net/syntax" // We cannot guarantee API stability for these types // as they are closely tied to the implementation. -// A Binding contains resolver information about an identifer. +// A Binding contains resolver information about an identifier. // The resolver populates the Binding field of each syntax.Identifier. // The Binding ties together all identifiers that denote the same variable. type Binding struct { diff --git a/vendor/go.starlark.net/resolve/resolve.go b/vendor/go.starlark.net/resolve/resolve.go index 09b9acdea7..494811dc78 100644 --- a/vendor/go.starlark.net/resolve/resolve.go +++ b/vendor/go.starlark.net/resolve/resolve.go @@ -97,6 +97,9 @@ const doesnt = "this Starlark dialect does not " // global options // These features are either not standard Starlark (yet), or deprecated // features of the BUILD language, so we put them behind flags. +// +// Deprecated: use an explicit [syntax.FileOptions] argument instead, +// as it avoids all the usual problems of global variables. var ( AllowSet = false // allow the 'set' built-in AllowGlobalReassign = false // allow reassignment to top-level names; also, allow if/for/while at top-level @@ -130,7 +133,7 @@ func File(file *syntax.File, isPredeclared, isUniversal func(name string) bool) // REPLChunk is a generalization of the File function that supports a // non-empty initial global block, as occurs in a REPL. func REPLChunk(file *syntax.File, isGlobal, isPredeclared, isUniversal func(name string) bool) error { - r := newResolver(isGlobal, isPredeclared, isUniversal) + r := newResolver(file.Options, isGlobal, isPredeclared, isUniversal) r.stmts(file.Stmts) r.env.resolveLocalUses() @@ -151,12 +154,20 @@ func REPLChunk(file *syntax.File, isGlobal, isPredeclared, isUniversal func(name return nil } -// Expr resolves the specified expression. -// It returns the local variables bound within the expression. +// Expr calls [ExprOptions] using [syntax.LegacyFileOptions]. // -// The isPredeclared and isUniversal predicates behave as for the File function. +// Deprecated: use [ExprOptions] with [syntax.FileOptions] instead, +// because this function relies on legacy global variables. func Expr(expr syntax.Expr, isPredeclared, isUniversal func(name string) bool) ([]*Binding, error) { - r := newResolver(nil, isPredeclared, isUniversal) + return ExprOptions(syntax.LegacyFileOptions(), expr, isPredeclared, isUniversal) +} + +// ExprOptions resolves the specified expression. +// It returns the local variables bound within the expression. +// +// The isPredeclared and isUniversal predicates behave as for the File function +func ExprOptions(opts *syntax.FileOptions, expr syntax.Expr, isPredeclared, isUniversal func(name string) bool) ([]*Binding, error) { + r := newResolver(opts, nil, isPredeclared, isUniversal) r.expr(expr) r.env.resolveLocalUses() r.resolveNonLocalUses(r.env) // globals & universals @@ -179,9 +190,10 @@ type Error struct { func (e Error) Error() string { return e.Pos.String() + ": " + e.Msg } -func newResolver(isGlobal, isPredeclared, isUniversal func(name string) bool) *resolver { +func newResolver(options *syntax.FileOptions, isGlobal, isPredeclared, isUniversal func(name string) bool) *resolver { file := new(block) return &resolver{ + options: options, file: file, env: file, isGlobal: isGlobal, @@ -193,6 +205,8 @@ func newResolver(isGlobal, isPredeclared, isUniversal func(name string) bool) *r } type resolver struct { + options *syntax.FileOptions + // env is the current local environment: // a linked list of blocks, innermost first. // The tail of the list is the file block. @@ -314,7 +328,7 @@ func (r *resolver) bind(id *syntax.Ident) bool { r.moduleGlobals = append(r.moduleGlobals, bind) } } - if ok && !AllowGlobalReassign { + if ok && !r.options.GlobalReassign { r.errorf(id.NamePos, "cannot reassign %s %s declared at %s", bind.Scope, id.Name, bind.First.NamePos) } @@ -382,7 +396,7 @@ func (r *resolver) use(id *syntax.Ident) { // We will piggyback support for the legacy semantics on the // AllowGlobalReassign flag, which is loosely related and also // required for Bazel. - if AllowGlobalReassign && r.env == r.file { + if r.options.GlobalReassign && r.env == r.file { r.useToplevel(use) return } @@ -420,7 +434,7 @@ func (r *resolver) useToplevel(use use) (bind *Binding) { r.predeclared[id.Name] = bind // save it } else if r.isUniversal(id.Name) { // use of universal name - if !AllowSet && id.Name == "set" { + if !r.options.Set && id.Name == "set" { r.errorf(id.NamePos, doesnt+"support sets") } bind = &Binding{Scope: Universal} @@ -493,7 +507,7 @@ func (r *resolver) stmt(stmt syntax.Stmt) { } case *syntax.IfStmt: - if !AllowGlobalReassign && r.container().function == nil { + if !r.options.TopLevelControl && r.container().function == nil { r.errorf(stmt.If, "if statement not within a function") } r.expr(stmt.Cond) @@ -519,7 +533,7 @@ func (r *resolver) stmt(stmt syntax.Stmt) { r.function(fn, stmt.Def) case *syntax.ForStmt: - if !AllowGlobalReassign && r.container().function == nil { + if !r.options.TopLevelControl && r.container().function == nil { r.errorf(stmt.For, "for loop not within a function") } r.expr(stmt.X) @@ -530,10 +544,10 @@ func (r *resolver) stmt(stmt syntax.Stmt) { r.loops-- case *syntax.WhileStmt: - if !AllowRecursion { + if !r.options.While { r.errorf(stmt.While, doesnt+"support while loops") } - if !AllowGlobalReassign && r.container().function == nil { + if !r.options.TopLevelControl && r.container().function == nil { r.errorf(stmt.While, "while loop not within a function") } r.expr(stmt.Cond) @@ -569,9 +583,9 @@ func (r *resolver) stmt(stmt syntax.Stmt) { } id := stmt.To[i] - if LoadBindsGlobally { + if r.options.LoadBindsGlobally { r.bind(id) - } else if r.bindLocal(id) && !AllowGlobalReassign { + } else if r.bindLocal(id) && !r.options.GlobalReassign { // "Global" in AllowGlobalReassign is a misnomer for "toplevel". // Sadly we can't report the previous declaration // as id.Binding may not be set yet. diff --git a/vendor/go.starlark.net/starlark/debug.go b/vendor/go.starlark.net/starlark/debug.go index 22a21240f1..bbb37b55fd 100644 --- a/vendor/go.starlark.net/starlark/debug.go +++ b/vendor/go.starlark.net/starlark/debug.go @@ -1,41 +1,59 @@ package starlark -import "go.starlark.net/syntax" +import ( + "go.starlark.net/syntax" +) // This file defines an experimental API for the debugging tools. // Some of these declarations expose details of internal packages. // (The debugger makes liberal use of exported fields of unexported types.) // Breaking changes may occur without notice. -// Local returns the value of the i'th local variable. -// It may be nil if not yet assigned. +// A Binding is the name and position of a binding identifier. +type Binding struct { + Name string + Pos syntax.Position +} + +// NumLocals returns the number of local variables of this frame. +// It is zero unless fr.Callable() is a *Function. +func (fr *frame) NumLocals() int { return len(fr.locals) } + +// Local returns the binding (name and binding position) and value of +// the i'th local variable of the frame's function. +// Beware: the value may be nil if it has not yet been assigned! // -// Local may be called only for frames whose Callable is a *Function (a -// function defined by Starlark source code), and only while the frame -// is active; it will panic otherwise. +// The index i must be less than [NumLocals]. +// Local may be called only while the frame is active. // // This function is provided only for debugging tools. -// -// THIS API IS EXPERIMENTAL AND MAY CHANGE WITHOUT NOTICE. -func (fr *frame) Local(i int) Value { return fr.locals[i] } +func (fr *frame) Local(i int) (Binding, Value) { + return Binding(fr.callable.(*Function).funcode.Locals[i]), fr.locals[i] +} // DebugFrame is the debugger API for a frame of the interpreter's call stack. // // Most applications have no need for this API; use CallFrame instead. // +// It may be tempting to use this interface when implementing built-in +// functions. Beware that reflection over the call stack is easily +// abused, leading to built-in functions whose behavior is mysterious +// and unpredictable. +// // Clients must not retain a DebugFrame nor call any of its methods once // the current built-in call has returned or execution has resumed // after a breakpoint as this may have unpredictable effects, including // but not limited to retention of object that would otherwise be garbage. type DebugFrame interface { - Callable() Callable // returns the frame's function - Local(i int) Value // returns the value of the (Starlark) frame's ith local variable - Position() syntax.Position // returns the current position of execution in this frame + Callable() Callable // returns the frame's function + NumLocals() int // returns the number of local variables in this frame + Local(i int) (Binding, Value) // returns the binding and value of the (Starlark) frame's ith local variable + Position() syntax.Position // returns the current position of execution in this frame } // DebugFrame returns the debugger interface for // the specified frame of the interpreter's call stack. -// Frame numbering is as for Thread.CallFrame. +// Frame numbering is as for Thread.CallFrame: 0 <= depth < thread.CallStackDepth(). // // This function is intended for use in debugging tools. // Most applications should have no need for it; use CallFrame instead. diff --git a/vendor/go.starlark.net/starlark/eval.go b/vendor/go.starlark.net/starlark/eval.go index 949cb934d4..cc99e5dcc9 100644 --- a/vendor/go.starlark.net/starlark/eval.go +++ b/vendor/go.starlark.net/starlark/eval.go @@ -7,7 +7,6 @@ package starlark import ( "fmt" "io" - "io/ioutil" "log" "math/big" "sort" @@ -325,7 +324,15 @@ func (prog *Program) Write(out io.Writer) error { return err } -// ExecFile parses, resolves, and executes a Starlark file in the +// ExecFile calls [ExecFileOptions] using [syntax.LegacyFileOptions]. +// +// Deprecated: use [ExecFileOptions] with [syntax.FileOptions] instead, +// because this function relies on legacy global variables. +func ExecFile(thread *Thread, filename string, src interface{}, predeclared StringDict) (StringDict, error) { + return ExecFileOptions(syntax.LegacyFileOptions(), thread, filename, src, predeclared) +} + +// ExecFileOptions parses, resolves, and executes a Starlark file in the // specified global environment, which may be modified during execution. // // Thread is the state associated with the Starlark thread. @@ -340,11 +347,11 @@ func (prog *Program) Write(out io.Writer) error { // Execution does not modify this dictionary, though it may mutate // its values. // -// If ExecFile fails during evaluation, it returns an *EvalError +// If ExecFileOptions fails during evaluation, it returns an *EvalError // containing a backtrace. -func ExecFile(thread *Thread, filename string, src interface{}, predeclared StringDict) (StringDict, error) { +func ExecFileOptions(opts *syntax.FileOptions, thread *Thread, filename string, src interface{}, predeclared StringDict) (StringDict, error) { // Parse, resolve, and compile a Starlark source file. - _, mod, err := SourceProgram(filename, src, predeclared.Has) + _, mod, err := SourceProgramOptions(opts, filename, src, predeclared.Has) if err != nil { return nil, err } @@ -354,7 +361,15 @@ func ExecFile(thread *Thread, filename string, src interface{}, predeclared Stri return g, err } -// SourceProgram produces a new program by parsing, resolving, +// SourceProgram calls [SourceProgramOptions] using [syntax.LegacyFileOptions]. +// +// Deprecated: use [SourceProgramOptions] with [syntax.FileOptions] instead, +// because this function relies on legacy global variables. +func SourceProgram(filename string, src interface{}, isPredeclared func(string) bool) (*syntax.File, *Program, error) { + return SourceProgramOptions(syntax.LegacyFileOptions(), filename, src, isPredeclared) +} + +// SourceProgramOptions produces a new program by parsing, resolving, // and compiling a Starlark source file. // On success, it returns the parsed file and the compiled program. // The filename and src parameters are as for syntax.Parse. @@ -363,8 +378,8 @@ func ExecFile(thread *Thread, filename string, src interface{}, predeclared Stri // a pre-declared identifier of the current module. // Its typical value is predeclared.Has, // where predeclared is a StringDict of pre-declared values. -func SourceProgram(filename string, src interface{}, isPredeclared func(string) bool) (*syntax.File, *Program, error) { - f, err := syntax.Parse(filename, src, 0) +func SourceProgramOptions(opts *syntax.FileOptions, filename string, src interface{}, isPredeclared func(string) bool) (*syntax.File, *Program, error) { + f, err := opts.Parse(filename, src, 0) if err != nil { return nil, nil, err } @@ -396,7 +411,7 @@ func FileProgram(f *syntax.File, isPredeclared func(string) bool) (*Program, err } module := f.Module.(*resolve.Module) - compiled := compile.File(f.Stmts, pos, "", module.Locals, module.Globals) + compiled := compile.File(f.Options, f.Stmts, pos, "", module.Locals, module.Globals) return &Program{compiled}, nil } @@ -404,7 +419,7 @@ func FileProgram(f *syntax.File, isPredeclared func(string) bool) (*Program, err // CompiledProgram produces a new program from the representation // of a compiled program previously saved by Program.Write. func CompiledProgram(in io.Reader) (*Program, error) { - data, err := ioutil.ReadAll(in) + data, err := io.ReadAll(in) if err != nil { return nil, err } @@ -453,7 +468,7 @@ func ExecREPLChunk(f *syntax.File, thread *Thread, globals StringDict) error { } module := f.Module.(*resolve.Module) - compiled := compile.File(f.Stmts, pos, "", module.Locals, module.Globals) + compiled := compile.File(f.Options, f.Stmts, pos, "", module.Locals, module.Globals) prog := &Program{compiled} // -- variant of Program.Init -- @@ -512,7 +527,15 @@ func makeToplevelFunction(prog *compile.Program, predeclared StringDict) *Functi } } -// Eval parses, resolves, and evaluates an expression within the +// Eval calls [EvalOptions] using [syntax.LegacyFileOptions]. +// +// Deprecated: use [EvalOptions] with [syntax.FileOptions] instead, +// because this function relies on legacy global variables. +func Eval(thread *Thread, filename string, src interface{}, env StringDict) (Value, error) { + return EvalOptions(syntax.LegacyFileOptions(), thread, filename, src, env) +} + +// EvalOptions parses, resolves, and evaluates an expression within the // specified (predeclared) environment. // // Evaluation cannot mutate the environment dictionary itself, @@ -520,58 +543,75 @@ func makeToplevelFunction(prog *compile.Program, predeclared StringDict) *Functi // // The filename and src parameters are as for syntax.Parse. // -// If Eval fails during evaluation, it returns an *EvalError +// If EvalOptions fails during evaluation, it returns an *EvalError // containing a backtrace. -func Eval(thread *Thread, filename string, src interface{}, env StringDict) (Value, error) { - expr, err := syntax.ParseExpr(filename, src, 0) +func EvalOptions(opts *syntax.FileOptions, thread *Thread, filename string, src interface{}, env StringDict) (Value, error) { + expr, err := opts.ParseExpr(filename, src, 0) if err != nil { return nil, err } - f, err := makeExprFunc(expr, env) + f, err := makeExprFunc(opts, expr, env) if err != nil { return nil, err } return Call(thread, f, nil, nil) } -// EvalExpr resolves and evaluates an expression within the +// EvalExpr calls [EvalExprOptions] using [syntax.LegacyFileOptions]. +// +// Deprecated: use [EvalExprOptions] with [syntax.FileOptions] instead, +// because this function relies on legacy global variables. +func EvalExpr(thread *Thread, expr syntax.Expr, env StringDict) (Value, error) { + return EvalExprOptions(syntax.LegacyFileOptions(), thread, expr, env) +} + +// EvalExprOptions resolves and evaluates an expression within the // specified (predeclared) environment. // Evaluating a comma-separated list of expressions yields a tuple value. // // Resolving an expression mutates it. -// Do not call EvalExpr more than once for the same expression. +// Do not call EvalExprOptions more than once for the same expression. // // Evaluation cannot mutate the environment dictionary itself, // though it may modify variables reachable from the dictionary. // -// If Eval fails during evaluation, it returns an *EvalError +// If EvalExprOptions fails during evaluation, it returns an *EvalError // containing a backtrace. -func EvalExpr(thread *Thread, expr syntax.Expr, env StringDict) (Value, error) { - fn, err := makeExprFunc(expr, env) +func EvalExprOptions(opts *syntax.FileOptions, thread *Thread, expr syntax.Expr, env StringDict) (Value, error) { + fn, err := makeExprFunc(opts, expr, env) if err != nil { return nil, err } return Call(thread, fn, nil, nil) } +// ExprFunc calls [ExprFuncOptions] using [syntax.LegacyFileOptions]. +// +// Deprecated: use [ExprFuncOptions] with [syntax.FileOptions] instead, +// because this function relies on legacy global variables. +func ExprFunc(filename string, src interface{}, env StringDict) (*Function, error) { + return ExprFuncOptions(syntax.LegacyFileOptions(), filename, src, env) +} + // ExprFunc returns a no-argument function // that evaluates the expression whose source is src. -func ExprFunc(filename string, src interface{}, env StringDict) (*Function, error) { - expr, err := syntax.ParseExpr(filename, src, 0) +func ExprFuncOptions(options *syntax.FileOptions, filename string, src interface{}, env StringDict) (*Function, error) { + expr, err := options.ParseExpr(filename, src, 0) if err != nil { return nil, err } - return makeExprFunc(expr, env) + return makeExprFunc(options, expr, env) } // makeExprFunc returns a no-argument function whose body is expr. -func makeExprFunc(expr syntax.Expr, env StringDict) (*Function, error) { - locals, err := resolve.Expr(expr, env.Has, Universe.Has) +// The options must be consistent with those used when parsing expr. +func makeExprFunc(opts *syntax.FileOptions, expr syntax.Expr, env StringDict) (*Function, error) { + locals, err := resolve.ExprOptions(opts, expr, env.Has, Universe.Has) if err != nil { return nil, err } - return makeToplevelFunction(compile.Expr(expr, "", locals), env), nil + return makeToplevelFunction(compile.Expr(opts, expr, "", locals), env), nil } // The following functions are primitive operations of the byte code interpreter. @@ -795,6 +835,12 @@ func Binary(op syntax.Token, x, y Value) (Value, error) { } return x - yf, nil } + case *Set: // difference + if y, ok := y.(*Set); ok { + iter := y.Iterate() + defer iter.Done() + return x.Difference(iter) + } } case syntax.STAR: @@ -1066,17 +1112,9 @@ func Binary(op syntax.Token, x, y Value) (Value, error) { } case *Set: // intersection if y, ok := y.(*Set); ok { - set := new(Set) - if x.Len() > y.Len() { - x, y = y, x // opt: range over smaller set - } - for xe := x.ht.head; xe != nil; xe = xe.next { - // Has, Insert cannot fail here. - if found, _ := y.Has(xe.key); found { - set.Insert(xe.key) - } - } - return set, nil + iter := y.Iterate() + defer iter.Done() + return x.Intersection(iter) } } @@ -1088,18 +1126,9 @@ func Binary(op syntax.Token, x, y Value) (Value, error) { } case *Set: // symmetric difference if y, ok := y.(*Set); ok { - set := new(Set) - for xe := x.ht.head; xe != nil; xe = xe.next { - if found, _ := y.Has(xe.key); !found { - set.Insert(xe.key) - } - } - for ye := y.ht.head; ye != nil; ye = ye.next { - if found, _ := x.Has(ye.key); !found { - set.Insert(ye.key) - } - } - return set, nil + iter := y.Iterate() + defer iter.Done() + return x.SymmetricDifference(iter) } } @@ -1640,9 +1669,14 @@ func interpolate(format string, x Value) (Value, error) { index++ } - if index < nargs { + if index < nargs && !is[Mapping](x) { return nil, fmt.Errorf("too many arguments for format string") } return String(buf.String()), nil } + +func is[T any](x any) bool { + _, ok := x.(T) + return ok +} diff --git a/vendor/go.starlark.net/starlark/hashtable.go b/vendor/go.starlark.net/starlark/hashtable.go index 252d21d12d..e1bbeaafc6 100644 --- a/vendor/go.starlark.net/starlark/hashtable.go +++ b/vendor/go.starlark.net/starlark/hashtable.go @@ -6,7 +6,8 @@ package starlark import ( "fmt" - _ "unsafe" // for go:linkname hack + "hash/maphash" + "math/big" ) // hashtable is used to represent Starlark dict and set values. @@ -200,6 +201,57 @@ func (ht *hashtable) lookup(k Value) (v Value, found bool, err error) { return None, false, nil // not found } +// count returns the number of distinct elements of iter that are elements of ht. +func (ht *hashtable) count(iter Iterator) (int, error) { + if ht.table == nil { + return 0, nil // empty + } + + var k Value + count := 0 + + // Use a bitset per table entry to record seen elements of ht. + // Elements are identified by their bucket number and index within the bucket. + // Each bitset gets one word initially, but may grow. + storage := make([]big.Word, len(ht.table)) + bitsets := make([]big.Int, len(ht.table)) + for i := range bitsets { + bitsets[i].SetBits(storage[i : i+1 : i+1]) + } + for iter.Next(&k) && count != int(ht.len) { + h, err := k.Hash() + if err != nil { + return 0, err // unhashable + } + if h == 0 { + h = 1 // zero is reserved + } + + // Inspect each bucket in the bucket list. + bucketId := h & (uint32(len(ht.table) - 1)) + i := 0 + for p := &ht.table[bucketId]; p != nil; p = p.next { + for j := range p.entries { + e := &p.entries[j] + if e.hash == h { + if eq, err := Equal(k, e.key); err != nil { + return 0, err + } else if eq { + bitIndex := i<<3 + j + if bitsets[bucketId].Bit(bitIndex) == 0 { + bitsets[bucketId].SetBit(&bitsets[bucketId], bitIndex, 1) + count++ + } + } + } + } + i++ + } + } + + return count, nil +} + // Items returns all the items in the map (as key/value pairs) in insertion order. func (ht *hashtable) items() []Tuple { items := make([]Tuple, 0, ht.len) @@ -364,21 +416,29 @@ func (it *keyIterator) Done() { } } -// TODO(adonovan): use go1.19's maphash.String. +// entries is a go1.23 iterator over the entries of the hash table. +func (ht *hashtable) entries(yield func(k, v Value) bool) { + if !ht.frozen { + ht.itercount++ + defer func() { ht.itercount-- }() + } + for e := ht.head; e != nil && yield(e.key, e.value); e = e.next { + } +} + +var seed = maphash.MakeSeed() // hashString computes the hash of s. func hashString(s string) uint32 { if len(s) >= 12 { // Call the Go runtime's optimized hash implementation, - // which uses the AESENC instruction on amd64 machines. - return uint32(goStringHash(s, 0)) + // which uses the AES instructions on amd64 and arm64 machines. + h := maphash.String(seed, s) + return uint32(h>>32) | uint32(h) } return softHashString(s) } -//go:linkname goStringHash runtime.stringHash -func goStringHash(s string, seed uintptr) uintptr - // softHashString computes the 32-bit FNV-1a hash of s in software. func softHashString(s string) uint32 { var h uint32 = 2166136261 diff --git a/vendor/go.starlark.net/starlark/int.go b/vendor/go.starlark.net/starlark/int.go index a264e9d22d..8f2b279c76 100644 --- a/vendor/go.starlark.net/starlark/int.go +++ b/vendor/go.starlark.net/starlark/int.go @@ -191,15 +191,16 @@ func (i Int) Hash() (uint32, error) { return 12582917 * uint32(lo+3), nil } -// Required by the TotallyOrdered interface -func (x Int) Cmp(v Value, depth int) (int, error) { - y := v.(Int) - xSmall, xBig := x.get() - ySmall, yBig := y.get() - if xBig != nil || yBig != nil { - return x.bigInt().Cmp(y.bigInt()), nil +// Cmp implements comparison of two Int values. +// Required by the TotallyOrdered interface. +func (i Int) Cmp(v Value, depth int) (int, error) { + j := v.(Int) + iSmall, iBig := i.get() + jSmall, jBig := j.get() + if iBig != nil || jBig != nil { + return i.bigInt().Cmp(j.bigInt()), nil } - return signum64(xSmall - ySmall), nil // safe: int32 operands + return signum64(iSmall - jSmall), nil // safe: int32 operands } // Float returns the float value nearest i. @@ -211,6 +212,12 @@ func (i Int) Float() Float { return Float(iBig.Uint64()) } else if iBig.IsInt64() { return Float(iBig.Int64()) + } else { + // Fast path for very big ints. + const maxFiniteLen = 1023 + 1 // max exponent value + implicit mantissa bit + if iBig.BitLen() > maxFiniteLen { + return Float(math.Inf(iBig.Sign())) + } } f, _ := new(big.Float).SetInt(iBig).Float64() diff --git a/vendor/go.starlark.net/starlark/int_generic.go b/vendor/go.starlark.net/starlark/int_generic.go index f2adf45321..244a60ca5b 100644 --- a/vendor/go.starlark.net/starlark/int_generic.go +++ b/vendor/go.starlark.net/starlark/int_generic.go @@ -1,5 +1,4 @@ -//go:build (!linux && !darwin && !dragonfly && !freebsd && !netbsd && !solaris) || (!amd64 && !arm64 && !mips64x && !ppc64x && !loong64) -// +build !linux,!darwin,!dragonfly,!freebsd,!netbsd,!solaris !amd64,!arm64,!mips64x,!ppc64x,!loong64 +//go:build (!linux && !darwin && !dragonfly && !freebsd && !netbsd && !solaris) || (!amd64 && !arm64 && !mips64x && !ppc64 && !ppc64le && !loong64 && !s390x) package starlark diff --git a/vendor/go.starlark.net/starlark/int_posix64.go b/vendor/go.starlark.net/starlark/int_posix64.go index 2ab0beda3f..70c949efc2 100644 --- a/vendor/go.starlark.net/starlark/int_posix64.go +++ b/vendor/go.starlark.net/starlark/int_posix64.go @@ -1,6 +1,4 @@ -//go:build (linux || darwin || dragonfly || freebsd || netbsd || solaris) && (amd64 || arm64 || mips64x || ppc64x || loong64) -// +build linux darwin dragonfly freebsd netbsd solaris -// +build amd64 arm64 mips64x ppc64x loong64 +//go:build (linux || darwin || dragonfly || freebsd || netbsd || solaris) && (amd64 || arm64 || mips64x || ppc64 || ppc64le || loong64 || s390x) package starlark diff --git a/vendor/go.starlark.net/starlark/interp.go b/vendor/go.starlark.net/starlark/interp.go index b41905a0b0..261077fb6a 100644 --- a/vendor/go.starlark.net/starlark/interp.go +++ b/vendor/go.starlark.net/starlark/interp.go @@ -10,7 +10,6 @@ import ( "go.starlark.net/internal/compile" "go.starlark.net/internal/spell" - "go.starlark.net/resolve" "go.starlark.net/syntax" ) @@ -24,19 +23,19 @@ func (fn *Function) CallInternal(thread *Thread, args Tuple, kwargs []Tuple) (Va // Postcondition: args is not mutated. This is stricter than required by Callable, // but allows CALL to avoid a copy. - if !resolve.AllowRecursion { + f := fn.funcode + if !f.Prog.Recursion { // detect recursion for _, fr := range thread.stack[:len(thread.stack)-1] { // We look for the same function code, // not function value, otherwise the user could // defeat the check by writing the Y combinator. - if frfn, ok := fr.Callable().(*Function); ok && frfn.funcode == fn.funcode { + if frfn, ok := fr.Callable().(*Function); ok && frfn.funcode == f { return nil, fmt.Errorf("function %s called recursively", fn.Name()) } } } - f := fn.funcode fr := thread.frameAt(0) // Allocate space for stack and locals. @@ -542,7 +541,7 @@ loop: case compile.MAKEFUNC: funcode := f.Prog.Functions[arg] tuple := stack[sp-1].(Tuple) - n := len(tuple) - len(funcode.Freevars) + n := len(tuple) - len(funcode.FreeVars) defaults := tuple[:n:n] freevars := tuple[n:] stack[sp-1] = &Function{ @@ -623,7 +622,7 @@ loop: case compile.FREECELL: v := fn.freevars[arg].(*cell).v if v == nil { - err = fmt.Errorf("local variable %s referenced before assignment", f.Freevars[arg].Name) + err = fmt.Errorf("local variable %s referenced before assignment", f.FreeVars[arg].Name) break loop } stack[sp] = v diff --git a/vendor/go.starlark.net/starlark/library.go b/vendor/go.starlark.net/starlark/library.go index 1c801be644..4e73a40ba6 100644 --- a/vendor/go.starlark.net/starlark/library.go +++ b/vendor/go.starlark.net/starlark/library.go @@ -40,7 +40,7 @@ func init() { "True": True, "False": False, "abs": NewBuiltin("abs", abs), - "any": NewBuiltin("any", any), + "any": NewBuiltin("any", any_), "all": NewBuiltin("all", all), "bool": NewBuiltin("bool", bool_), "bytes": NewBuiltin("bytes", bytes_), @@ -140,7 +140,17 @@ var ( } setMethods = map[string]*Builtin{ - "union": NewBuiltin("union", set_union), + "add": NewBuiltin("add", set_add), + "clear": NewBuiltin("clear", set_clear), + "difference": NewBuiltin("difference", set_difference), + "discard": NewBuiltin("discard", set_discard), + "intersection": NewBuiltin("intersection", set_intersection), + "issubset": NewBuiltin("issubset", set_issubset), + "issuperset": NewBuiltin("issuperset", set_issuperset), + "pop": NewBuiltin("pop", set_pop), + "remove": NewBuiltin("remove", set_remove), + "symmetric_difference": NewBuiltin("symmetric_difference", set_symmetric_difference), + "union": NewBuiltin("union", set_union), } ) @@ -200,7 +210,7 @@ func all(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) } // https://github.com/google/starlark-go/blob/master/doc/spec.md#any -func any(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) { +func any_(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) { var iterable Iterable if err := UnpackPositionalArgs("any", args, kwargs, 1, &iterable); err != nil { return nil, err @@ -2168,6 +2178,162 @@ func string_splitlines(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value return NewList(list), nil } +// https://github.com/google/starlark-go/blob/master/doc/spec.md#set·add. +func set_add(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) { + var elem Value + if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &elem); err != nil { + return nil, err + } + if found, err := b.Receiver().(*Set).Has(elem); err != nil { + return nil, nameErr(b, err) + } else if found { + return None, nil + } + err := b.Receiver().(*Set).Insert(elem) + if err != nil { + return nil, nameErr(b, err) + } + return None, nil +} + +// https://github.com/google/starlark-go/blob/master/doc/spec.md#set·clear. +func set_clear(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) { + if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil { + return nil, err + } + if b.Receiver().(*Set).Len() > 0 { + if err := b.Receiver().(*Set).Clear(); err != nil { + return nil, nameErr(b, err) + } + } + return None, nil +} + +// https://github.com/google/starlark-go/blob/master/doc/spec.md#set·difference. +func set_difference(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) { + // TODO: support multiple others: s.difference(*others) + var other Iterable + if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &other); err != nil { + return nil, err + } + iter := other.Iterate() + defer iter.Done() + diff, err := b.Receiver().(*Set).Difference(iter) + if err != nil { + return nil, nameErr(b, err) + } + return diff, nil +} + +// https://github.com/google/starlark-go/blob/master/doc/spec.md#set_intersection. +func set_intersection(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) { + // TODO: support multiple others: s.difference(*others) + var other Iterable + if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &other); err != nil { + return nil, err + } + iter := other.Iterate() + defer iter.Done() + diff, err := b.Receiver().(*Set).Intersection(iter) + if err != nil { + return nil, nameErr(b, err) + } + return diff, nil +} + +// https://github.com/google/starlark-go/blob/master/doc/spec.md#set_issubset. +func set_issubset(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) { + var other Iterable + if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &other); err != nil { + return nil, err + } + iter := other.Iterate() + defer iter.Done() + diff, err := b.Receiver().(*Set).IsSubset(iter) + if err != nil { + return nil, nameErr(b, err) + } + return Bool(diff), nil +} + +// https://github.com/google/starlark-go/blob/master/doc/spec.md#set_issuperset. +func set_issuperset(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) { + var other Iterable + if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &other); err != nil { + return nil, err + } + iter := other.Iterate() + defer iter.Done() + diff, err := b.Receiver().(*Set).IsSuperset(iter) + if err != nil { + return nil, nameErr(b, err) + } + return Bool(diff), nil +} + +// https://github.com/google/starlark-go/blob/master/doc/spec.md#set·discard. +func set_discard(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) { + var k Value + if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &k); err != nil { + return nil, err + } + if found, err := b.Receiver().(*Set).Has(k); err != nil { + return nil, nameErr(b, err) + } else if !found { + return None, nil + } + if _, err := b.Receiver().(*Set).Delete(k); err != nil { + return nil, nameErr(b, err) // set is frozen + } + return None, nil +} + +// https://github.com/google/starlark-go/blob/master/doc/spec.md#set·pop. +func set_pop(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) { + if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil { + return nil, err + } + recv := b.Receiver().(*Set) + k, ok := recv.ht.first() + if !ok { + return nil, nameErr(b, "empty set") + } + _, err := recv.Delete(k) + if err != nil { + return nil, nameErr(b, err) // set is frozen + } + return k, nil +} + +// https://github.com/google/starlark-go/blob/master/doc/spec.md#set·remove. +func set_remove(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) { + var k Value + if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &k); err != nil { + return nil, err + } + if found, err := b.Receiver().(*Set).Delete(k); err != nil { + return nil, nameErr(b, err) // dict is frozen or key is unhashable + } else if found { + return None, nil + } + return nil, nameErr(b, "missing key") +} + +// https://github.com/google/starlark-go/blob/master/doc/spec.md#set·symmetric_difference. +func set_symmetric_difference(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) { + var other Iterable + if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &other); err != nil { + return nil, err + } + iter := other.Iterate() + defer iter.Done() + diff, err := b.Receiver().(*Set).SymmetricDifference(iter) + if err != nil { + return nil, nameErr(b, err) + } + return diff, nil +} + // https://github.com/google/starlark-go/blob/master/doc/spec.md#set·union. func set_union(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) { var iterable Iterable diff --git a/vendor/go.starlark.net/starlark/profile.go b/vendor/go.starlark.net/starlark/profile.go index 38da2b2e9f..364f30ca2a 100644 --- a/vendor/go.starlark.net/starlark/profile.go +++ b/vendor/go.starlark.net/starlark/profile.go @@ -22,7 +22,7 @@ package starlark // stack and sends it to the profiler goroutine, along with the number // of quanta, which are subtracted. For example, if the accumulator // holds 3ms and then a completed span adds 25ms to it, its value is 28ms, -// which exceeeds 10ms. The profiler records a stack with the value 20ms +// which exceeds 10ms. The profiler records a stack with the value 20ms // (2 quanta), and the accumulator is left with 8ms. // // The profiler goroutine converts the stacks into the pprof format and @@ -101,11 +101,11 @@ func StartProfile(w io.Writer) error { return nil } -// StopProfiler stops the profiler started by a prior call to +// StopProfile stops the profiler started by a prior call to // StartProfile and finalizes the profile. It returns an error if the // profile could not be completed. // -// StopProfiler must not be called concurrently with Starlark execution. +// StopProfile must not be called concurrently with Starlark execution. func StopProfile() error { // Terminate the profiler goroutine and get its result. close(profiler.events) @@ -391,7 +391,7 @@ func profFuncAddr(fn Callable) uintptr { } // User-defined callable types are typically of - // of kind pointer-to-struct. Handle them specially. + // kind pointer-to-struct. Handle them specially. if v := reflect.ValueOf(fn); v.Type().Kind() == reflect.Ptr { return v.Pointer() } diff --git a/vendor/go.starlark.net/starlark/unpack.go b/vendor/go.starlark.net/starlark/unpack.go index 3168589921..d15dd8ee7f 100644 --- a/vendor/go.starlark.net/starlark/unpack.go +++ b/vendor/go.starlark.net/starlark/unpack.go @@ -25,7 +25,7 @@ type Unpacker interface { // If the variable is a bool, integer, string, *List, *Dict, Callable, // Iterable, or user-defined implementation of Value, // UnpackArgs performs the appropriate type check. -// Predeclared Go integer types uses the AsInt check. +// Predeclared Go integer types use the AsInt check. // // If the parameter name ends with "?", it is optional. // @@ -33,7 +33,7 @@ type Unpacker interface { // as if the argument was absent. // // If a parameter is marked optional, then all following parameters are -// implicitly optional where or not they are marked. +// implicitly optional whether or not they are marked. // // If the variable implements Unpacker, its Unpack argument // is called with the argument value, allowing an application @@ -44,23 +44,23 @@ type Unpacker interface { // // Examples: // -// var ( -// a Value -// b = MakeInt(42) -// c Value = starlark.None -// ) +// var ( +// a Value +// b = MakeInt(42) +// c Value = starlark.None +// ) // -// // 1. mixed parameters, like def f(a, b=42, c=None). -// err := UnpackArgs("f", args, kwargs, "a", &a, "b?", &b, "c?", &c) +// // 1. mixed parameters, like def f(a, b=42, c=None). +// err := UnpackArgs("f", args, kwargs, "a", &a, "b?", &b, "c?", &c) // -// // 2. keyword parameters only, like def f(*, a, b, c=None). -// if len(args) > 0 { -// return fmt.Errorf("f: unexpected positional arguments") -// } -// err := UnpackArgs("f", args, kwargs, "a", &a, "b?", &b, "c?", &c) +// // 2. keyword parameters only, like def f(*, a, b, c=None). +// if len(args) > 0 { +// return fmt.Errorf("f: unexpected positional arguments") +// } +// err := UnpackArgs("f", args, kwargs, "a", &a, "b?", &b, "c?", &c) // -// // 3. positional parameters only, like def f(a, b=42, c=None, /) in Python 3.8. -// err := UnpackPositionalArgs("f", args, kwargs, 1, &a, &b, &c) +// // 3. positional parameters only, like def f(a, b=42, c=None, /) in Python 3.8. +// err := UnpackPositionalArgs("f", args, kwargs, 1, &a, &b, &c) // // More complex forms such as def f(a, b=42, *args, c, d=123, **kwargs) // require additional logic, but their need in built-ins is exceedingly rare. @@ -79,23 +79,22 @@ type Unpacker interface { // for the zero values of variables of type *List, *Dict, Callable, or // Iterable. For example: // -// // def myfunc(d=None, e=[], f={}) -// var ( -// d Value -// e *List -// f *Dict -// ) -// err := UnpackArgs("myfunc", args, kwargs, "d?", &d, "e?", &e, "f?", &f) -// if d == nil { d = None; } -// if e == nil { e = new(List); } -// if f == nil { f = new(Dict); } -// -func UnpackArgs(fnname string, args Tuple, kwargs []Tuple, pairs ...interface{}) error { +// // def myfunc(d=None, e=[], f={}) +// var ( +// d Value +// e *List +// f *Dict +// ) +// err := UnpackArgs("myfunc", args, kwargs, "d?", &d, "e?", &e, "f?", &f) +// if d == nil { d = None; } +// if e == nil { e = new(List); } +// if f == nil { f = new(Dict); } +func UnpackArgs(fnname string, args Tuple, kwargs []Tuple, pairs ...any) error { nparams := len(pairs) / 2 var defined intset defined.init(nparams) - paramName := func(x interface{}) (name string, skipNone bool) { // (no free variables) + paramName := func(x any) (name string, skipNone bool) { // (no free variables) name = x.(string) if strings.HasSuffix(name, "??") { name = strings.TrimSuffix(name, "??") @@ -164,12 +163,15 @@ kwloop: } // Check that all non-optional parameters are defined. - // (We needn't check the first len(args).) - for i := len(args); i < nparams; i++ { + for i := 0; i < nparams; i++ { name := pairs[2*i].(string) if strings.HasSuffix(name, "?") { break // optional } + // (We needn't check the first len(args).) + if i < len(args) { + continue + } if !defined.get(i) { return fmt.Errorf("%s: missing argument for %s", fnname, name) } @@ -187,7 +189,7 @@ kwloop: // any conversion fails. // // See UnpackArgs for general comments. -func UnpackPositionalArgs(fnname string, args Tuple, kwargs []Tuple, min int, vars ...interface{}) error { +func UnpackPositionalArgs(fnname string, args Tuple, kwargs []Tuple, min int, vars ...any) error { if len(kwargs) > 0 { return fmt.Errorf("%s: unexpected keyword arguments", fnname) } @@ -214,7 +216,7 @@ func UnpackPositionalArgs(fnname string, args Tuple, kwargs []Tuple, min int, va return nil } -func unpackOneArg(v Value, ptr interface{}) error { +func unpackOneArg(v Value, ptr any) error { // On failure, don't clobber *ptr. switch ptr := ptr.(type) { case Unpacker: diff --git a/vendor/go.starlark.net/starlark/value.go b/vendor/go.starlark.net/starlark/value.go index da21795167..d0a9bb35c6 100644 --- a/vendor/go.starlark.net/starlark/value.go +++ b/vendor/go.starlark.net/starlark/value.go @@ -254,12 +254,17 @@ var ( // // Example usage: // -// iter := iterable.Iterator() +// var seq Iterator = ... +// iter := seq.Iterate() // defer iter.Done() -// var x Value -// for iter.Next(&x) { +// var elem Value +// for iter.Next(elem) { // ... // } +// +// Or, using go1.23 iterators: +// +// for elem := range Elements(seq) { ... } type Iterator interface { // If the iterator is exhausted, Next returns false. // Otherwise it sets *p to the current element of the sequence, @@ -283,6 +288,8 @@ type Mapping interface { } // An IterableMapping is a mapping that supports key enumeration. +// +// See [Entries] for example use. type IterableMapping interface { Mapping Iterate() Iterator // see Iterable interface @@ -465,9 +472,11 @@ func isFinite(f float64) bool { return math.Abs(f) <= math.MaxFloat64 } -func (x Float) Cmp(y_ Value, depth int) (int, error) { - y := y_.(Float) - return floatCmp(x, y), nil +// Cmp implements comparison of two Float values. +// Required by the TotallyOrdered interface. +func (f Float) Cmp(v Value, depth int) (int, error) { + g := v.(Float) + return floatCmp(f, g), nil } // floatCmp performs a three-valued comparison on floats, @@ -526,7 +535,7 @@ func (f Float) Unary(op syntax.Token) (Value, error) { // String is the type of a Starlark text string. // -// A String encapsulates an an immutable sequence of bytes, +// A String encapsulates an immutable sequence of bytes, // but strings are not directly iterable. Instead, iterate // over the result of calling one of these four methods: // codepoints, codepoint_ords, elems, elem_ords. @@ -766,6 +775,15 @@ func (fn *Function) ParamDefault(i int) Value { func (fn *Function) HasVarargs() bool { return fn.funcode.HasVarargs } func (fn *Function) HasKwargs() bool { return fn.funcode.HasKwargs } +// NumFreeVars returns the number of free variables of this function. +func (fn *Function) NumFreeVars() int { return len(fn.funcode.FreeVars) } + +// FreeVar returns the binding (name and binding position) and value +// of the i'th free variable of function fn. +func (fn *Function) FreeVar(i int) (Binding, Value) { + return Binding(fn.funcode.FreeVars[i]), fn.freevars[i].(*cell).v +} + // A Builtin is a function implemented in Go. type Builtin struct { name string @@ -845,6 +863,7 @@ func (d *Dict) Type() string { return "dict" func (d *Dict) Freeze() { d.ht.freeze() } func (d *Dict) Truth() Bool { return d.Len() > 0 } func (d *Dict) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable type: dict") } +func (d *Dict) Entries() func(yield func(k, v Value) bool) { return d.ht.entries } func (x *Dict) Union(y *Dict) *Dict { z := new(Dict) @@ -952,6 +971,25 @@ func (l *List) Iterate() Iterator { return &listIterator{l: l} } +// Elements returns a go1.23 iterator over the elements of the list. +// +// Example: +// +// for elem := range list.Elements() { ... } +func (l *List) Elements() func(yield func(Value) bool) { + return func(yield func(Value) bool) { + if !l.frozen { + l.itercount++ + defer func() { l.itercount-- }() + } + for _, x := range l.elems { + if !yield(x) { + break + } + } + } +} + func (x *List) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) { y := y_.(*List) // It's tempting to check x == y as an optimization here, @@ -1051,6 +1089,22 @@ func (t Tuple) Slice(start, end, step int) Value { } func (t Tuple) Iterate() Iterator { return &tupleIterator{elems: t} } + +// Elements returns a go1.23 iterator over the elements of the tuple. +// +// (A Tuple is a slice, so it is of course directly iterable. This +// method exists to provide a fast path for the [Elements] standalone +// function.) +func (t Tuple) Elements() func(yield func(Value) bool) { + return func(yield func(Value) bool) { + for _, x := range t { + if !yield(x) { + break + } + } + } +} + func (t Tuple) Freeze() { for _, elem := range t { elem.Freeze() @@ -1122,6 +1176,11 @@ func (s *Set) Truth() Bool { return s.Len() > 0 } func (s *Set) Attr(name string) (Value, error) { return builtinAttr(s, name, setMethods) } func (s *Set) AttrNames() []string { return builtinAttrNames(setMethods) } +func (s *Set) Elements() func(yield func(k Value) bool) { + return func(yield func(k Value) bool) { + s.ht.entries(func(k, _ Value) bool { return yield(k) }) + } +} func (x *Set) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) { y := y_.(*Set) @@ -1132,6 +1191,34 @@ func (x *Set) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error case syntax.NEQ: ok, err := setsEqual(x, y, depth) return !ok, err + case syntax.GE: // superset + if x.Len() < y.Len() { + return false, nil + } + iter := y.Iterate() + defer iter.Done() + return x.IsSuperset(iter) + case syntax.LE: // subset + if x.Len() > y.Len() { + return false, nil + } + iter := y.Iterate() + defer iter.Done() + return x.IsSubset(iter) + case syntax.GT: // proper superset + if x.Len() <= y.Len() { + return false, nil + } + iter := y.Iterate() + defer iter.Done() + return x.IsSuperset(iter) + case syntax.LT: // proper subset + if x.Len() >= y.Len() { + return false, nil + } + iter := y.Iterate() + defer iter.Done() + return x.IsSubset(iter) default: return false, fmt.Errorf("%s %s %s not implemented", x.Type(), op, y.Type()) } @@ -1149,11 +1236,28 @@ func setsEqual(x, y *Set, depth int) (bool, error) { return true, nil } -func (s *Set) Union(iter Iterator) (Value, error) { +func setFromIterator(iter Iterator) (*Set, error) { + var x Value + set := new(Set) + for iter.Next(&x) { + err := set.Insert(x) + if err != nil { + return set, err + } + } + return set, nil +} + +func (s *Set) clone() *Set { set := new(Set) for e := s.ht.head; e != nil; e = e.next { set.Insert(e.key) // can't fail } + return set +} + +func (s *Set) Union(iter Iterator) (Value, error) { + set := s.clone() var x Value for iter.Next(&x) { if err := set.Insert(x); err != nil { @@ -1163,6 +1267,72 @@ func (s *Set) Union(iter Iterator) (Value, error) { return set, nil } +func (s *Set) Difference(other Iterator) (Value, error) { + diff := s.clone() + var x Value + for other.Next(&x) { + if _, err := diff.Delete(x); err != nil { + return nil, err + } + } + return diff, nil +} + +func (s *Set) IsSuperset(other Iterator) (bool, error) { + var x Value + for other.Next(&x) { + found, err := s.Has(x) + if err != nil { + return false, err + } + if !found { + return false, nil + } + } + return true, nil +} + +func (s *Set) IsSubset(other Iterator) (bool, error) { + if count, err := s.ht.count(other); err != nil { + return false, err + } else { + return count == s.Len(), nil + } +} + +func (s *Set) Intersection(other Iterator) (Value, error) { + intersect := new(Set) + var x Value + for other.Next(&x) { + found, err := s.Has(x) + if err != nil { + return nil, err + } + if found { + err = intersect.Insert(x) + if err != nil { + return nil, err + } + } + } + return intersect, nil +} + +func (s *Set) SymmetricDifference(other Iterator) (Value, error) { + diff := s.clone() + var x Value + for other.Next(&x) { + found, err := diff.Delete(x) + if err != nil { + return nil, err + } + if !found { + diff.Insert(x) + } + } + return diff, nil +} + // toString returns the string form of value v. // It may be more efficient than v.String() for larger values. func toString(v Value) string { @@ -1448,10 +1618,78 @@ func Iterate(x Value) Iterator { return nil } +// Elements returns an iterator for the elements of the iterable value. +// +// Example of go1.23 iteration: +// +// for elem := range Elements(iterable) { ... } +// +// Push iterators are provided as a convenience for Go client code. The +// core iteration behavior of Starlark for-loops is defined by the +// [Iterable] interface. +// +// TODO(adonovan): change return type to go1.23 iter.Seq[Value]. +func Elements(iterable Iterable) func(yield func(Value) bool) { + // Use specialized push iterator if available (*List, Tuple, *Set). + type hasElements interface { + Elements() func(yield func(k Value) bool) + } + if iterable, ok := iterable.(hasElements); ok { + return iterable.Elements() + } + + iter := iterable.Iterate() + return func(yield func(Value) bool) { + defer iter.Done() + var x Value + for iter.Next(&x) && yield(x) { + } + } +} + +// Entries returns an iterator over the entries (key/value pairs) of +// the iterable mapping. +// +// Example of go1.23 iteration: +// +// for k, v := range Entries(mapping) { ... } +// +// Push iterators are provided as a convenience for Go client code. The +// core iteration behavior of Starlark for-loops is defined by the +// [Iterable] interface. +// +// TODO(adonovan): change return type to go1.23 iter.Seq2[Value, Value]. +func Entries(mapping IterableMapping) func(yield func(k, v Value) bool) { + // If available (e.g. *Dict), use specialized push iterator, + // as it gets k and v in one shot. + type hasEntries interface { + Entries() func(yield func(k, v Value) bool) + } + if mapping, ok := mapping.(hasEntries); ok { + return mapping.Entries() + } + + iter := mapping.Iterate() + return func(yield func(k, v Value) bool) { + defer iter.Done() + var k Value + for iter.Next(&k) { + v, found, err := mapping.Get(k) + if err != nil || !found { + panic(fmt.Sprintf("Iterate and Get are inconsistent (mapping=%v, key=%v)", + mapping.Type(), k.Type())) + } + if !yield(k, v) { + break + } + } + } +} + // Bytes is the type of a Starlark binary string. // // A Bytes encapsulates an immutable sequence of bytes. -// It is comparable, indexable, and sliceable, but not direcly iterable; +// It is comparable, indexable, and sliceable, but not directly iterable; // use bytes.elems() for an iterable view. // // In this Go implementation, the elements of 'string' and 'bytes' are diff --git a/vendor/go.starlark.net/syntax/options.go b/vendor/go.starlark.net/syntax/options.go new file mode 100644 index 0000000000..51b2638233 --- /dev/null +++ b/vendor/go.starlark.net/syntax/options.go @@ -0,0 +1,63 @@ +// Copyright 2023 The Bazel Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package syntax + +import _ "unsafe" // for linkname + +// FileOptions specifies various per-file options that affect static +// aspects of an individual file such as parsing, name resolution, and +// code generation. (Options that affect global dynamics are typically +// controlled through [starlark.Thread].) +// +// The zero value of FileOptions is the default behavior. +// +// Many functions in this package come in two versions: the legacy +// standalone function (such as [Parse]) uses [LegacyFileOptions], +// whereas the more recent method (such as [Options.Parse]) honors the +// provided options. The second form is preferred. In other packages, +// the modern version is a standalone function with a leading +// FileOptions parameter and the name suffix "Options", such as +// [starlark.ExecFileOptions]. +type FileOptions struct { + // resolver + Set bool // allow references to the 'set' built-in function + While bool // allow 'while' statements + TopLevelControl bool // allow if/for/while statements at top-level + GlobalReassign bool // allow reassignment to top-level names + LoadBindsGlobally bool // load creates global not file-local bindings (deprecated) + + // compiler + Recursion bool // disable recursion check for functions in this file +} + +// TODO(adonovan): provide a canonical flag parser for FileOptions. +// (And use it in the testdata "options:" strings.) + +// LegacyFileOptions returns a new FileOptions containing the current +// values of the resolver package's legacy global variables such as +// [resolve.AllowRecursion], etc. +// These variables may be associated with command-line flags. +func LegacyFileOptions() *FileOptions { + return &FileOptions{ + Set: resolverAllowSet, + While: resolverAllowGlobalReassign, + TopLevelControl: resolverAllowGlobalReassign, + GlobalReassign: resolverAllowGlobalReassign, + Recursion: resolverAllowRecursion, + LoadBindsGlobally: resolverLoadBindsGlobally, + } +} + +// Access resolver (legacy) flags, if they are linked in; false otherwise. +var ( + //go:linkname resolverAllowSet go.starlark.net/resolve.AllowSet + resolverAllowSet bool + //go:linkname resolverAllowGlobalReassign go.starlark.net/resolve.AllowGlobalReassign + resolverAllowGlobalReassign bool + //go:linkname resolverAllowRecursion go.starlark.net/resolve.AllowRecursion + resolverAllowRecursion bool + //go:linkname resolverLoadBindsGlobally go.starlark.net/resolve.LoadBindsGlobally + resolverLoadBindsGlobally bool +) diff --git a/vendor/go.starlark.net/syntax/parse.go b/vendor/go.starlark.net/syntax/parse.go index f4c8fff4d7..215e20d9b8 100644 --- a/vendor/go.starlark.net/syntax/parse.go +++ b/vendor/go.starlark.net/syntax/parse.go @@ -23,19 +23,27 @@ const ( RetainComments Mode = 1 << iota // retain comments in AST; see Node.Comments ) +// Parse calls the Parse method of LegacyFileOptions(). +// +// Deprecated: use [FileOptions.Parse] instead, +// because this function relies on legacy global variables. +func Parse(filename string, src interface{}, mode Mode) (f *File, err error) { + return LegacyFileOptions().Parse(filename, src, mode) +} + // Parse parses the input data and returns the corresponding parse tree. // -// If src != nil, ParseFile parses the source from src and the filename +// If src != nil, Parse parses the source from src and the filename // is only used when recording position information. // The type of the argument for the src parameter must be string, // []byte, io.Reader, or FilePortion. -// If src == nil, ParseFile parses the file specified by filename. -func Parse(filename string, src interface{}, mode Mode) (f *File, err error) { +// If src == nil, Parse parses the file specified by filename. +func (opts *FileOptions) Parse(filename string, src interface{}, mode Mode) (f *File, err error) { in, err := newScanner(filename, src, mode&RetainComments != 0) if err != nil { return nil, err } - p := parser{in: in} + p := parser{options: opts, in: in} defer p.in.recover(&err) p.nextToken() // read first lookahead token @@ -47,6 +55,14 @@ func Parse(filename string, src interface{}, mode Mode) (f *File, err error) { return f, nil } +// ParseCompoundStmt calls the ParseCompoundStmt method of LegacyFileOptions(). +// +// Deprecated: use [FileOptions.ParseCompoundStmt] instead, +// because this function relies on legacy global variables. +func ParseCompoundStmt(filename string, readline func() ([]byte, error)) (f *File, err error) { + return LegacyFileOptions().ParseCompoundStmt(filename, readline) +} + // ParseCompoundStmt parses a single compound statement: // a blank line, a def, for, while, or if statement, or a // semicolon-separated list of simple statements followed @@ -54,13 +70,13 @@ func Parse(filename string, src interface{}, mode Mode) (f *File, err error) { // ParseCompoundStmt does not consume any following input. // The parser calls the readline function each // time it needs a new line of input. -func ParseCompoundStmt(filename string, readline func() ([]byte, error)) (f *File, err error) { +func (opts *FileOptions) ParseCompoundStmt(filename string, readline func() ([]byte, error)) (f *File, err error) { in, err := newScanner(filename, readline, false) if err != nil { return nil, err } - p := parser{in: in} + p := parser{options: opts, in: in} defer p.in.recover(&err) p.nextToken() // read first lookahead token @@ -79,18 +95,26 @@ func ParseCompoundStmt(filename string, readline func() ([]byte, error)) (f *Fil } } - return &File{Path: filename, Stmts: stmts}, nil + return &File{Options: opts, Path: filename, Stmts: stmts}, nil +} + +// ParseExpr calls the ParseExpr method of LegacyFileOptions(). +// +// Deprecated: use [FileOptions.ParseExpr] instead, +// because this function relies on legacy global variables. +func ParseExpr(filename string, src interface{}, mode Mode) (expr Expr, err error) { + return LegacyFileOptions().ParseExpr(filename, src, mode) } // ParseExpr parses a Starlark expression. // A comma-separated list of expressions is parsed as a tuple. // See Parse for explanation of parameters. -func ParseExpr(filename string, src interface{}, mode Mode) (expr Expr, err error) { +func (opts *FileOptions) ParseExpr(filename string, src interface{}, mode Mode) (expr Expr, err error) { in, err := newScanner(filename, src, mode&RetainComments != 0) if err != nil { return nil, err } - p := parser{in: in} + p := parser{options: opts, in: in} defer p.in.recover(&err) p.nextToken() // read first lookahead token @@ -112,9 +136,10 @@ func ParseExpr(filename string, src interface{}, mode Mode) (expr Expr, err erro } type parser struct { - in *scanner - tok Token - tokval tokenValue + options *FileOptions + in *scanner + tok Token + tokval tokenValue } // nextToken advances the scanner and returns the position of the @@ -139,7 +164,7 @@ func (p *parser) parseFile() *File { } stmts = p.parseStmt(stmts) } - return &File{Stmts: stmts} + return &File{Options: p.options, Stmts: stmts} } func (p *parser) parseStmt(stmts []Stmt) []Stmt { @@ -158,15 +183,17 @@ func (p *parser) parseStmt(stmts []Stmt) []Stmt { func (p *parser) parseDefStmt() Stmt { defpos := p.nextToken() // consume DEF id := p.parseIdent() - p.consume(LPAREN) + lparen := p.consume(LPAREN) params := p.parseParams() - p.consume(RPAREN) + rparen := p.consume(RPAREN) p.consume(COLON) body := p.parseSuite() return &DefStmt{ Def: defpos, Name: id, + Lparen: lparen, Params: params, + Rparen: rparen, Body: body, } } @@ -275,10 +302,11 @@ func (p *parser) parseSimpleStmt(stmts []Stmt, consumeNL bool) []Stmt { } // small_stmt = RETURN expr? -// | PASS | BREAK | CONTINUE -// | LOAD ... -// | expr ('=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=') expr // assign -// | expr +// +// | PASS | BREAK | CONTINUE +// | LOAD ... +// | expr ('=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=') expr // assign +// | expr func (p *parser) parseSmallStmt() Stmt { switch p.tok { case RETURN: @@ -415,21 +443,23 @@ func (p *parser) consume(t Token) Position { } // params = (param COMMA)* param COMMA? -// | +// +// | // // param = IDENT -// | IDENT EQ test -// | STAR -// | STAR IDENT -// | STARSTAR IDENT +// +// | IDENT EQ test +// | STAR +// | STAR IDENT +// | STARSTAR IDENT // // parseParams parses a parameter list. The resulting expressions are of the form: // -// *Ident x -// *Binary{Op: EQ, X: *Ident, Y: Expr} x=y -// *Unary{Op: STAR} * -// *Unary{Op: STAR, X: *Ident} *args -// *Unary{Op: STARSTAR, X: *Ident} **kwargs +// *Ident x +// *Binary{Op: EQ, X: *Ident, Y: Expr} x=y +// *Unary{Op: STAR} * +// *Unary{Op: STAR, X: *Ident} *args +// *Unary{Op: STARSTAR, X: *Ident} **kwargs func (p *parser) parseParams() []Expr { var params []Expr for p.tok != RPAREN && p.tok != COLON && p.tok != EOF { @@ -532,7 +562,7 @@ func (p *parser) parseTest() Expr { return x } -// parseTestNoCond parses a a single-component expression without +// parseTestNoCond parses a single-component expression without // consuming a trailing 'if expr else expr'. func (p *parser) parseTestNoCond() Expr { if p.tok == LAMBDA { @@ -651,9 +681,10 @@ func init() { } // primary_with_suffix = primary -// | primary '.' IDENT -// | primary slice_suffix -// | primary call_suffix +// +// | primary '.' IDENT +// | primary slice_suffix +// | primary call_suffix func (p *parser) parsePrimaryWithSuffix() Expr { x := p.parsePrimary() for { @@ -770,12 +801,13 @@ func (p *parser) parseArgs() []Expr { return args } -// primary = IDENT -// | INT | FLOAT | STRING | BYTES -// | '[' ... // list literal or comprehension -// | '{' ... // dict literal or comprehension -// | '(' ... // tuple or parenthesized expression -// | ('-'|'+'|'~') primary_with_suffix +// primary = IDENT +// +// | INT | FLOAT | STRING | BYTES +// | '[' ... // list literal or comprehension +// | '{' ... // dict literal or comprehension +// | '(' ... // tuple or parenthesized expression +// | ('-'|'+'|'~') primary_with_suffix func (p *parser) parsePrimary() Expr { switch p.tok { case IDENT: @@ -831,14 +863,17 @@ func (p *parser) parsePrimary() Expr { X: x, } } - p.in.errorf(p.in.pos, "got %#v, want primary expression", p.tok) + + // Report start pos of final token as it may be a NEWLINE (#532). + p.in.errorf(p.tokval.pos, "got %#v, want primary expression", p.tok) panic("unreachable") } // list = '[' ']' -// | '[' expr ']' -// | '[' expr expr_list ']' -// | '[' expr (FOR loop_variables IN expr)+ ']' +// +// | '[' expr ']' +// | '[' expr expr_list ']' +// | '[' expr (FOR loop_variables IN expr)+ ']' func (p *parser) parseList() Expr { lbrack := p.nextToken() if p.tok == RBRACK { @@ -865,8 +900,9 @@ func (p *parser) parseList() Expr { } // dict = '{' '}' -// | '{' dict_entry_list '}' -// | '{' dict_entry FOR loop_variables IN expr '}' +// +// | '{' dict_entry_list '}' +// | '{' dict_entry FOR loop_variables IN expr '}' func (p *parser) parseDict() Expr { lbrace := p.nextToken() if p.tok == RBRACE { @@ -904,8 +940,9 @@ func (p *parser) parseDictEntry() *DictEntry { } // comp_suffix = FOR loopvars IN expr comp_suffix -// | IF expr comp_suffix -// | ']' or ')' (end) +// +// | IF expr comp_suffix +// | ']' or ')' (end) // // There can be multiple FOR/IF clauses; the first is always a FOR. func (p *parser) parseComprehensionSuffix(lbrace Position, body Expr, endBrace Token) Expr { diff --git a/vendor/go.starlark.net/syntax/scan.go b/vendor/go.starlark.net/syntax/scan.go index bb4165e9d2..95499772f9 100644 --- a/vendor/go.starlark.net/syntax/scan.go +++ b/vendor/go.starlark.net/syntax/scan.go @@ -9,7 +9,6 @@ package syntax import ( "fmt" "io" - "io/ioutil" "log" "math/big" "os" @@ -287,7 +286,7 @@ func readSource(filename string, src interface{}) ([]byte, error) { case []byte: return src, nil case io.Reader: - data, err := ioutil.ReadAll(src) + data, err := io.ReadAll(src) if err != nil { err = &os.PathError{Op: "read", Path: filename, Err: err} return nil, err @@ -296,7 +295,7 @@ func readSource(filename string, src interface{}) ([]byte, error) { case FilePortion: return src.Content, nil case nil: - return ioutil.ReadFile(filename) + return os.ReadFile(filename) default: return nil, fmt.Errorf("invalid source: %T", src) } @@ -1107,6 +1106,8 @@ var keywordToken = map[string]Token{ // reserved words: "as": ILLEGAL, // "assert": ILLEGAL, // heavily used by our tests + "async": ILLEGAL, + "await": ILLEGAL, "class": ILLEGAL, "del": ILLEGAL, "except": ILLEGAL, diff --git a/vendor/go.starlark.net/syntax/syntax.go b/vendor/go.starlark.net/syntax/syntax.go index 3756637583..5bfbcec39a 100644 --- a/vendor/go.starlark.net/syntax/syntax.go +++ b/vendor/go.starlark.net/syntax/syntax.go @@ -70,7 +70,8 @@ type File struct { Path string Stmts []Stmt - Module interface{} // a *resolve.Module, set by resolver + Module interface{} // a *resolve.Module, set by resolver + Options *FileOptions } func (x *File) Span() (start, end Position) { @@ -99,9 +100,10 @@ func (*LoadStmt) stmt() {} func (*ReturnStmt) stmt() {} // An AssignStmt represents an assignment: +// // x = 0 // x, y = y, x -// x += 1 +// x += 1 type AssignStmt struct { commentsRef OpPos Position @@ -121,7 +123,9 @@ type DefStmt struct { commentsRef Def Position Name *Ident + Lparen Position Params []Expr // param = ident | ident=expr | * | *ident | **ident + Rparen Position Body []Stmt Function interface{} // a *resolve.Function, set by resolver diff --git a/vendor/modules.txt b/vendor/modules.txt index 6b165a5c7f..030b3d166d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -821,8 +821,8 @@ go.opentelemetry.io/proto/otlp/collector/trace/v1 go.opentelemetry.io/proto/otlp/common/v1 go.opentelemetry.io/proto/otlp/resource/v1 go.opentelemetry.io/proto/otlp/trace/v1 -# go.starlark.net v0.0.0-20230525235612-a134d8f9ddca -## explicit; go 1.16 +# go.starlark.net v0.0.0-20240510163022-f457c4c2b267 +## explicit; go 1.19 go.starlark.net/internal/compile go.starlark.net/internal/spell go.starlark.net/resolve