OLD | NEW |
| (Empty) |
1 // Copyright 2011 Google Inc. All Rights Reserved. | |
2 | |
3 package com.google.dart.compiler.backend.js.analysis; | |
4 | |
5 import com.google.common.collect.Maps; | |
6 | |
7 import junit.framework.TestCase; | |
8 | |
9 import org.mozilla.javascript.Parser; | |
10 import org.mozilla.javascript.Token; | |
11 import org.mozilla.javascript.ast.AstNode; | |
12 import org.mozilla.javascript.ast.AstRoot; | |
13 | |
14 import java.util.ArrayList; | |
15 import java.util.List; | |
16 import java.util.Map; | |
17 | |
18 /** | |
19 * Tests how "top-level" elements are identified in Javascript code. | |
20 */ | |
21 public class TopLevelElementIndexerTest extends TestCase { | |
22 /** | |
23 * Tests that we can find top-level invocations to the RunEntry method to anch
or the analysis. | |
24 */ | |
25 public void testGetEntryPoints() { | |
26 Parser parser = new Parser(); | |
27 AstRoot astRoot = parser.parse("function main() {} RunEntry(main)", "", 1); | |
28 Map<String, List<JavascriptElement>> namesToElements = Maps.newHashMap(); | |
29 List<AstNode> globals = new ArrayList<AstNode>(); | |
30 TopLevelElementIndexer topLevelElementIndexer = | |
31 new TopLevelElementIndexer(namesToElements, globals); | |
32 | |
33 astRoot.visit(topLevelElementIndexer); | |
34 List<AstNode> entryPoints = topLevelElementIndexer.getEntryPoints(); | |
35 assertFalse(entryPoints.isEmpty()); | |
36 | |
37 // Assert that the entry point node is the "RunEntry(main) node. | |
38 assertEquals(astRoot.getLastChild(), entryPoints.get(0)); | |
39 } | |
40 | |
41 /** | |
42 * Tests that we don't find any entry point invocations. | |
43 */ | |
44 public void testGetEntryPointsEmpty() { | |
45 Parser parser = new Parser(); | |
46 AstRoot astRoot = parser.parse("function main() {}", "", 1); | |
47 Map<String, List<JavascriptElement>> namesToElements = Maps.newHashMap(); | |
48 List<AstNode> globals = new ArrayList<AstNode>(); | |
49 TopLevelElementIndexer topLevelElementIndexer = | |
50 new TopLevelElementIndexer(namesToElements, globals); | |
51 astRoot.visit(topLevelElementIndexer); | |
52 List<AstNode> entryPoints = topLevelElementIndexer.getEntryPoints(); | |
53 assertTrue(entryPoints.isEmpty()); | |
54 } | |
55 | |
56 /** | |
57 * Test that we find global symbols. | |
58 */ | |
59 public void testGlobals() { | |
60 Parser parser = new Parser(); | |
61 AstRoot astRoot = parser.parse("if (true) {}", "", 1); | |
62 Map<String, List<JavascriptElement>> namesToElements = Maps.newHashMap(); | |
63 List<AstNode> globals = new ArrayList<AstNode>(); | |
64 TopLevelElementIndexer topLevelElementIndexer = | |
65 new TopLevelElementIndexer(namesToElements, globals); | |
66 astRoot.visit(topLevelElementIndexer); | |
67 | |
68 // if (true) {} should not introduce a top level name and should be a global | |
69 assertTrue(namesToElements.isEmpty()); | |
70 | |
71 assertEquals(1, globals.size()); | |
72 } | |
73 | |
74 /** | |
75 * Checks that instance methods are associated with their parent and that thei
r names appear | |
76 * as fully qualified "A.prototype.Hello" and virtually as "Hello". | |
77 */ | |
78 public void testInstanceFunctions() { | |
79 Parser parser = new Parser(); | |
80 AstRoot astRoot = parser.parse("function A() {} A.prototype.Hello = function
(){}", "", 1); | |
81 Map<String, List<JavascriptElement>> namesToElements = Maps.newHashMap(); | |
82 List<AstNode> globals = new ArrayList<AstNode>(); | |
83 TopLevelElementIndexer topLevelElementIndexer = | |
84 new TopLevelElementIndexer(namesToElements, globals); | |
85 astRoot.visit(topLevelElementIndexer); | |
86 | |
87 assertEquals(0, globals.size()); | |
88 // A, A.prototype.Hello and Hello | |
89 assertEquals(3, namesToElements.size()); | |
90 | |
91 List<JavascriptElement> list = namesToElements.get("A"); | |
92 assertNotNull(list); | |
93 assertEquals(1, list.size()); | |
94 JavascriptElement a = list.get(0); | |
95 assertEquals(1, a.getMembers().size()); | |
96 | |
97 list = namesToElements.get("A.prototype.Hello"); | |
98 assertNotNull(list); | |
99 assertEquals(1, list.size()); | |
100 | |
101 JavascriptElement javascriptElement = list.get(0); | |
102 assertEquals(list.get(0), namesToElements.get("Hello").get(0)); | |
103 | |
104 assertNotNull(javascriptElement); | |
105 assertTrue(javascriptElement.isVirtual()); | |
106 AstNode node = javascriptElement.getNode(); | |
107 assertEquals(Token.EXPR_RESULT, node.getType()); | |
108 assertEquals(a, javascriptElement.getEnclosingElement()); | |
109 } | |
110 | |
111 /** | |
112 * Checks that static functions get associated with their parent. | |
113 */ | |
114 public void testStaticFunctions() { | |
115 Parser parser = new Parser(); | |
116 AstRoot astRoot = parser.parse("function A() {} A.Hello = function(){}", "",
1); | |
117 Map<String, List<JavascriptElement>> namesToElements = Maps.newHashMap(); | |
118 List<AstNode> globals = new ArrayList<AstNode>(); | |
119 TopLevelElementIndexer topLevelElementIndexer = | |
120 new TopLevelElementIndexer(namesToElements, globals); | |
121 astRoot.visit(topLevelElementIndexer); | |
122 | |
123 assertEquals(0, globals.size()); | |
124 assertEquals(2, namesToElements.size()); | |
125 | |
126 List<JavascriptElement> list = namesToElements.get("A"); | |
127 assertNotNull(list); | |
128 assertEquals(1, list.size()); | |
129 JavascriptElement a = list.get(0); | |
130 assertFalse(a.isVirtual()); | |
131 assertEquals(1, a.getMembers().size()); | |
132 | |
133 list = namesToElements.get("A.Hello"); | |
134 assertNotNull(list); | |
135 assertEquals(1, list.size()); | |
136 | |
137 JavascriptElement javascriptElement = list.get(0); | |
138 assertFalse(javascriptElement.isVirtual()); | |
139 | |
140 assertNotNull(javascriptElement); | |
141 AstNode node = javascriptElement.getNode(); | |
142 assertEquals(Token.EXPR_RESULT, node.getType()); | |
143 assertEquals(a, javascriptElement.getEnclosingElement()); | |
144 } | |
145 | |
146 public void testStaticFunctions2() { | |
147 Parser parser = new Parser(); | |
148 AstRoot astRoot = parser.parse("var A = new Object(); A.Hello = function(){}
", "", 1); | |
149 Map<String, List<JavascriptElement>> namesToElements = Maps.newHashMap(); | |
150 List<AstNode> globals = new ArrayList<AstNode>(); | |
151 TopLevelElementIndexer topLevelElementIndexer = | |
152 new TopLevelElementIndexer(namesToElements, globals); | |
153 astRoot.visit(topLevelElementIndexer); | |
154 | |
155 assertEquals(0, globals.size()); | |
156 assertEquals(2, namesToElements.size()); | |
157 | |
158 List<JavascriptElement> list = namesToElements.get("A"); | |
159 assertNotNull(list); | |
160 assertEquals(1, list.size()); | |
161 JavascriptElement a = list.get(0); | |
162 assertFalse(a.isVirtual()); | |
163 assertEquals(1, a.getMembers().size()); | |
164 | |
165 list = namesToElements.get("A.Hello"); | |
166 assertNotNull(list); | |
167 assertEquals(1, list.size()); | |
168 | |
169 JavascriptElement javascriptElement = list.get(0); | |
170 assertFalse(javascriptElement.isVirtual()); | |
171 | |
172 assertNotNull(javascriptElement); | |
173 AstNode node = javascriptElement.getNode(); | |
174 assertEquals(Token.EXPR_RESULT, node.getType()); | |
175 assertEquals(a, javascriptElement.getEnclosingElement()); | |
176 } | |
177 | |
178 public void testTopLevelFunctions() { | |
179 Parser parser = new Parser(); | |
180 AstRoot astRoot = parser.parse("function Hello(){}", "", 1); | |
181 Map<String, List<JavascriptElement>> namesToElements = Maps.newHashMap(); | |
182 List<AstNode> globals = new ArrayList<AstNode>(); | |
183 TopLevelElementIndexer topLevelElementIndexer = | |
184 new TopLevelElementIndexer(namesToElements, globals); | |
185 astRoot.visit(topLevelElementIndexer); | |
186 | |
187 assertEquals(0, globals.size()); | |
188 assertEquals(1, namesToElements.size()); | |
189 | |
190 List<JavascriptElement> list = namesToElements.get("Hello"); | |
191 assertNotNull(list); | |
192 assertEquals(1, list.size()); | |
193 | |
194 JavascriptElement javascriptElement = list.get(0); | |
195 assertNotNull(javascriptElement); | |
196 assertEquals(Token.FUNCTION, javascriptElement.getNode().getType()); | |
197 } | |
198 | |
199 /** | |
200 * Tests that names that appear in a variable declaration map to the same node
if they are in | |
201 * part of the same variable declaration. | |
202 */ | |
203 public void testVariables() { | |
204 Parser parser = new Parser(); | |
205 AstRoot astRoot = parser.parse("var A = 1, B = 2; var C;", "", 1); | |
206 Map<String, List<JavascriptElement>> namesToElements = Maps.newHashMap(); | |
207 List<AstNode> globals = new ArrayList<AstNode>(); | |
208 TopLevelElementIndexer topLevelElementIndexer = | |
209 new TopLevelElementIndexer(namesToElements, globals); | |
210 astRoot.visit(topLevelElementIndexer); | |
211 | |
212 assertEquals(3, namesToElements.size()); | |
213 List<JavascriptElement> a = namesToElements.get("A"); | |
214 List<JavascriptElement> b = namesToElements.get("B"); | |
215 assertEquals(a.get(0).getNode(), b.get(0).getNode()); | |
216 | |
217 List<JavascriptElement> c = namesToElements.get("C"); | |
218 assertEquals(1, c.size()); | |
219 assertNotSame(a.get(0).getNode(), c.get(0).getNode()); | |
220 } | |
221 | |
222 /** | |
223 * Tests that we handle "natives" correctly and that we associate virtual memb
ers with them. | |
224 */ | |
225 public void testNatives() { | |
226 Parser parser = new Parser(); | |
227 AstRoot astRoot = parser.parse("Array.prototype.foo = function() {}", "", 1)
; | |
228 Map<String, List<JavascriptElement>> namesToElements = Maps.newHashMap(); | |
229 List<AstNode> globals = new ArrayList<AstNode>(); | |
230 TopLevelElementIndexer topLevelElementIndexer = | |
231 new TopLevelElementIndexer(namesToElements, globals); | |
232 astRoot.visit(topLevelElementIndexer); | |
233 | |
234 // Array (native), Array.prototype.foo, foo | |
235 assertEquals(3, namesToElements.size()); | |
236 | |
237 List<JavascriptElement> list = namesToElements.get("Array"); | |
238 JavascriptElement javascriptElement = list.get(0); | |
239 assertTrue(javascriptElement.isNative()); | |
240 assertEquals(1, javascriptElement.getMembers().size()); | |
241 | |
242 List<JavascriptElement> staticFoo = namesToElements.get("Array.prototype.foo
"); | |
243 assertEquals(1, staticFoo.size()); | |
244 List<JavascriptElement> virtualFoo = namesToElements.get("foo"); | |
245 assertEquals(1, virtualFoo.size()); | |
246 assertEquals(staticFoo.get(0), virtualFoo.get(0)); | |
247 assertTrue(virtualFoo.get(0).isVirtual()); | |
248 } | |
249 } | |
OLD | NEW |