1
+ # Strict Early Errors
2
+ # -------------------
3
+
4
+ # The following are prohibited under ES5's `strict` mode
5
+ # * `Octal Integer Literals`
6
+ # * `Octal Escape Sequences`
7
+ # * duplicate property definitions in `Object Literal`s
8
+ # * duplicate formal parameter
9
+ # * `delete` operand is a variable
10
+ # * `delete` operand is a parameter
11
+ # * `delete` operand is `undefined`
12
+ # * `Future Reserved Word`s as identifiers: implements, interface, let, package, private, protected, public, static, yield
13
+ # * `eval` or `arguments` as `catch` identifier
14
+ # * `eval` or `arguments` as formal parameter
15
+ # * `eval` or `arguments` as function declaration identifier
16
+ # * `eval` or `arguments` as LHS of assignment
17
+ # * `eval` or `arguments` as the operand of a post/pre-fix inc/dec-rement expression
18
+
19
+ # helper to assert that code complies with strict prohibitions
20
+ strict = (code , msg ) ->
21
+ throws (-> CoffeeScript .compile code), null , msg
22
+ strictOk = (code , msg ) ->
23
+ doesNotThrow (-> CoffeeScript .compile code), msg
24
+
25
+
26
+ test " Octal Integer Literals prohibited" , ->
27
+ strict ' n = 01'
28
+ strict ' n = 07777'
29
+ strictOk ' n = 09'
30
+ strictOk ' n = 079'
31
+ strictOk ' n = `01`'
32
+
33
+ test " Octal Escape Sequences prohibited" , ->
34
+ strict ' e = "\\ 01"'
35
+ strict ' e = "\\ 0777"'
36
+ strictOk ' e = "\\ 09"'
37
+ strictOk ' e = "\\ 07777"'
38
+ strictOk " e = `'\033 [0;1m'`"
39
+
40
+ test " duplicate property definitions in `Object Literal`s are prohibited" , ->
41
+ strict ' o = {x:1,x:1}'
42
+ strict ' x = 1; o = {x, x: 2}'
43
+
44
+ test " duplicate formal parameter are prohibited" , ->
45
+ nonce = {}
46
+
47
+ # a Param can be an Identifier, ThisProperty( @-param ), Array, or Object
48
+ # a Param can also be a splat (...) or an assignment (param=value)
49
+ # the following function expressions should throw errors
50
+ strict ' (_,_)->' , ' param, param'
51
+ strict ' (_,@_)->' , ' param, @param'
52
+ strict ' (_,_...)->' , ' param, param...'
53
+ strict ' (@_,_...)->' , ' @param, param...'
54
+ strict ' (_,_ = true)->' , ' param, param='
55
+ strict ' (@_,@_)->' , ' two @params'
56
+ strict ' (_,@_ = true)->' , ' param, @param='
57
+ strict ' (_,{_})->' , ' param, {param}'
58
+ strict ' (@_,{_})->' , ' @param, {param}'
59
+ strict ' ({_,_})->' , ' {param, param}'
60
+ strict ' ({_,@_})->' , ' {param, @param}'
61
+ strict ' (_,[_])->' , ' param, [param]'
62
+ strict ' ([_,_])->' , ' [param, param]'
63
+ strict ' ([_,@_])->' , ' [param, @param]'
64
+ strict ' (_,[_]=true)->' , ' param, [param]='
65
+ strict ' (_,[@_,{_}])->' , ' param, [@param, {param}]'
66
+ strict ' (_,[_,{@_}])->' , ' param, [param, {@param}]'
67
+ strict ' (_,[_,{_}])->' , ' param, [param, {param}]'
68
+ strict ' (_,[_,{__}])->' , ' param, [param, {param2}]'
69
+ strict ' (_,[__,{_}])->' , ' param, [param2, {param}]'
70
+ strict ' (__,[_,{_}])->' , ' param, [param2, {param2}]'
71
+ # the following function expressions should **not** throw errors
72
+ strictOk ' ({},_arg)->'
73
+ strictOk ' ({},{})->'
74
+ strictOk ' ([]...,_arg)->'
75
+ strictOk ' ({}...,_arg)->'
76
+ strictOk ' ({}...,[],_arg)->'
77
+ strictOk ' ([]...,{},_arg)->'
78
+ strictOk ' (@case,_case)->'
79
+ strictOk ' (@case,_case...)->'
80
+ strictOk ' (@case...,_case)->'
81
+ strictOk ' (_case,@case)->'
82
+ strictOk ' (_case,@case...)->'
83
+
84
+ test " `delete` operand is a var is prohibited" , ->
85
+ strict ' a = 1; delete a'
86
+ strictOk ' delete a' # noop
87
+
88
+ test " `delete` operand is a parameter is prohibited" , ->
89
+ strict ' (a) -> delete a'
90
+ strict ' (@a) -> delete a'
91
+ strict ' (a...) -> delete a'
92
+ strict ' (a = 1) -> delete a'
93
+ strict ' ([a]) -> delete a'
94
+ strict ' ({a}) -> delete a'
95
+
96
+ test " `Future Reserved Word`s as identifiers prohibited" , ->
97
+ futures = ' implements interface let package private protected public static yield' .split ' '
98
+ for keyword in futures
99
+ strict " #{ keyword} = 1"
100
+ strict " class #{ keyword} "
101
+ strict " try new Error catch #{ keyword} "
102
+ strict " (#{ keyword} ) ->"
103
+ strict " {keyword}++"
104
+ strict " ++{keyword}"
105
+ strict " {keyword}--"
106
+ strict " --{keyword}"
107
+
108
+ test " `eval` and `arguments` use restricted" , ->
109
+ proscribeds = ' eval arguments' .split ' '
110
+ for proscribed in proscribeds
111
+ strict " #{ proscribed} = 1"
112
+ strict " class #{ proscribed} "
113
+ strict " try new Error catch #{ proscribed} "
114
+ strict " (#{ proscribed} ) ->"
115
+ strict " {proscribed}++"
116
+ strict " ++{proscribed}"
117
+ strict " {proscribed}--"
118
+ strict " --{proscribed}"
119
+ strictOk " eval 'true'"
120
+ strictOk " -> arguments[0]"
121
+
122
+
123
+
124
+
0 commit comments