1 | // Copyright (C) 2008 Google Inc. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | package com.google.caja.parser.quasiliteral.opt; |
16 | |
17 | import java.util.Iterator; |
18 | |
19 | import com.google.caja.parser.AncestorChain; |
20 | import com.google.caja.parser.js.Identifier; |
21 | import com.google.caja.util.CajaTestCase; |
22 | import com.google.caja.util.Join; |
23 | |
24 | public class ScopeTreeTest extends CajaTestCase { |
25 | public final void testConstructor() throws Exception { |
26 | ScopeTree t = ScopeTree.create(AncestorChain.instance(js(fromString( |
27 | "" |
28 | + "function foo(j) {\n" |
29 | + " var i = 0;\n" |
30 | + " return j + 1;\n" |
31 | + "}\n" |
32 | + "try {\n" |
33 | + " var bar = (function () {\n" |
34 | + " var i = 0;\n" |
35 | + " function bar() {\n" |
36 | + " return ++i;\n" |
37 | + " }\n" |
38 | + " return bar;\n" |
39 | + " })();\n" |
40 | + "} catch (ex) {\n" |
41 | + " panic(ex);\n" |
42 | + "}\n" |
43 | )))); |
44 | assertEquals( |
45 | "" |
46 | + "(ScopeTree Block\n" |
47 | + " (ScopeTree function foo)\n" |
48 | + " (ScopeTree function\n" |
49 | + " (ScopeTree function bar))\n" |
50 | + " (ScopeTree CatchStmt))", |
51 | t.toString()); |
52 | } |
53 | |
54 | public final void testUsesOf() throws Exception { |
55 | ScopeTree t = ScopeTree.create(AncestorChain.instance(js(fromString( |
56 | "" |
57 | + "for (var i = 0; i < 1000; i++) alert('annoying innit');\n" |
58 | + "var counter = (function () {\n" |
59 | + " var i = -1;\n" |
60 | + " return function () { return ++i; };\n" |
61 | + "})();")))); |
62 | ScopeTree f1 = t.children().get(0); |
63 | ScopeTree f2 = f1.children().get(0); |
64 | Iterator<AncestorChain<Identifier>> uses; |
65 | |
66 | // No uses |
67 | uses = f2.usesOf("j").iterator(); |
68 | assertFalse(uses.hasNext()); |
69 | |
70 | // Includes uses from the declaring scope, but not masked declarations from |
71 | // the global scope. |
72 | uses = f2.usesOf("i").iterator(); |
73 | assertTrue(uses.hasNext()); |
74 | assertEquals( |
75 | Join.join( |
76 | "\n", |
77 | "Block", |
78 | " Declaration", |
79 | " SpecialOperation : FUNCTION_CALL", |
80 | " FunctionConstructor", |
81 | " Block", |
82 | " Declaration", |
83 | " Identifier : i"), |
84 | uses.next().toString()); |
85 | assertTrue(uses.hasNext()); |
86 | assertEquals( |
87 | Join.join( |
88 | "\n", |
89 | "Block", |
90 | " Declaration", |
91 | " SpecialOperation : FUNCTION_CALL", |
92 | " FunctionConstructor", |
93 | " Block", |
94 | " ReturnStmt", |
95 | " FunctionConstructor", |
96 | " Block", |
97 | " ReturnStmt", |
98 | " AssignOperation : PRE_INCREMENT", |
99 | " Reference", |
100 | " Identifier : i"), |
101 | uses.next().toString()); |
102 | assertFalse(uses.hasNext()); |
103 | |
104 | // Does not include declarations in sub-scopes where the declaration is |
105 | // redefined. |
106 | // for (var i = 0; i < 1000; i++) alert('annoying innit'); |
107 | uses = t.usesOf("i").iterator(); |
108 | assertTrue(uses.hasNext()); |
109 | assertEquals( |
110 | Join.join( |
111 | "\n", |
112 | "Block", |
113 | " ForLoop : ", |
114 | " Declaration", |
115 | " Identifier : i"), |
116 | uses.next().toString()); |
117 | assertTrue(uses.hasNext()); |
118 | assertEquals( |
119 | Join.join( |
120 | "\n", |
121 | "Block", |
122 | " ForLoop : ", |
123 | " SimpleOperation : LESS_THAN", |
124 | " Reference", |
125 | " Identifier : i"), |
126 | uses.next().toString()); |
127 | assertTrue(uses.hasNext()); |
128 | assertEquals( |
129 | Join.join( |
130 | "\n", |
131 | "Block", |
132 | " ForLoop : ", |
133 | " ExpressionStmt", |
134 | " AssignOperation : POST_INCREMENT", |
135 | " Reference", |
136 | " Identifier : i"), |
137 | uses.next().toString()); |
138 | assertFalse(uses.hasNext()); |
139 | } |
140 | } |