1*4947cdc7SCole Faust// Copyright 2017 The Bazel Authors. All rights reserved. 2*4947cdc7SCole Faust// Use of this source code is governed by a BSD-style 3*4947cdc7SCole Faust// license that can be found in the LICENSE file. 4*4947cdc7SCole Faust 5*4947cdc7SCole Faustpackage resolve_test 6*4947cdc7SCole Faust 7*4947cdc7SCole Faustimport ( 8*4947cdc7SCole Faust "strings" 9*4947cdc7SCole Faust "testing" 10*4947cdc7SCole Faust 11*4947cdc7SCole Faust "go.starlark.net/internal/chunkedfile" 12*4947cdc7SCole Faust "go.starlark.net/resolve" 13*4947cdc7SCole Faust "go.starlark.net/starlarktest" 14*4947cdc7SCole Faust "go.starlark.net/syntax" 15*4947cdc7SCole Faust) 16*4947cdc7SCole Faust 17*4947cdc7SCole Faustfunc setOptions(src string) { 18*4947cdc7SCole Faust resolve.AllowGlobalReassign = option(src, "globalreassign") 19*4947cdc7SCole Faust resolve.AllowRecursion = option(src, "recursion") 20*4947cdc7SCole Faust resolve.AllowSet = option(src, "set") 21*4947cdc7SCole Faust resolve.LoadBindsGlobally = option(src, "loadbindsglobally") 22*4947cdc7SCole Faust} 23*4947cdc7SCole Faust 24*4947cdc7SCole Faustfunc option(chunk, name string) bool { 25*4947cdc7SCole Faust return strings.Contains(chunk, "option:"+name) 26*4947cdc7SCole Faust} 27*4947cdc7SCole Faust 28*4947cdc7SCole Faustfunc TestResolve(t *testing.T) { 29*4947cdc7SCole Faust defer setOptions("") 30*4947cdc7SCole Faust filename := starlarktest.DataFile("resolve", "testdata/resolve.star") 31*4947cdc7SCole Faust for _, chunk := range chunkedfile.Read(filename, t) { 32*4947cdc7SCole Faust f, err := syntax.Parse(filename, chunk.Source, 0) 33*4947cdc7SCole Faust if err != nil { 34*4947cdc7SCole Faust t.Error(err) 35*4947cdc7SCole Faust continue 36*4947cdc7SCole Faust } 37*4947cdc7SCole Faust 38*4947cdc7SCole Faust // A chunk may set options by containing e.g. "option:recursion". 39*4947cdc7SCole Faust setOptions(chunk.Source) 40*4947cdc7SCole Faust 41*4947cdc7SCole Faust if err := resolve.File(f, isPredeclared, isUniversal); err != nil { 42*4947cdc7SCole Faust for _, err := range err.(resolve.ErrorList) { 43*4947cdc7SCole Faust chunk.GotError(int(err.Pos.Line), err.Msg) 44*4947cdc7SCole Faust } 45*4947cdc7SCole Faust } 46*4947cdc7SCole Faust chunk.Done() 47*4947cdc7SCole Faust } 48*4947cdc7SCole Faust} 49*4947cdc7SCole Faust 50*4947cdc7SCole Faustfunc TestDefVarargsAndKwargsSet(t *testing.T) { 51*4947cdc7SCole Faust source := "def f(*args, **kwargs): pass\n" 52*4947cdc7SCole Faust file, err := syntax.Parse("foo.star", source, 0) 53*4947cdc7SCole Faust if err != nil { 54*4947cdc7SCole Faust t.Fatal(err) 55*4947cdc7SCole Faust } 56*4947cdc7SCole Faust if err := resolve.File(file, isPredeclared, isUniversal); err != nil { 57*4947cdc7SCole Faust t.Fatal(err) 58*4947cdc7SCole Faust } 59*4947cdc7SCole Faust fn := file.Stmts[0].(*syntax.DefStmt).Function.(*resolve.Function) 60*4947cdc7SCole Faust if !fn.HasVarargs { 61*4947cdc7SCole Faust t.Error("HasVarargs not set") 62*4947cdc7SCole Faust } 63*4947cdc7SCole Faust if !fn.HasKwargs { 64*4947cdc7SCole Faust t.Error("HasKwargs not set") 65*4947cdc7SCole Faust } 66*4947cdc7SCole Faust} 67*4947cdc7SCole Faust 68*4947cdc7SCole Faustfunc TestLambdaVarargsAndKwargsSet(t *testing.T) { 69*4947cdc7SCole Faust resolve.AllowLambda = true 70*4947cdc7SCole Faust source := "f = lambda *args, **kwargs: 0\n" 71*4947cdc7SCole Faust file, err := syntax.Parse("foo.star", source, 0) 72*4947cdc7SCole Faust if err != nil { 73*4947cdc7SCole Faust t.Fatal(err) 74*4947cdc7SCole Faust } 75*4947cdc7SCole Faust if err := resolve.File(file, isPredeclared, isUniversal); err != nil { 76*4947cdc7SCole Faust t.Fatal(err) 77*4947cdc7SCole Faust } 78*4947cdc7SCole Faust lam := file.Stmts[0].(*syntax.AssignStmt).RHS.(*syntax.LambdaExpr).Function.(*resolve.Function) 79*4947cdc7SCole Faust if !lam.HasVarargs { 80*4947cdc7SCole Faust t.Error("HasVarargs not set") 81*4947cdc7SCole Faust } 82*4947cdc7SCole Faust if !lam.HasKwargs { 83*4947cdc7SCole Faust t.Error("HasKwargs not set") 84*4947cdc7SCole Faust } 85*4947cdc7SCole Faust} 86*4947cdc7SCole Faust 87*4947cdc7SCole Faustfunc isPredeclared(name string) bool { return name == "M" } 88*4947cdc7SCole Faust 89*4947cdc7SCole Faustfunc isUniversal(name string) bool { return name == "U" || name == "float" } 90