| 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 |