Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: compiler/java/com/google/dart/compiler/backend/js/analysis/TopLevelElementIndexer.java

Issue 9479013: Remove backends. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: More clean up Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 package com.google.dart.compiler.backend.js.analysis;
6
7 import org.mozilla.javascript.Token;
8 import org.mozilla.javascript.ast.Assignment;
9 import org.mozilla.javascript.ast.AstNode;
10 import org.mozilla.javascript.ast.ExpressionStatement;
11 import org.mozilla.javascript.ast.FunctionCall;
12 import org.mozilla.javascript.ast.FunctionNode;
13 import org.mozilla.javascript.ast.Name;
14 import org.mozilla.javascript.ast.NodeVisitor;
15 import org.mozilla.javascript.ast.VariableDeclaration;
16 import org.mozilla.javascript.ast.VariableInitializer;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Deque;
21 import java.util.Iterator;
22 import java.util.LinkedList;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Map.Entry;
26 import java.util.Set;
27
28 /**
29 * Indexes the top level declarations and expressions contained in a JavaScript AST tree. Where top
30 * level expressions can be global variables, method definitions or invocations. Note that method
31 * bodies are not processed.
32 */
33 class TopLevelElementIndexer implements NodeVisitor {
34 /**
35 *
36 */
37 private static final String RUN_ENTRY_METHOD_NAME = "RunEntry";
38
39 /**
40 * Collects {@link Name} {@link AstNode}s.
41 */
42 static class NameLocator implements NodeVisitor {
43 private static final int PROTOTYPE_DEFAULT_INDEX = -1;
44 private final Deque<String> identifiers = new LinkedList<String>();
45 private int prototypeIndex = PROTOTYPE_DEFAULT_INDEX;
46
47 public String getEnclosingTypeName() {
48 return identifiers.getFirst();
49 }
50
51 public String getName() {
52 return identifiers.getLast();
53 }
54
55 public Collection<String> getPossibleNames() {
56 List<String> names = new ArrayList<String>(2);
57 if (hasPrototypeInName()) {
58 names.add(identifiers.getLast());
59 }
60 names.add(getQualifiedName());
61 return names;
62 }
63
64 public String getQualifiedName() {
65 StringBuffer sb = new StringBuffer();
66 Iterator<String> iterator = identifiers.iterator();
67 while (iterator.hasNext()) {
68 sb.append(iterator.next());
69 if (iterator.hasNext()) {
70 sb.append(".");
71 }
72 }
73 return sb.toString();
74 }
75
76 public boolean hasPrototypeInName() {
77 return prototypeIndex != PROTOTYPE_DEFAULT_INDEX;
78 }
79
80 @Override
81 public boolean visit(AstNode node) {
82 if (node.getType() == Token.NAME) {
83 Name name = (Name) node;
84 String identifier = name.getIdentifier();
85 if ("prototype".equals(identifier)) {
86 prototypeIndex = identifiers.size();
87 }
88 identifiers.add(identifier);
89 }
90 return true;
91 }
92 }
93
94 public static void printGlobals(List<AstNode> globals) {
95 System.out.println("Globals");
96 for (AstNode global : globals) {
97 System.out.println("--------");
98 System.out.println(global.toSource());
99 System.out.println();
100 }
101 }
102
103 public static void printNamesToElements(Map<String, List<JavascriptElement>> n amesToElements) {
104 long rttCost = 0;
105 long namedCost = 0;
106 long ctorCost = 0;
107
108 Set<Entry<String, List<JavascriptElement>>> entrySet = namesToElements.entry Set();
109 for (Entry<String, List<JavascriptElement>> entry : entrySet) {
110 System.out.println("--------");
111 System.out.println("Name: " + entry.getKey());
112 for (JavascriptElement javascriptElement : entry.getValue()) {
113 AstNode node = javascriptElement.getNode();
114 if (node == null) {
115 continue;
116 }
117
118 System.out.println("Type: " + Token.typeToName(node.getType()));
119 if (javascriptElement.getInheritsElement() != null) {
120 System.out.println("Inherits: " + javascriptElement.getInheritsElement ());
121 }
122
123 try {
124 System.out.println(node.toSource());
125 } catch (Exception e) {
126 System.out.println("Failed to print node source code");
127 }
128
129 String name = javascriptElement.getName();
130 if (name.endsWith("$named")) {
131 namedCost += node.getLength();
132 } else if (name.endsWith("$addTo") || name.endsWith("$lookupRTT")
133 || name.endsWith("$RTTimplements")) {
134 rttCost += node.getLength();
135 } else if (name.endsWith("$Constructor") || name.endsWith("$Initializer" )) {
136 ctorCost += node.getLength();
137 }
138 }
139 System.out.println();
140 }
141
142 System.out.println(ctorCost +
143 " characters worth of $Constructor and $Initializer methode declarations ");
144 System.out.println(namedCost + " characters worth of $named methods declarat ions");
145 System.out.println(rttCost + " characters worth of RTT method declarations") ;
146 }
147
148 private final List<AstNode> entryPoints = new ArrayList<AstNode>();
149 private final List<AstNode> globals;
150
151 private final Map<String, List<JavascriptElement>> namesToElements;
152
153 public TopLevelElementIndexer(Map<String, List<JavascriptElement>> namesToElem ents,
154 List<AstNode> globals) {
155 this.globals = globals;
156 this.namesToElements = namesToElements;
157 }
158
159 private void addElement(String identifier, JavascriptElement javascriptElement ) {
160 List<JavascriptElement> list = namesToElements.get(identifier);
161 if (list == null) {
162 list = new ArrayList<JavascriptElement>(1);
163 namesToElements.put(identifier, list);
164 }
165 list.add(javascriptElement);
166 }
167
168 /**
169 * Processes an AST node that does not define a method. If the node is an inv ocation to a
170 * RunEntry method or an inherits method update the entry points and element i nheritance
171 * hierarchy accordingly. Otherwise we just add this node to the globals bloc k and continue.
172 */
173 private void processGlobal(AstNode node) {
174 if (node.getType() == Token.EXPR_RESULT) {
175 ExpressionStatement expressionStatement = (ExpressionStatement) node;
176 AstNode expression = expressionStatement.getExpression();
177 if (expression.getType() == Token.CALL) {
178 FunctionCall functionCall = (FunctionCall) expression;
179 AstNode target = functionCall.getTarget();
180 if (target.getType() == Token.NAME) {
181 Name targetName = (Name) target;
182 if (RUN_ENTRY_METHOD_NAME.equals(targetName.getIdentifier())) {
183 // This is a call to an entry point so add it to the known set of en try points.
184 entryPoints.add(node);
185 return;
186 } else if ("$inherits".equals(targetName.getIdentifier())) {
187 // This is an inherits call so update the element's inheritance hier archy.
188 List<AstNode> arguments = functionCall.getArguments();
189 assert (arguments.size() == 2);
190 assert (arguments.get(0).getType() == Token.NAME);
191 assert (arguments.get(1).getType() == Token.NAME);
192 Name subtype = (Name) arguments.get(0);
193 Name supertype = (Name) arguments.get(1);
194 List<JavascriptElement> subTypeFunctions = namesToElements.get(subty pe.getIdentifier());
195 assert (subTypeFunctions != null && subTypeFunctions.size() == 1);
196 JavascriptElement subtypeFunction = subTypeFunctions.get(0);
197 subtypeFunction.setInheritsNode(node);
198 subtypeFunction.setInherits(namesToElements.get(supertype.getIdentif ier()).get(0));
199 return;
200 }
201 }
202 }
203 }
204
205 globals.add(node);
206 }
207
208 public List<AstNode> getEntryPoints() {
209 return entryPoints;
210 }
211
212 @Override
213 public boolean visit(AstNode node) {
214 if (node == node.getAstRoot()) {
215 return true;
216 }
217
218 switch (node.getType()) {
219 case Token.EXPR_VOID:
220 case Token.EXPR_RESULT:
221 ExpressionStatement expressionStatement = (ExpressionStatement) node;
222 AstNode expression = expressionStatement.getExpression();
223 if (expression.getType() == Token.ASSIGN) {
224 Assignment assignment = (Assignment) expression;
225 NameLocator nameLocator = new NameLocator();
226 assignment.getLeft().visit(nameLocator);
227 String enclosingTypeName = nameLocator.getEnclosingTypeName();
228 JavascriptElement enclosingElement = null;
229 if (enclosingTypeName != null) {
230 List<JavascriptElement> list = namesToElements.get(enclosingTypeName );
231 if (list == null) {
232 // TODO: Assume that this is a native object for now, we could hav e a whitelist of
233 // native objects if we wanted to.
234 enclosingElement =
235 new JavascriptElement(null, false, enclosingTypeName, nameLoca tor.getName(),
236 null);
237 addElement(enclosingTypeName, enclosingElement);
238 } else {
239 assert (list != null && list.size() == 1);
240 enclosingElement = list.get(0);
241 }
242 }
243
244 JavascriptElement javascriptElement =
245 new JavascriptElement(enclosingElement, nameLocator.hasPrototypeIn Name(),
246 nameLocator.getQualifiedName(), nameLocator.getName(), node);
247 for (String identifier : nameLocator.getPossibleNames()) {
248 addElement(identifier, javascriptElement);
249 }
250 } else {
251 processGlobal(node);
252 }
253 break;
254
255 case Token.FUNCTION:
256 FunctionNode functionNode = (FunctionNode) node;
257 String name = functionNode.getName();
258 if (name != null && !name.isEmpty()) {
259 addElement(name, new JavascriptElement(null, false, name, name, node)) ;
260 }
261 break;
262
263 case Token.VAR:
264 VariableDeclaration variableDeclaration = (VariableDeclaration) node;
265 List<VariableInitializer> variables = variableDeclaration.getVariables() ;
266 for (VariableInitializer variable : variables) {
267 AstNode target = variable.getTarget();
268 if (target.getType() == Token.NAME) {
269 Name variableName = (Name) target;
270 addElement(variableName.getIdentifier(), new JavascriptElement(null, false,
271 variableName.getIdentifier(), variableName.getIdentifier(), node ));
272 }
273 }
274 break;
275
276 default:
277 processGlobal(node);
278 break;
279 }
280
281 return false;
282 }
283 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698