aboutsummaryrefslogtreecommitdiff
path: root/resolve/testdata/resolve.sky
diff options
context:
space:
mode:
Diffstat (limited to 'resolve/testdata/resolve.sky')
-rw-r--r--resolve/testdata/resolve.sky246
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