]> git.saurik.com Git - apple/javascriptcore.git/blob - parser/ASTBuilder.h
JavaScriptCore-1097.13.tar.gz
[apple/javascriptcore.git] / parser / ASTBuilder.h
1 /*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #ifndef ASTBuilder_h
27 #define ASTBuilder_h
28
29 #include "NodeConstructors.h"
30 #include "SyntaxChecker.h"
31 #include <utility>
32
33 namespace JSC {
34
35 class ASTBuilder {
36 struct BinaryOpInfo {
37 BinaryOpInfo() {}
38 BinaryOpInfo(int s, int d, int e, bool r)
39 : start(s)
40 , divot(d)
41 , end(e)
42 , hasAssignment(r)
43 {
44 }
45 BinaryOpInfo(const BinaryOpInfo& lhs, const BinaryOpInfo& rhs)
46 : start(lhs.start)
47 , divot(rhs.start)
48 , end(rhs.end)
49 , hasAssignment(lhs.hasAssignment || rhs.hasAssignment)
50 {
51 }
52 int start;
53 int divot;
54 int end;
55 bool hasAssignment;
56 };
57
58
59 struct AssignmentInfo {
60 AssignmentInfo() {}
61 AssignmentInfo(ExpressionNode* node, int start, int divot, int initAssignments, Operator op)
62 : m_node(node)
63 , m_start(start)
64 , m_divot(divot)
65 , m_initAssignments(initAssignments)
66 , m_op(op)
67 {
68 }
69 ExpressionNode* m_node;
70 int m_start;
71 int m_divot;
72 int m_initAssignments;
73 Operator m_op;
74 };
75 public:
76 ASTBuilder(JSGlobalData* globalData, SourceCode* sourceCode)
77 : m_globalData(globalData)
78 , m_sourceCode(sourceCode)
79 , m_scope(globalData)
80 , m_evalCount(0)
81 {
82 }
83
84 struct BinaryExprContext {
85 BinaryExprContext(ASTBuilder&) {}
86 };
87 struct UnaryExprContext {
88 UnaryExprContext(ASTBuilder&) {}
89 };
90
91 typedef SyntaxChecker FunctionBodyBuilder;
92
93 typedef ExpressionNode* Expression;
94 typedef JSC::SourceElements* SourceElements;
95 typedef ArgumentsNode* Arguments;
96 typedef CommaNode* Comma;
97 typedef PropertyNode* Property;
98 typedef PropertyListNode* PropertyList;
99 typedef ElementNode* ElementList;
100 typedef ArgumentListNode* ArgumentsList;
101 typedef ParameterNode* FormalParameterList;
102 typedef FunctionBodyNode* FunctionBody;
103 typedef StatementNode* Statement;
104 typedef ClauseListNode* ClauseList;
105 typedef CaseClauseNode* Clause;
106 typedef ConstDeclNode* ConstDeclList;
107 typedef std::pair<ExpressionNode*, BinaryOpInfo> BinaryOperand;
108
109 static const bool CreatesAST = true;
110 static const bool NeedsFreeVariableInfo = true;
111 static const bool CanUseFunctionCache = true;
112 static const int DontBuildKeywords = 0;
113 static const int DontBuildStrings = 0;
114
115 ExpressionNode* makeBinaryNode(int lineNumber, int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>);
116 ExpressionNode* makeFunctionCallNode(int lineNumber, ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end);
117
118 JSC::SourceElements* createSourceElements() { return new (m_globalData) JSC::SourceElements(); }
119
120 ParserArenaData<DeclarationStacks::VarStack>* varDeclarations() { return m_scope.m_varDeclarations; }
121 ParserArenaData<DeclarationStacks::FunctionStack>* funcDeclarations() { return m_scope.m_funcDeclarations; }
122 int features() const { return m_scope.m_features; }
123 int numConstants() const { return m_scope.m_numConstants; }
124
125 void appendToComma(CommaNode* commaNode, ExpressionNode* expr) { commaNode->append(expr); }
126
127 CommaNode* createCommaExpr(int lineNumber, ExpressionNode* lhs, ExpressionNode* rhs) { return new (m_globalData) CommaNode(lineNumber, lhs, rhs); }
128
129 ExpressionNode* makeAssignNode(int lineNumber, ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, int start, int divot, int end);
130 ExpressionNode* makePrefixNode(int lineNumber, ExpressionNode*, Operator, int start, int divot, int end);
131 ExpressionNode* makePostfixNode(int lineNumber, ExpressionNode*, Operator, int start, int divot, int end);
132 ExpressionNode* makeTypeOfNode(int lineNumber, ExpressionNode*);
133 ExpressionNode* makeDeleteNode(int lineNumber, ExpressionNode*, int start, int divot, int end);
134 ExpressionNode* makeNegateNode(int lineNumber, ExpressionNode*);
135 ExpressionNode* makeBitwiseNotNode(int lineNumber, ExpressionNode*);
136 ExpressionNode* makeMultNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
137 ExpressionNode* makeDivNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
138 ExpressionNode* makeModNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
139 ExpressionNode* makeAddNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
140 ExpressionNode* makeSubNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
141 ExpressionNode* makeBitXOrNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
142 ExpressionNode* makeBitAndNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
143 ExpressionNode* makeBitOrNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
144 ExpressionNode* makeLeftShiftNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
145 ExpressionNode* makeRightShiftNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
146 ExpressionNode* makeURightShiftNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
147
148 ExpressionNode* createLogicalNot(int lineNumber, ExpressionNode* expr) { return new (m_globalData) LogicalNotNode(lineNumber, expr); }
149 ExpressionNode* createUnaryPlus(int lineNumber, ExpressionNode* expr) { return new (m_globalData) UnaryPlusNode(lineNumber, expr); }
150 ExpressionNode* createVoid(int lineNumber, ExpressionNode* expr)
151 {
152 incConstants();
153 return new (m_globalData) VoidNode(lineNumber, expr);
154 }
155 ExpressionNode* thisExpr(int lineNumber)
156 {
157 usesThis();
158 return new (m_globalData) ThisNode(lineNumber);
159 }
160 ExpressionNode* createResolve(int lineNumber, const Identifier* ident, int start)
161 {
162 if (m_globalData->propertyNames->arguments == *ident)
163 usesArguments();
164 return new (m_globalData) ResolveNode(lineNumber, *ident, start);
165 }
166 ExpressionNode* createObjectLiteral(int lineNumber) { return new (m_globalData) ObjectLiteralNode(lineNumber); }
167 ExpressionNode* createObjectLiteral(int lineNumber, PropertyListNode* properties) { return new (m_globalData) ObjectLiteralNode(lineNumber, properties); }
168
169 ExpressionNode* createArray(int lineNumber, int elisions)
170 {
171 if (elisions)
172 incConstants();
173 return new (m_globalData) ArrayNode(lineNumber, elisions);
174 }
175
176 ExpressionNode* createArray(int lineNumber, ElementNode* elems) { return new (m_globalData) ArrayNode(lineNumber, elems); }
177 ExpressionNode* createArray(int lineNumber, int elisions, ElementNode* elems)
178 {
179 if (elisions)
180 incConstants();
181 return new (m_globalData) ArrayNode(lineNumber, elisions, elems);
182 }
183 ExpressionNode* createNumberExpr(int lineNumber, double d)
184 {
185 incConstants();
186 return new (m_globalData) NumberNode(lineNumber, d);
187 }
188
189 ExpressionNode* createString(int lineNumber, const Identifier* string)
190 {
191 incConstants();
192 return new (m_globalData) StringNode(lineNumber, *string);
193 }
194
195 ExpressionNode* createBoolean(int lineNumber, bool b)
196 {
197 incConstants();
198 return new (m_globalData) BooleanNode(lineNumber, b);
199 }
200
201 ExpressionNode* createNull(int lineNumber)
202 {
203 incConstants();
204 return new (m_globalData) NullNode(lineNumber);
205 }
206
207 ExpressionNode* createBracketAccess(int lineNumber, ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, int start, int divot, int end)
208 {
209 BracketAccessorNode* node = new (m_globalData) BracketAccessorNode(lineNumber, base, property, propertyHasAssignments);
210 setExceptionLocation(node, start, divot, end);
211 return node;
212 }
213
214 ExpressionNode* createDotAccess(int lineNumber, ExpressionNode* base, const Identifier* property, int start, int divot, int end)
215 {
216 DotAccessorNode* node = new (m_globalData) DotAccessorNode(lineNumber, base, *property);
217 setExceptionLocation(node, start, divot, end);
218 return node;
219 }
220
221 ExpressionNode* createRegExp(int lineNumber, const Identifier& pattern, const Identifier& flags, int start)
222 {
223 if (Yarr::checkSyntax(pattern.ustring()))
224 return 0;
225 RegExpNode* node = new (m_globalData) RegExpNode(lineNumber, pattern, flags);
226 int size = pattern.length() + 2; // + 2 for the two /'s
227 setExceptionLocation(node, start, start + size, start + size);
228 return node;
229 }
230
231 ExpressionNode* createNewExpr(int lineNumber, ExpressionNode* expr, ArgumentsNode* arguments, int start, int divot, int end)
232 {
233 NewExprNode* node = new (m_globalData) NewExprNode(lineNumber, expr, arguments);
234 setExceptionLocation(node, start, divot, end);
235 return node;
236 }
237
238 ExpressionNode* createNewExpr(int lineNumber, ExpressionNode* expr, int start, int end)
239 {
240 NewExprNode* node = new (m_globalData) NewExprNode(lineNumber, expr);
241 setExceptionLocation(node, start, end, end);
242 return node;
243 }
244
245 ExpressionNode* createConditionalExpr(int lineNumber, ExpressionNode* condition, ExpressionNode* lhs, ExpressionNode* rhs)
246 {
247 return new (m_globalData) ConditionalNode(lineNumber, condition, lhs, rhs);
248 }
249
250 ExpressionNode* createAssignResolve(int lineNumber, const Identifier& ident, ExpressionNode* rhs, bool rhsHasAssignment, int start, int divot, int end)
251 {
252 if (rhs->isFuncExprNode())
253 static_cast<FuncExprNode*>(rhs)->body()->setInferredName(ident);
254 AssignResolveNode* node = new (m_globalData) AssignResolveNode(lineNumber, ident, rhs, rhsHasAssignment);
255 setExceptionLocation(node, start, divot, end);
256 return node;
257 }
258
259 ExpressionNode* createFunctionExpr(int lineNumber, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
260 {
261 FuncExprNode* result = new (m_globalData) FuncExprNode(lineNumber, *name, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), parameters);
262 body->setLoc(bodyStartLine, bodyEndLine);
263 return result;
264 }
265
266 FunctionBodyNode* createFunctionBody(int lineNumber, bool inStrictContext)
267 {
268 return FunctionBodyNode::create(m_globalData, lineNumber, inStrictContext);
269 }
270
271 template <bool> PropertyNode* createGetterOrSetterProperty(int lineNumber, PropertyNode::Type type, const Identifier* name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
272 {
273 ASSERT(name);
274 body->setLoc(bodyStartLine, bodyEndLine);
275 body->setInferredName(*name);
276 return new (m_globalData) PropertyNode(m_globalData, *name, new (m_globalData) FuncExprNode(lineNumber, m_globalData->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), params), type);
277 }
278
279 template <bool> PropertyNode* createGetterOrSetterProperty(JSGlobalData*, int lineNumber, PropertyNode::Type type, double name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
280 {
281 body->setLoc(bodyStartLine, bodyEndLine);
282 return new (m_globalData) PropertyNode(m_globalData, name, new (m_globalData) FuncExprNode(lineNumber, m_globalData->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), params), type);
283 }
284
285 ArgumentsNode* createArguments() { return new (m_globalData) ArgumentsNode(); }
286 ArgumentsNode* createArguments(ArgumentListNode* args) { return new (m_globalData) ArgumentsNode(args); }
287 ArgumentListNode* createArgumentsList(int lineNumber, ExpressionNode* arg) { return new (m_globalData) ArgumentListNode(lineNumber, arg); }
288 ArgumentListNode* createArgumentsList(int lineNumber, ArgumentListNode* args, ExpressionNode* arg) { return new (m_globalData) ArgumentListNode(lineNumber, args, arg); }
289
290 template <bool> PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type)
291 {
292 if (node->isFuncExprNode())
293 static_cast<FuncExprNode*>(node)->body()->setInferredName(*propertyName);
294 return new (m_globalData) PropertyNode(m_globalData, *propertyName, node, type);
295 }
296 template <bool> PropertyNode* createProperty(JSGlobalData*, double propertyName, ExpressionNode* node, PropertyNode::Type type) { return new (m_globalData) PropertyNode(m_globalData, propertyName, node, type); }
297 PropertyListNode* createPropertyList(int lineNumber, PropertyNode* property) { return new (m_globalData) PropertyListNode(lineNumber, property); }
298 PropertyListNode* createPropertyList(int lineNumber, PropertyNode* property, PropertyListNode* tail) { return new (m_globalData) PropertyListNode(lineNumber, property, tail); }
299
300 ElementNode* createElementList(int elisions, ExpressionNode* expr) { return new (m_globalData) ElementNode(elisions, expr); }
301 ElementNode* createElementList(ElementNode* elems, int elisions, ExpressionNode* expr) { return new (m_globalData) ElementNode(elems, elisions, expr); }
302
303 ParameterNode* createFormalParameterList(const Identifier& ident) { return new (m_globalData) ParameterNode(ident); }
304 ParameterNode* createFormalParameterList(ParameterNode* list, const Identifier& ident) { return new (m_globalData) ParameterNode(list, ident); }
305
306 CaseClauseNode* createClause(ExpressionNode* expr, JSC::SourceElements* statements) { return new (m_globalData) CaseClauseNode(expr, statements); }
307 ClauseListNode* createClauseList(CaseClauseNode* clause) { return new (m_globalData) ClauseListNode(clause); }
308 ClauseListNode* createClauseList(ClauseListNode* tail, CaseClauseNode* clause) { return new (m_globalData) ClauseListNode(tail, clause); }
309
310 void setUsesArguments(FunctionBodyNode* node) { node->setUsesArguments(); }
311
312 StatementNode* createFuncDeclStatement(int lineNumber, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
313 {
314 FuncDeclNode* decl = new (m_globalData) FuncDeclNode(lineNumber, *name, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), parameters);
315 if (*name == m_globalData->propertyNames->arguments)
316 usesArguments();
317 m_scope.m_funcDeclarations->data.append(decl->body());
318 body->setLoc(bodyStartLine, bodyEndLine);
319 return decl;
320 }
321
322 StatementNode* createBlockStatement(int lineNumber, JSC::SourceElements* elements, int startLine, int endLine)
323 {
324 BlockNode* block = new (m_globalData) BlockNode(lineNumber, elements);
325 block->setLoc(startLine, endLine);
326 return block;
327 }
328
329 StatementNode* createExprStatement(int lineNumber, ExpressionNode* expr, int start, int end)
330 {
331 ExprStatementNode* result = new (m_globalData) ExprStatementNode(lineNumber, expr);
332 result->setLoc(start, end);
333 return result;
334 }
335
336 StatementNode* createIfStatement(int lineNumber, ExpressionNode* condition, StatementNode* trueBlock, int start, int end)
337 {
338 IfNode* result = new (m_globalData) IfNode(lineNumber, condition, trueBlock);
339 result->setLoc(start, end);
340 return result;
341 }
342
343 StatementNode* createIfStatement(int lineNumber, ExpressionNode* condition, StatementNode* trueBlock, StatementNode* falseBlock, int start, int end)
344 {
345 IfNode* result = new (m_globalData) IfElseNode(lineNumber, condition, trueBlock, falseBlock);
346 result->setLoc(start, end);
347 return result;
348 }
349
350 StatementNode* createForLoop(int lineNumber, ExpressionNode* initializer, ExpressionNode* condition, ExpressionNode* iter, StatementNode* statements, bool b, int start, int end)
351 {
352 ForNode* result = new (m_globalData) ForNode(lineNumber, initializer, condition, iter, statements, b);
353 result->setLoc(start, end);
354 return result;
355 }
356
357 StatementNode* createForInLoop(int lineNumber, const Identifier* ident, ExpressionNode* initializer, ExpressionNode* iter, StatementNode* statements, int start, int divot, int end, int initStart, int initEnd, int startLine, int endLine)
358 {
359 ForInNode* result = new (m_globalData) ForInNode(m_globalData, lineNumber, *ident, initializer, iter, statements, initStart, initStart - start, initEnd - initStart);
360 result->setLoc(startLine, endLine);
361 setExceptionLocation(result, start, divot + 1, end);
362 return result;
363 }
364
365 StatementNode* createForInLoop(int lineNumber, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, int eStart, int eDivot, int eEnd, int start, int end)
366 {
367 ForInNode* result = new (m_globalData) ForInNode(m_globalData, lineNumber, lhs, iter, statements);
368 result->setLoc(start, end);
369 setExceptionLocation(result, eStart, eDivot, eEnd);
370 return result;
371 }
372
373 StatementNode* createEmptyStatement(int lineNumber) { return new (m_globalData) EmptyStatementNode(lineNumber); }
374
375 StatementNode* createVarStatement(int lineNumber, ExpressionNode* expr, int start, int end)
376 {
377 StatementNode* result;
378 if (!expr)
379 result = new (m_globalData) EmptyStatementNode(lineNumber);
380 else
381 result = new (m_globalData) VarStatementNode(lineNumber, expr);
382 result->setLoc(start, end);
383 return result;
384 }
385
386 StatementNode* createReturnStatement(int lineNumber, ExpressionNode* expression, int eStart, int eEnd, int startLine, int endLine)
387 {
388 ReturnNode* result = new (m_globalData) ReturnNode(lineNumber, expression);
389 setExceptionLocation(result, eStart, eEnd, eEnd);
390 result->setLoc(startLine, endLine);
391 return result;
392 }
393
394 StatementNode* createBreakStatement(int lineNumber, int eStart, int eEnd, int startLine, int endLine)
395 {
396 BreakNode* result = new (m_globalData) BreakNode(m_globalData, lineNumber);
397 setExceptionLocation(result, eStart, eEnd, eEnd);
398 result->setLoc(startLine, endLine);
399 return result;
400 }
401
402 StatementNode* createBreakStatement(int lineNumber, const Identifier* ident, int eStart, int eEnd, int startLine, int endLine)
403 {
404 BreakNode* result = new (m_globalData) BreakNode(lineNumber, *ident);
405 setExceptionLocation(result, eStart, eEnd, eEnd);
406 result->setLoc(startLine, endLine);
407 return result;
408 }
409
410 StatementNode* createContinueStatement(int lineNumber, int eStart, int eEnd, int startLine, int endLine)
411 {
412 ContinueNode* result = new (m_globalData) ContinueNode(m_globalData, lineNumber);
413 setExceptionLocation(result, eStart, eEnd, eEnd);
414 result->setLoc(startLine, endLine);
415 return result;
416 }
417
418 StatementNode* createContinueStatement(int lineNumber, const Identifier* ident, int eStart, int eEnd, int startLine, int endLine)
419 {
420 ContinueNode* result = new (m_globalData) ContinueNode(lineNumber, *ident);
421 setExceptionLocation(result, eStart, eEnd, eEnd);
422 result->setLoc(startLine, endLine);
423 return result;
424 }
425
426 StatementNode* createTryStatement(int lineNumber, StatementNode* tryBlock, const Identifier* ident, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
427 {
428 TryNode* result = new (m_globalData) TryNode(lineNumber, tryBlock, *ident, catchBlock, finallyBlock);
429 if (catchBlock)
430 usesCatch();
431 result->setLoc(startLine, endLine);
432 return result;
433 }
434
435 StatementNode* createSwitchStatement(int lineNumber, ExpressionNode* expr, ClauseListNode* firstClauses, CaseClauseNode* defaultClause, ClauseListNode* secondClauses, int startLine, int endLine)
436 {
437 CaseBlockNode* cases = new (m_globalData) CaseBlockNode(firstClauses, defaultClause, secondClauses);
438 SwitchNode* result = new (m_globalData) SwitchNode(lineNumber, expr, cases);
439 result->setLoc(startLine, endLine);
440 return result;
441 }
442
443 StatementNode* createWhileStatement(int lineNumber, ExpressionNode* expr, StatementNode* statement, int startLine, int endLine)
444 {
445 WhileNode* result = new (m_globalData) WhileNode(lineNumber, expr, statement);
446 result->setLoc(startLine, endLine);
447 return result;
448 }
449
450 StatementNode* createDoWhileStatement(int lineNumber, StatementNode* statement, ExpressionNode* expr, int startLine, int endLine)
451 {
452 DoWhileNode* result = new (m_globalData) DoWhileNode(lineNumber, statement, expr);
453 result->setLoc(startLine, endLine);
454 return result;
455 }
456
457 StatementNode* createLabelStatement(int lineNumber, const Identifier* ident, StatementNode* statement, int start, int end)
458 {
459 LabelNode* result = new (m_globalData) LabelNode(lineNumber, *ident, statement);
460 setExceptionLocation(result, start, end, end);
461 return result;
462 }
463
464 StatementNode* createWithStatement(int lineNumber, ExpressionNode* expr, StatementNode* statement, int start, int end, int startLine, int endLine)
465 {
466 usesWith();
467 WithNode* result = new (m_globalData) WithNode(lineNumber, expr, statement, end, end - start);
468 result->setLoc(startLine, endLine);
469 return result;
470 }
471
472 StatementNode* createThrowStatement(int lineNumber, ExpressionNode* expr, int start, int end, int startLine, int endLine)
473 {
474 ThrowNode* result = new (m_globalData) ThrowNode(lineNumber, expr);
475 result->setLoc(startLine, endLine);
476 setExceptionLocation(result, start, end, end);
477 return result;
478 }
479
480 StatementNode* createDebugger(int lineNumber, int startLine, int endLine)
481 {
482 DebuggerStatementNode* result = new (m_globalData) DebuggerStatementNode(lineNumber);
483 result->setLoc(startLine, endLine);
484 return result;
485 }
486
487 StatementNode* createConstStatement(int lineNumber, ConstDeclNode* decls, int startLine, int endLine)
488 {
489 ConstStatementNode* result = new (m_globalData) ConstStatementNode(lineNumber, decls);
490 result->setLoc(startLine, endLine);
491 return result;
492 }
493
494 ConstDeclNode* appendConstDecl(int lineNumber, ConstDeclNode* tail, const Identifier* name, ExpressionNode* initializer)
495 {
496 ConstDeclNode* result = new (m_globalData) ConstDeclNode(lineNumber, *name, initializer);
497 if (tail)
498 tail->m_next = result;
499 return result;
500 }
501
502 void appendStatement(JSC::SourceElements* elements, JSC::StatementNode* statement)
503 {
504 elements->append(statement);
505 }
506
507 void addVar(const Identifier* ident, int attrs)
508 {
509 if (m_globalData->propertyNames->arguments == *ident)
510 usesArguments();
511 m_scope.m_varDeclarations->data.append(std::make_pair(ident, attrs));
512 }
513
514 ExpressionNode* combineCommaNodes(int lineNumber, ExpressionNode* list, ExpressionNode* init)
515 {
516 if (!list)
517 return init;
518 if (list->isCommaNode()) {
519 static_cast<CommaNode*>(list)->append(init);
520 return list;
521 }
522 return new (m_globalData) CommaNode(lineNumber, list, init);
523 }
524
525 int evalCount() const { return m_evalCount; }
526
527 void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, int exprStart, int lhs, int rhs, bool hasAssignments)
528 {
529 operandStackDepth++;
530 m_binaryOperandStack.append(std::make_pair(current, BinaryOpInfo(exprStart, lhs, rhs, hasAssignments)));
531 }
532
533 // Logic to handle datastructures used during parsing of binary expressions
534 void operatorStackPop(int& operatorStackDepth)
535 {
536 operatorStackDepth--;
537 m_binaryOperatorStack.removeLast();
538 }
539 bool operatorStackHasHigherPrecedence(int&, int precedence)
540 {
541 return precedence <= m_binaryOperatorStack.last().second;
542 }
543 const BinaryOperand& getFromOperandStack(int i) { return m_binaryOperandStack[m_binaryOperandStack.size() + i]; }
544 void shrinkOperandStackBy(int& operandStackDepth, int amount)
545 {
546 operandStackDepth -= amount;
547 ASSERT(operandStackDepth >= 0);
548 m_binaryOperandStack.resize(m_binaryOperandStack.size() - amount);
549 }
550 void appendBinaryOperation(int lineNumber, int& operandStackDepth, int&, const BinaryOperand& lhs, const BinaryOperand& rhs)
551 {
552 operandStackDepth++;
553 m_binaryOperandStack.append(std::make_pair(makeBinaryNode(lineNumber, m_binaryOperatorStack.last().first, lhs, rhs), BinaryOpInfo(lhs.second, rhs.second)));
554 }
555 void operatorStackAppend(int& operatorStackDepth, int op, int precedence)
556 {
557 operatorStackDepth++;
558 m_binaryOperatorStack.append(std::make_pair(op, precedence));
559 }
560 ExpressionNode* popOperandStack(int&)
561 {
562 ExpressionNode* result = m_binaryOperandStack.last().first;
563 m_binaryOperandStack.removeLast();
564 return result;
565 }
566
567 void appendUnaryToken(int& tokenStackDepth, int type, int start)
568 {
569 tokenStackDepth++;
570 m_unaryTokenStack.append(std::make_pair(type, start));
571 }
572
573 int unaryTokenStackLastType(int&)
574 {
575 return m_unaryTokenStack.last().first;
576 }
577
578 int unaryTokenStackLastStart(int&)
579 {
580 return m_unaryTokenStack.last().second;
581 }
582
583 void unaryTokenStackRemoveLast(int& tokenStackDepth)
584 {
585 tokenStackDepth--;
586 m_unaryTokenStack.removeLast();
587 }
588
589 void assignmentStackAppend(int& assignmentStackDepth, ExpressionNode* node, int start, int divot, int assignmentCount, Operator op)
590 {
591 assignmentStackDepth++;
592 m_assignmentInfoStack.append(AssignmentInfo(node, start, divot, assignmentCount, op));
593 }
594
595 ExpressionNode* createAssignment(int lineNumber, int& assignmentStackDepth, ExpressionNode* rhs, int initialAssignmentCount, int currentAssignmentCount, int lastTokenEnd)
596 {
597 ExpressionNode* result = makeAssignNode(lineNumber, m_assignmentInfoStack.last().m_node, m_assignmentInfoStack.last().m_op, rhs, m_assignmentInfoStack.last().m_initAssignments != initialAssignmentCount, m_assignmentInfoStack.last().m_initAssignments != currentAssignmentCount, m_assignmentInfoStack.last().m_start, m_assignmentInfoStack.last().m_divot + 1, lastTokenEnd);
598 m_assignmentInfoStack.removeLast();
599 assignmentStackDepth--;
600 return result;
601 }
602
603 const Identifier& getName(Property property) const { return property->name(); }
604 PropertyNode::Type getType(Property property) const { return property->type(); }
605
606 bool isResolve(ExpressionNode* expr) const { return expr->isResolveNode(); }
607
608 private:
609 struct Scope {
610 Scope(JSGlobalData* globalData)
611 : m_varDeclarations(new (globalData) ParserArenaData<DeclarationStacks::VarStack>)
612 , m_funcDeclarations(new (globalData) ParserArenaData<DeclarationStacks::FunctionStack>)
613 , m_features(0)
614 , m_numConstants(0)
615 {
616 }
617 ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
618 ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
619 int m_features;
620 int m_numConstants;
621 };
622
623 static void setExceptionLocation(ThrowableExpressionData* node, unsigned start, unsigned divot, unsigned end)
624 {
625 node->setExceptionSourceCode(divot, divot - start, end - divot);
626 }
627
628 void incConstants() { m_scope.m_numConstants++; }
629 void usesThis() { m_scope.m_features |= ThisFeature; }
630 void usesCatch() { m_scope.m_features |= CatchFeature; }
631 void usesArguments() { m_scope.m_features |= ArgumentsFeature; }
632 void usesWith() { m_scope.m_features |= WithFeature; }
633 void usesEval()
634 {
635 m_evalCount++;
636 m_scope.m_features |= EvalFeature;
637 }
638 ExpressionNode* createNumber(int lineNumber, double d)
639 {
640 return new (m_globalData) NumberNode(lineNumber, d);
641 }
642
643 JSGlobalData* m_globalData;
644 SourceCode* m_sourceCode;
645 Scope m_scope;
646 Vector<BinaryOperand, 10> m_binaryOperandStack;
647 Vector<AssignmentInfo, 10> m_assignmentInfoStack;
648 Vector<pair<int, int>, 10> m_binaryOperatorStack;
649 Vector<pair<int, int>, 10> m_unaryTokenStack;
650 int m_evalCount;
651 };
652
653 ExpressionNode* ASTBuilder::makeTypeOfNode(int lineNumber, ExpressionNode* expr)
654 {
655 if (expr->isResolveNode()) {
656 ResolveNode* resolve = static_cast<ResolveNode*>(expr);
657 return new (m_globalData) TypeOfResolveNode(lineNumber, resolve->identifier());
658 }
659 return new (m_globalData) TypeOfValueNode(lineNumber, expr);
660 }
661
662 ExpressionNode* ASTBuilder::makeDeleteNode(int lineNumber, ExpressionNode* expr, int start, int divot, int end)
663 {
664 if (!expr->isLocation())
665 return new (m_globalData) DeleteValueNode(lineNumber, expr);
666 if (expr->isResolveNode()) {
667 ResolveNode* resolve = static_cast<ResolveNode*>(expr);
668 return new (m_globalData) DeleteResolveNode(lineNumber, resolve->identifier(), divot, divot - start, end - divot);
669 }
670 if (expr->isBracketAccessorNode()) {
671 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
672 return new (m_globalData) DeleteBracketNode(lineNumber, bracket->base(), bracket->subscript(), divot, divot - start, end - divot);
673 }
674 ASSERT(expr->isDotAccessorNode());
675 DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
676 return new (m_globalData) DeleteDotNode(lineNumber, dot->base(), dot->identifier(), divot, divot - start, end - divot);
677 }
678
679 ExpressionNode* ASTBuilder::makeNegateNode(int lineNumber, ExpressionNode* n)
680 {
681 if (n->isNumber()) {
682 NumberNode* numberNode = static_cast<NumberNode*>(n);
683 numberNode->setValue(-numberNode->value());
684 return numberNode;
685 }
686
687 return new (m_globalData) NegateNode(lineNumber, n);
688 }
689
690 ExpressionNode* ASTBuilder::makeBitwiseNotNode(int lineNumber, ExpressionNode* expr)
691 {
692 if (expr->isNumber())
693 return createNumber(lineNumber, ~toInt32(static_cast<NumberNode*>(expr)->value()));
694 return new (m_globalData) BitwiseNotNode(lineNumber, expr);
695 }
696
697 ExpressionNode* ASTBuilder::makeMultNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
698 {
699 expr1 = expr1->stripUnaryPlus();
700 expr2 = expr2->stripUnaryPlus();
701
702 if (expr1->isNumber() && expr2->isNumber())
703 return createNumber(lineNumber, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value());
704
705 if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1)
706 return new (m_globalData) UnaryPlusNode(lineNumber, expr2);
707
708 if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1)
709 return new (m_globalData) UnaryPlusNode(lineNumber, expr1);
710
711 return new (m_globalData) MultNode(lineNumber, expr1, expr2, rightHasAssignments);
712 }
713
714 ExpressionNode* ASTBuilder::makeDivNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
715 {
716 expr1 = expr1->stripUnaryPlus();
717 expr2 = expr2->stripUnaryPlus();
718
719 if (expr1->isNumber() && expr2->isNumber())
720 return createNumber(lineNumber, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value());
721 return new (m_globalData) DivNode(lineNumber, expr1, expr2, rightHasAssignments);
722 }
723
724 ExpressionNode* ASTBuilder::makeModNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
725 {
726 expr1 = expr1->stripUnaryPlus();
727 expr2 = expr2->stripUnaryPlus();
728
729 if (expr1->isNumber() && expr2->isNumber())
730 return createNumber(lineNumber, fmod(static_cast<NumberNode*>(expr1)->value(), static_cast<NumberNode*>(expr2)->value()));
731 return new (m_globalData) ModNode(lineNumber, expr1, expr2, rightHasAssignments);
732 }
733
734 ExpressionNode* ASTBuilder::makeAddNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
735 {
736 if (expr1->isNumber() && expr2->isNumber())
737 return createNumber(lineNumber, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value());
738 return new (m_globalData) AddNode(lineNumber, expr1, expr2, rightHasAssignments);
739 }
740
741 ExpressionNode* ASTBuilder::makeSubNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
742 {
743 expr1 = expr1->stripUnaryPlus();
744 expr2 = expr2->stripUnaryPlus();
745
746 if (expr1->isNumber() && expr2->isNumber())
747 return createNumber(lineNumber, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value());
748 return new (m_globalData) SubNode(lineNumber, expr1, expr2, rightHasAssignments);
749 }
750
751 ExpressionNode* ASTBuilder::makeLeftShiftNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
752 {
753 if (expr1->isNumber() && expr2->isNumber())
754 return createNumber(lineNumber, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
755 return new (m_globalData) LeftShiftNode(lineNumber, expr1, expr2, rightHasAssignments);
756 }
757
758 ExpressionNode* ASTBuilder::makeRightShiftNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
759 {
760 if (expr1->isNumber() && expr2->isNumber())
761 return createNumber(lineNumber, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
762 return new (m_globalData) RightShiftNode(lineNumber, expr1, expr2, rightHasAssignments);
763 }
764
765 ExpressionNode* ASTBuilder::makeURightShiftNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
766 {
767 if (expr1->isNumber() && expr2->isNumber())
768 return createNumber(lineNumber, toUInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
769 return new (m_globalData) UnsignedRightShiftNode(lineNumber, expr1, expr2, rightHasAssignments);
770 }
771
772 ExpressionNode* ASTBuilder::makeBitOrNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
773 {
774 if (expr1->isNumber() && expr2->isNumber())
775 return createNumber(lineNumber, toInt32(static_cast<NumberNode*>(expr1)->value()) | toInt32(static_cast<NumberNode*>(expr2)->value()));
776 return new (m_globalData) BitOrNode(lineNumber, expr1, expr2, rightHasAssignments);
777 }
778
779 ExpressionNode* ASTBuilder::makeBitAndNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
780 {
781 if (expr1->isNumber() && expr2->isNumber())
782 return createNumber(lineNumber, toInt32(static_cast<NumberNode*>(expr1)->value()) & toInt32(static_cast<NumberNode*>(expr2)->value()));
783 return new (m_globalData) BitAndNode(lineNumber, expr1, expr2, rightHasAssignments);
784 }
785
786 ExpressionNode* ASTBuilder::makeBitXOrNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
787 {
788 if (expr1->isNumber() && expr2->isNumber())
789 return createNumber(lineNumber, toInt32(static_cast<NumberNode*>(expr1)->value()) ^ toInt32(static_cast<NumberNode*>(expr2)->value()));
790 return new (m_globalData) BitXOrNode(lineNumber, expr1, expr2, rightHasAssignments);
791 }
792
793 ExpressionNode* ASTBuilder::makeFunctionCallNode(int lineNumber, ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end)
794 {
795 if (!func->isLocation())
796 return new (m_globalData) FunctionCallValueNode(lineNumber, func, args, divot, divot - start, end - divot);
797 if (func->isResolveNode()) {
798 ResolveNode* resolve = static_cast<ResolveNode*>(func);
799 const Identifier& identifier = resolve->identifier();
800 if (identifier == m_globalData->propertyNames->eval) {
801 usesEval();
802 return new (m_globalData) EvalFunctionCallNode(lineNumber, args, divot, divot - start, end - divot);
803 }
804 return new (m_globalData) FunctionCallResolveNode(lineNumber, identifier, args, divot, divot - start, end - divot);
805 }
806 if (func->isBracketAccessorNode()) {
807 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func);
808 FunctionCallBracketNode* node = new (m_globalData) FunctionCallBracketNode(lineNumber, bracket->base(), bracket->subscript(), args, divot, divot - start, end - divot);
809 node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
810 return node;
811 }
812 ASSERT(func->isDotAccessorNode());
813 DotAccessorNode* dot = static_cast<DotAccessorNode*>(func);
814 FunctionCallDotNode* node;
815 if (dot->identifier() == m_globalData->propertyNames->call)
816 node = new (m_globalData) CallFunctionCallDotNode(lineNumber, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
817 else if (dot->identifier() == m_globalData->propertyNames->apply)
818 node = new (m_globalData) ApplyFunctionCallDotNode(lineNumber, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
819 else
820 node = new (m_globalData) FunctionCallDotNode(lineNumber, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
821 node->setSubexpressionInfo(dot->divot(), dot->endOffset());
822 return node;
823 }
824
825 ExpressionNode* ASTBuilder::makeBinaryNode(int lineNumber, int token, pair<ExpressionNode*, BinaryOpInfo> lhs, pair<ExpressionNode*, BinaryOpInfo> rhs)
826 {
827 switch (token) {
828 case OR:
829 return new (m_globalData) LogicalOpNode(lineNumber, lhs.first, rhs.first, OpLogicalOr);
830
831 case AND:
832 return new (m_globalData) LogicalOpNode(lineNumber, lhs.first, rhs.first, OpLogicalAnd);
833
834 case BITOR:
835 return makeBitOrNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
836
837 case BITXOR:
838 return makeBitXOrNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
839
840 case BITAND:
841 return makeBitAndNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
842
843 case EQEQ:
844 return new (m_globalData) EqualNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
845
846 case NE:
847 return new (m_globalData) NotEqualNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
848
849 case STREQ:
850 return new (m_globalData) StrictEqualNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
851
852 case STRNEQ:
853 return new (m_globalData) NotStrictEqualNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
854
855 case LT:
856 return new (m_globalData) LessNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
857
858 case GT:
859 return new (m_globalData) GreaterNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
860
861 case LE:
862 return new (m_globalData) LessEqNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
863
864 case GE:
865 return new (m_globalData) GreaterEqNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
866
867 case INSTANCEOF: {
868 InstanceOfNode* node = new (m_globalData) InstanceOfNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
869 setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
870 return node;
871 }
872
873 case INTOKEN: {
874 InNode* node = new (m_globalData) InNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
875 setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
876 return node;
877 }
878
879 case LSHIFT:
880 return makeLeftShiftNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
881
882 case RSHIFT:
883 return makeRightShiftNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
884
885 case URSHIFT:
886 return makeURightShiftNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
887
888 case PLUS:
889 return makeAddNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
890
891 case MINUS:
892 return makeSubNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
893
894 case TIMES:
895 return makeMultNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
896
897 case DIVIDE:
898 return makeDivNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
899
900 case MOD:
901 return makeModNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
902 }
903 CRASH();
904 return 0;
905 }
906
907 ExpressionNode* ASTBuilder::makeAssignNode(int lineNumber, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end)
908 {
909 if (!loc->isLocation())
910 return new (m_globalData) AssignErrorNode(lineNumber, loc, op, expr, divot, divot - start, end - divot);
911
912 if (loc->isResolveNode()) {
913 ResolveNode* resolve = static_cast<ResolveNode*>(loc);
914 if (op == OpEqual) {
915 if (expr->isFuncExprNode())
916 static_cast<FuncExprNode*>(expr)->body()->setInferredName(resolve->identifier());
917 AssignResolveNode* node = new (m_globalData) AssignResolveNode(lineNumber, resolve->identifier(), expr, exprHasAssignments);
918 setExceptionLocation(node, start, divot, end);
919 return node;
920 }
921 return new (m_globalData) ReadModifyResolveNode(lineNumber, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
922 }
923 if (loc->isBracketAccessorNode()) {
924 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc);
925 if (op == OpEqual)
926 return new (m_globalData) AssignBracketNode(lineNumber, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot());
927 ReadModifyBracketNode* node = new (m_globalData) ReadModifyBracketNode(lineNumber, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot);
928 node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
929 return node;
930 }
931 ASSERT(loc->isDotAccessorNode());
932 DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc);
933 if (op == OpEqual) {
934 if (expr->isFuncExprNode())
935 static_cast<FuncExprNode*>(expr)->body()->setInferredName(dot->identifier());
936 return new (m_globalData) AssignDotNode(lineNumber, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot());
937 }
938
939 ReadModifyDotNode* node = new (m_globalData) ReadModifyDotNode(lineNumber, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
940 node->setSubexpressionInfo(dot->divot(), dot->endOffset());
941 return node;
942 }
943
944 ExpressionNode* ASTBuilder::makePrefixNode(int lineNumber, ExpressionNode* expr, Operator op, int start, int divot, int end)
945 {
946 if (!expr->isLocation())
947 return new (m_globalData) PrefixErrorNode(lineNumber, expr, op, divot, divot - start, end - divot);
948
949 if (expr->isResolveNode()) {
950 ResolveNode* resolve = static_cast<ResolveNode*>(expr);
951 return new (m_globalData) PrefixResolveNode(lineNumber, resolve->identifier(), op, divot, divot - start, end - divot);
952 }
953 if (expr->isBracketAccessorNode()) {
954 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
955 PrefixBracketNode* node = new (m_globalData) PrefixBracketNode(lineNumber, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
956 node->setSubexpressionInfo(bracket->divot(), bracket->startOffset());
957 return node;
958 }
959 ASSERT(expr->isDotAccessorNode());
960 DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
961 PrefixDotNode* node = new (m_globalData) PrefixDotNode(lineNumber, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
962 node->setSubexpressionInfo(dot->divot(), dot->startOffset());
963 return node;
964 }
965
966 ExpressionNode* ASTBuilder::makePostfixNode(int lineNumber, ExpressionNode* expr, Operator op, int start, int divot, int end)
967 {
968 if (!expr->isLocation())
969 return new (m_globalData) PostfixErrorNode(lineNumber, expr, op, divot, divot - start, end - divot);
970
971 if (expr->isResolveNode()) {
972 ResolveNode* resolve = static_cast<ResolveNode*>(expr);
973 return new (m_globalData) PostfixResolveNode(lineNumber, resolve->identifier(), op, divot, divot - start, end - divot);
974 }
975 if (expr->isBracketAccessorNode()) {
976 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
977 PostfixBracketNode* node = new (m_globalData) PostfixBracketNode(lineNumber, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
978 node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
979 return node;
980
981 }
982 ASSERT(expr->isDotAccessorNode());
983 DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
984 PostfixDotNode* node = new (m_globalData) PostfixDotNode(lineNumber, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
985 node->setSubexpressionInfo(dot->divot(), dot->endOffset());
986 return node;
987 }
988
989 }
990
991 #endif