|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 /** |
|
5 * Test that inferring anonymous function information is done correctly. |
|
6 */ |
|
7 |
|
8 function test() { |
|
9 let { Parser, ParserHelpers, SyntaxTreeVisitor } = |
|
10 Cu.import("resource:///modules/devtools/Parser.jsm", {}); |
|
11 |
|
12 function verify(source, predicate, details) { |
|
13 let { name, chain } = details; |
|
14 let [[sline, scol], [eline, ecol]] = details.loc; |
|
15 let ast = Parser.reflectionAPI.parse(source); |
|
16 let node = SyntaxTreeVisitor.filter(ast, predicate).pop(); |
|
17 let info = ParserHelpers.inferFunctionExpressionInfo(node); |
|
18 |
|
19 is(info.name, name, |
|
20 "The function expression assignment property name is correct."); |
|
21 is(chain ? info.chain.toSource() : info.chain, chain ? chain.toSource() : chain, |
|
22 "The function expression assignment property chain is correct."); |
|
23 is(info.loc.start.toSource(), { line: sline, column: scol }.toSource(), |
|
24 "The start location was correct for the identifier in: '" + source + "'."); |
|
25 is(info.loc.end.toSource(), { line: eline, column: ecol }.toSource(), |
|
26 "The end location was correct for the identifier in: '" + source + "'."); |
|
27 } |
|
28 |
|
29 // VariableDeclarator |
|
30 |
|
31 verify("var foo=function(){}", e => e.type == "FunctionExpression", { |
|
32 name: "foo", |
|
33 chain: null, |
|
34 loc: [[1, 4], [1, 7]] |
|
35 }); |
|
36 verify("\nvar\nfoo\n=\nfunction\n(\n)\n{\n}\n", e => e.type == "FunctionExpression", { |
|
37 name: "foo", |
|
38 chain: null, |
|
39 loc: [[3, 0], [3, 3]] |
|
40 }); |
|
41 |
|
42 // AssignmentExpression |
|
43 |
|
44 verify("foo=function(){}", e => e.type == "FunctionExpression", |
|
45 { name: "foo", chain: [], loc: [[1, 0], [1, 3]] }); |
|
46 |
|
47 verify("\nfoo\n=\nfunction\n(\n)\n{\n}\n", e => e.type == "FunctionExpression", |
|
48 { name: "foo", chain: [], loc: [[2, 0], [2, 3]] }); |
|
49 |
|
50 verify("foo.bar=function(){}", e => e.type == "FunctionExpression", |
|
51 { name: "bar", chain: ["foo"], loc: [[1, 0], [1, 7]] }); |
|
52 |
|
53 verify("\nfoo.bar\n=\nfunction\n(\n)\n{\n}\n", e => e.type == "FunctionExpression", |
|
54 { name: "bar", chain: ["foo"], loc: [[2, 0], [2, 7]] }); |
|
55 |
|
56 verify("this.foo=function(){}", e => e.type == "FunctionExpression", |
|
57 { name: "foo", chain: ["this"], loc: [[1, 0], [1, 8]] }); |
|
58 |
|
59 verify("\nthis.foo\n=\nfunction\n(\n)\n{\n}\n", e => e.type == "FunctionExpression", |
|
60 { name: "foo", chain: ["this"], loc: [[2, 0], [2, 8]] }); |
|
61 |
|
62 verify("this.foo.bar=function(){}", e => e.type == "FunctionExpression", |
|
63 { name: "bar", chain: ["this", "foo"], loc: [[1, 0], [1, 12]] }); |
|
64 |
|
65 verify("\nthis.foo.bar\n=\nfunction\n(\n)\n{\n}\n", e => e.type == "FunctionExpression", |
|
66 { name: "bar", chain: ["this", "foo"], loc: [[2, 0], [2, 12]] }); |
|
67 |
|
68 verify("foo.this.bar=function(){}", e => e.type == "FunctionExpression", |
|
69 { name: "bar", chain: ["foo", "this"], loc: [[1, 0], [1, 12]] }); |
|
70 |
|
71 verify("\nfoo.this.bar\n=\nfunction\n(\n)\n{\n}\n", e => e.type == "FunctionExpression", |
|
72 { name: "bar", chain: ["foo", "this"], loc: [[2, 0], [2, 12]] }); |
|
73 |
|
74 // ObjectExpression |
|
75 |
|
76 verify("({foo:function(){}})", e => e.type == "FunctionExpression", |
|
77 { name: "foo", chain: [], loc: [[1, 2], [1, 5]] }); |
|
78 |
|
79 verify("(\n{\nfoo\n:\nfunction\n(\n)\n{\n}\n}\n)", e => e.type == "FunctionExpression", |
|
80 { name: "foo", chain: [], loc: [[3, 0], [3, 3]] }); |
|
81 |
|
82 verify("({foo:{bar:function(){}}})", e => e.type == "FunctionExpression", |
|
83 { name: "bar", chain: ["foo"], loc: [[1, 7], [1, 10]] }); |
|
84 |
|
85 verify("(\n{\nfoo\n:\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n}\n)", e => e.type == "FunctionExpression", |
|
86 { name: "bar", chain: ["foo"], loc: [[6, 0], [6, 3]] }); |
|
87 |
|
88 // AssignmentExpression + ObjectExpression |
|
89 |
|
90 verify("foo={bar:function(){}}", e => e.type == "FunctionExpression", |
|
91 { name: "bar", chain: ["foo"], loc: [[1, 5], [1, 8]] }); |
|
92 |
|
93 verify("\nfoo\n=\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n", e => e.type == "FunctionExpression", |
|
94 { name: "bar", chain: ["foo"], loc: [[5, 0], [5, 3]] }); |
|
95 |
|
96 verify("foo={bar:{baz:function(){}}}", e => e.type == "FunctionExpression", |
|
97 { name: "baz", chain: ["foo", "bar"], loc: [[1, 10], [1, 13]] }); |
|
98 |
|
99 verify("\nfoo\n=\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n", e => e.type == "FunctionExpression", |
|
100 { name: "baz", chain: ["foo", "bar"], loc: [[8, 0], [8, 3]] }); |
|
101 |
|
102 verify("nested.foo={bar:function(){}}", e => e.type == "FunctionExpression", |
|
103 { name: "bar", chain: ["nested", "foo"], loc: [[1, 12], [1, 15]] }); |
|
104 |
|
105 verify("\nnested.foo\n=\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n", e => e.type == "FunctionExpression", |
|
106 { name: "bar", chain: ["nested", "foo"], loc: [[5, 0], [5, 3]] }); |
|
107 |
|
108 verify("nested.foo={bar:{baz:function(){}}}", e => e.type == "FunctionExpression", |
|
109 { name: "baz", chain: ["nested", "foo", "bar"], loc: [[1, 17], [1, 20]] }); |
|
110 |
|
111 verify("\nnested.foo\n=\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n", e => e.type == "FunctionExpression", |
|
112 { name: "baz", chain: ["nested", "foo", "bar"], loc: [[8, 0], [8, 3]] }); |
|
113 |
|
114 verify("this.foo={bar:function(){}}", e => e.type == "FunctionExpression", |
|
115 { name: "bar", chain: ["this", "foo"], loc: [[1, 10], [1, 13]] }); |
|
116 |
|
117 verify("\nthis.foo\n=\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n", e => e.type == "FunctionExpression", |
|
118 { name: "bar", chain: ["this", "foo"], loc: [[5, 0], [5, 3]] }); |
|
119 |
|
120 verify("this.foo={bar:{baz:function(){}}}", e => e.type == "FunctionExpression", |
|
121 { name: "baz", chain: ["this", "foo", "bar"], loc: [[1, 15], [1, 18]] }); |
|
122 |
|
123 verify("\nthis.foo\n=\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n", e => e.type == "FunctionExpression", |
|
124 { name: "baz", chain: ["this", "foo", "bar"], loc: [[8, 0], [8, 3]] }); |
|
125 |
|
126 verify("this.nested.foo={bar:function(){}}", e => e.type == "FunctionExpression", |
|
127 { name: "bar", chain: ["this", "nested", "foo"], loc: [[1, 17], [1, 20]] }); |
|
128 |
|
129 verify("\nthis.nested.foo\n=\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n", e => e.type == "FunctionExpression", |
|
130 { name: "bar", chain: ["this", "nested", "foo"], loc: [[5, 0], [5, 3]] }); |
|
131 |
|
132 verify("this.nested.foo={bar:{baz:function(){}}}", e => e.type == "FunctionExpression", |
|
133 { name: "baz", chain: ["this", "nested", "foo", "bar"], loc: [[1, 22], [1, 25]] }); |
|
134 |
|
135 verify("\nthis.nested.foo\n=\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n", e => e.type == "FunctionExpression", |
|
136 { name: "baz", chain: ["this", "nested", "foo", "bar"], loc: [[8, 0], [8, 3]] }); |
|
137 |
|
138 verify("nested.this.foo={bar:function(){}}", e => e.type == "FunctionExpression", |
|
139 { name: "bar", chain: ["nested", "this", "foo"], loc: [[1, 17], [1, 20]] }); |
|
140 |
|
141 verify("\nnested.this.foo\n=\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n", e => e.type == "FunctionExpression", |
|
142 { name: "bar", chain: ["nested", "this", "foo"], loc: [[5, 0], [5, 3]] }); |
|
143 |
|
144 verify("nested.this.foo={bar:{baz:function(){}}}", e => e.type == "FunctionExpression", |
|
145 { name: "baz", chain: ["nested", "this", "foo", "bar"], loc: [[1, 22], [1, 25]] }); |
|
146 |
|
147 verify("\nnested.this.foo\n=\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n", e => e.type == "FunctionExpression", |
|
148 { name: "baz", chain: ["nested", "this", "foo", "bar"], loc: [[8, 0], [8, 3]] }); |
|
149 |
|
150 // VariableDeclarator + AssignmentExpression + ObjectExpression |
|
151 |
|
152 verify("let foo={bar:function(){}}", e => e.type == "FunctionExpression", |
|
153 { name: "bar", chain: ["foo"], loc: [[1, 9], [1, 12]] }); |
|
154 |
|
155 verify("\nlet\nfoo\n=\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n", e => e.type == "FunctionExpression", |
|
156 { name: "bar", chain: ["foo"], loc: [[6, 0], [6, 3]] }); |
|
157 |
|
158 verify("let foo={bar:{baz:function(){}}}", e => e.type == "FunctionExpression", |
|
159 { name: "baz", chain: ["foo", "bar"], loc: [[1, 14], [1, 17]] }); |
|
160 |
|
161 verify("\nlet\nfoo\n=\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n", e => e.type == "FunctionExpression", |
|
162 { name: "baz", chain: ["foo", "bar"], loc: [[9, 0], [9, 3]] }); |
|
163 |
|
164 // New/CallExpression + AssignmentExpression + ObjectExpression |
|
165 |
|
166 verify("foo({bar:function(){}})", e => e.type == "FunctionExpression", |
|
167 { name: "bar", chain: [], loc: [[1, 5], [1, 8]] }); |
|
168 |
|
169 verify("\nfoo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
170 { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); |
|
171 |
|
172 verify("foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", |
|
173 { name: "baz", chain: ["bar"], loc: [[1, 10], [1, 13]] }); |
|
174 |
|
175 verify("\nfoo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
176 { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); |
|
177 |
|
178 verify("nested.foo({bar:function(){}})", e => e.type == "FunctionExpression", |
|
179 { name: "bar", chain: [], loc: [[1, 12], [1, 15]] }); |
|
180 |
|
181 verify("\nnested.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
182 { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); |
|
183 |
|
184 verify("nested.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", |
|
185 { name: "baz", chain: ["bar"], loc: [[1, 17], [1, 20]] }); |
|
186 |
|
187 verify("\nnested.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
188 { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); |
|
189 |
|
190 verify("this.foo({bar:function(){}})", e => e.type == "FunctionExpression", |
|
191 { name: "bar", chain: [], loc: [[1, 10], [1, 13]] }); |
|
192 |
|
193 verify("\nthis.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
194 { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); |
|
195 |
|
196 verify("this.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", |
|
197 { name: "baz", chain: ["bar"], loc: [[1, 15], [1, 18]] }); |
|
198 |
|
199 verify("\nthis.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
200 { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); |
|
201 |
|
202 verify("this.nested.foo({bar:function(){}})", e => e.type == "FunctionExpression", |
|
203 { name: "bar", chain: [], loc: [[1, 17], [1, 20]] }); |
|
204 |
|
205 verify("\nthis.nested.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
206 { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); |
|
207 |
|
208 verify("this.nested.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", |
|
209 { name: "baz", chain: ["bar"], loc: [[1, 22], [1, 25]] }); |
|
210 |
|
211 verify("\nthis.nested.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
212 { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); |
|
213 |
|
214 verify("nested.this.foo({bar:function(){}})", e => e.type == "FunctionExpression", |
|
215 { name: "bar", chain: [], loc: [[1, 17], [1, 20]] }); |
|
216 |
|
217 verify("\nnested.this.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
218 { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); |
|
219 |
|
220 verify("nested.this.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", |
|
221 { name: "baz", chain: ["bar"], loc: [[1, 22], [1, 25]] }); |
|
222 |
|
223 verify("\nnested.this.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
224 { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); |
|
225 |
|
226 // New/CallExpression + VariableDeclarator + AssignmentExpression + ObjectExpression |
|
227 |
|
228 verify("let target=foo({bar:function(){}})", e => e.type == "FunctionExpression", |
|
229 { name: "bar", chain: ["target"], loc: [[1, 16], [1, 19]] }); |
|
230 |
|
231 verify("\nlet\ntarget=\nfoo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
232 { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); |
|
233 |
|
234 verify("let target=foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", |
|
235 { name: "baz", chain: ["target", "bar"], loc: [[1, 21], [1, 24]] }); |
|
236 |
|
237 verify("\nlet\ntarget=\nfoo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
238 { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); |
|
239 |
|
240 verify("let target=nested.foo({bar:function(){}})", e => e.type == "FunctionExpression", |
|
241 { name: "bar", chain: ["target"], loc: [[1, 23], [1, 26]] }); |
|
242 |
|
243 verify("\nlet\ntarget=\nnested.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
244 { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); |
|
245 |
|
246 verify("let target=nested.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", |
|
247 { name: "baz", chain: ["target", "bar"], loc: [[1, 28], [1, 31]] }); |
|
248 |
|
249 verify("\nlet\ntarget=\nnested.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
250 { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); |
|
251 |
|
252 verify("let target=this.foo({bar:function(){}})", e => e.type == "FunctionExpression", |
|
253 { name: "bar", chain: ["target"], loc: [[1, 21], [1, 24]] }); |
|
254 |
|
255 verify("\nlet\ntarget=\nthis.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
256 { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); |
|
257 |
|
258 verify("let target=this.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", |
|
259 { name: "baz", chain: ["target", "bar"], loc: [[1, 26], [1, 29]] }); |
|
260 |
|
261 verify("\nlet\ntarget=\nthis.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
262 { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); |
|
263 |
|
264 verify("let target=this.nested.foo({bar:function(){}})", e => e.type == "FunctionExpression", |
|
265 { name: "bar", chain: ["target"], loc: [[1, 28], [1, 31]] }); |
|
266 |
|
267 verify("\nlet\ntarget=\nthis.nested.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
268 { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); |
|
269 |
|
270 verify("let target=this.nested.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", |
|
271 { name: "baz", chain: ["target", "bar"], loc: [[1, 33], [1, 36]] }); |
|
272 |
|
273 verify("\nlet\ntarget=\nthis.nested.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
274 { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); |
|
275 |
|
276 verify("let target=nested.this.foo({bar:function(){}})", e => e.type == "FunctionExpression", |
|
277 { name: "bar", chain: ["target"], loc: [[1, 28], [1, 31]] }); |
|
278 |
|
279 verify("\nlet\ntarget=\nnested.this.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
280 { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); |
|
281 |
|
282 verify("let target=nested.this.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", |
|
283 { name: "baz", chain: ["target", "bar"], loc: [[1, 33], [1, 36]] }); |
|
284 |
|
285 verify("\nlet\ntarget=\nnested.this.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", |
|
286 { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); |
|
287 |
|
288 finish(); |
|
289 } |