diff options
Diffstat (limited to 'resolve/testdata/resolve.sky')
-rw-r--r-- | resolve/testdata/resolve.sky | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/resolve/testdata/resolve.sky b/resolve/testdata/resolve.sky new file mode 100644 index 0000000..c48af1c --- /dev/null +++ b/resolve/testdata/resolve.sky @@ -0,0 +1,246 @@ +# Tests of resolver errors. + +# use of declared global +x = 1 +_ = x + +--- +# premature use of global +_ = x ### "undefined: x" +x = 1 + +--- +# use of undefined global +_ = x ### "undefined: x" + +--- +# redeclaration of global +x = 1 +x = 2 ### "cannot reassign global x declared at .*resolve.sky:18:1" + +--- +# redeclaration of predeclared global or built-in + +# This rule permits tool maintainers to add members to the global +# environment without breaking exsiting programs. + +G = 1 # ok +G = 2 ### "cannot reassign global G declared at .*/resolve.sky" + +B = 1 # ok +B = 1 ### "cannot reassign global B declared at .*/resolve.sky" + +--- +# reference to built-in +B() + +--- +# locals may be referenced before they are defined + +def f(): + G(x) # dynamic error + x = 1 + +--- +# Various forms of assignment: + +def f(x): # parameter + G(x) + G(y) ### "undefined: y" + +(a, b) = 1, 2 +G(a) +G(b) +G(c) ### "undefined: c" + +[p, q] = 1, 2 +G(p) +G(q) +G(r) ### "undefined: r" + +--- +# a comprehension introduces a separate lexical block + +_ = [x for x in "abc"] +G(x) ### "undefined: x" + +--- +# Functions may have forward refs. (option:lambda option:nesteddef) +def f(): + g() + h() ### "undefined: h" + def inner(): + i() + i = lambda: 0 + + +def g(): + f() + +--- +# It's permitted to rebind a global using a += assignment. + +x = [1] +x.extend([2]) # ok +x += [3] # ok (a list mutation, not a global rebinding) + +def f(): + x += [4] # x is local to f + +y = 1 +y += 2 # ok (even though it is in fact a global rebinding) + +z += 3 # ok (but fails dynamically because z is undefined) + +--- +def f(a): + if 1==1: + b = 1 + c = 1 + G(a) # ok: param + G(b) # ok: maybe bound local + G(c) # ok: bound local + G(d) # NB: we don't do a use-before-def check on local vars! + G(e) # ok: global + G(f) # ok: global + d = 1 + +e = 1 + +--- +# This program should resolve successfully but fail dynamically. +# However, the Java implementation currently reports the dynamic +# error at the x=2 statement. +x = 1 + +def f(): + G(x) # dynamic error: reference to undefined local + x = 2 + +f() + +--- + +def f(): + load("foo", "bar") ### "load statement within a function" + +load("foo", + "", ### "load: empty identifier" + "_a", ### "load: names with leading underscores are not exported: _a" + b="", ### "load: empty identifier" + c="_d", ### "load: names with leading underscores are not exported: _d" + _e="f") # ok + +--- +# A load() call as an expression statement is converted into a +# load statement, but load is not currently a reserved word. +# TODO(adonovan): clarify the Skylark spec on this issue. + +def load(): # doesn't affect following call + pass + +_ = 1 + load() # ok + +load("foo.sky", "") ### "load: empty identifier" + +--- + +def f(load): + _ = (load, load()) # ok + load("foo.sky", "x") ### "load statement within a function" + +--- +# return, if statements and for loops at top-level are forbidden + +for x in "abc": ### "for loop not within a function" + pass + +if x: ### "if statement not within a function" + pass + +return ### "return statement not within a function" + +--- +# The parser allows any expression on the LHS of an assignment. + +1 = 2 ### "can't assign to literal" +1+2 = 3 ### "can't assign to binaryexpr" +f() = 4 ### "can't assign to callexpr" + +[a, b] = [1, 2] +[a, b] += [3, 4] ### "can't use list expression in augmented assignment" +(a, b) += [3, 4] ### "can't use tuple expression in augmented assignment" +[] = [] ### "can't assign to \\[\\]" +() = () ### "can't assign to ()" + +--- +# break and continue statements must appear within a loop + +break ### "break not in a loop" + +continue ### "continue not in a loop" + +pass + +--- +# No parameters may follow **kwargs + +def f(**kwargs, x): ### `parameter may not follow \*\*kwargs` + pass + +def g(**kwargs, *args): ### `\*args may not follow \*\*kwargs` + pass + +def h(**kwargs1, **kwargs2): ### `multiple \*\*kwargs not allowed` + pass + +--- +# Only **kwargs may follow *args + +def f(*args, x): ### `parameter may not follow \*args` + pass + +def g(*args1, *args2): ### `multiple \*args not allowed` + pass + +def h(*args, **kwargs): # ok + pass + +--- +# No arguments may follow **kwargs +def f(*args, **kwargs): + pass + +f(**{}, 1) ### `argument may not follow \*\*kwargs` +f(**{}, x=1) ### `argument may not follow \*\*kwargs` +f(**{}, *[]) ### `\*args may not follow \*\*kwargs` +f(**{}, **{}) ### `multiple \*\*kwargs not allowed` + +--- +# Only keyword arguments may follow *args +def f(*args, **kwargs): + pass + +f(*[], 1) ### `argument may not follow \*args` +f(*[], a=1) # ok +f(*[], *[]) ### `multiple \*args not allowed` +f(*[], **{}) # ok + +--- +# Parameter names must be unique. + +def f(a, b, a): pass ### "duplicate parameter: a" +def g(args, b, *args): pass ### "duplicate parameter: args" +def h(kwargs, a, **kwargs): pass ### "duplicate parameter: kwargs" +def i(*x, **x): pass ### "duplicate parameter: x" + +--- +# No floating point +a = float("3.141") ### `dialect does not support floating point` +b = 1 / 2 ### `dialect does not support floating point \(use //\)` +c = 3.141 ### `dialect does not support floating point` +--- +# Floating point support (option:float) +a = float("3.141") +b = 1 / 2 +c = 3.141 |