2 * Copyright (C) 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #include "NodeConstructors.h"
30 #include "SyntaxChecker.h"
38 BinaryOpInfo(int s
, int d
, int e
, bool r
)
45 BinaryOpInfo(const BinaryOpInfo
& lhs
, const BinaryOpInfo
& rhs
)
49 , hasAssignment(lhs
.hasAssignment
|| rhs
.hasAssignment
)
59 struct AssignmentInfo
{
61 AssignmentInfo(ExpressionNode
* node
, int start
, int divot
, int initAssignments
, Operator op
)
65 , m_initAssignments(initAssignments
)
69 ExpressionNode
* m_node
;
72 int m_initAssignments
;
76 ASTBuilder(JSGlobalData
* globalData
, SourceCode
* sourceCode
)
77 : m_globalData(globalData
)
78 , m_sourceCode(sourceCode
)
84 struct BinaryExprContext
{
85 BinaryExprContext(ASTBuilder
&) {}
87 struct UnaryExprContext
{
88 UnaryExprContext(ASTBuilder
&) {}
91 typedef SyntaxChecker FunctionBodyBuilder
;
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
;
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;
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
);
118 JSC::SourceElements
* createSourceElements() { return new (m_globalData
) JSC::SourceElements(); }
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
; }
125 void appendToComma(CommaNode
* commaNode
, ExpressionNode
* expr
) { commaNode
->append(expr
); }
127 CommaNode
* createCommaExpr(int lineNumber
, ExpressionNode
* lhs
, ExpressionNode
* rhs
) { return new (m_globalData
) CommaNode(lineNumber
, lhs
, rhs
); }
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
);
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
)
153 return new (m_globalData
) VoidNode(lineNumber
, expr
);
155 ExpressionNode
* thisExpr(int lineNumber
)
158 return new (m_globalData
) ThisNode(lineNumber
);
160 ExpressionNode
* createResolve(int lineNumber
, const Identifier
* ident
, int start
)
162 if (m_globalData
->propertyNames
->arguments
== *ident
)
164 return new (m_globalData
) ResolveNode(lineNumber
, *ident
, start
);
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
); }
169 ExpressionNode
* createArray(int lineNumber
, int elisions
)
173 return new (m_globalData
) ArrayNode(lineNumber
, elisions
);
176 ExpressionNode
* createArray(int lineNumber
, ElementNode
* elems
) { return new (m_globalData
) ArrayNode(lineNumber
, elems
); }
177 ExpressionNode
* createArray(int lineNumber
, int elisions
, ElementNode
* elems
)
181 return new (m_globalData
) ArrayNode(lineNumber
, elisions
, elems
);
183 ExpressionNode
* createNumberExpr(int lineNumber
, double d
)
186 return new (m_globalData
) NumberNode(lineNumber
, d
);
189 ExpressionNode
* createString(int lineNumber
, const Identifier
* string
)
192 return new (m_globalData
) StringNode(lineNumber
, *string
);
195 ExpressionNode
* createBoolean(int lineNumber
, bool b
)
198 return new (m_globalData
) BooleanNode(lineNumber
, b
);
201 ExpressionNode
* createNull(int lineNumber
)
204 return new (m_globalData
) NullNode(lineNumber
);
207 ExpressionNode
* createBracketAccess(int lineNumber
, ExpressionNode
* base
, ExpressionNode
* property
, bool propertyHasAssignments
, int start
, int divot
, int end
)
209 BracketAccessorNode
* node
= new (m_globalData
) BracketAccessorNode(lineNumber
, base
, property
, propertyHasAssignments
);
210 setExceptionLocation(node
, start
, divot
, end
);
214 ExpressionNode
* createDotAccess(int lineNumber
, ExpressionNode
* base
, const Identifier
* property
, int start
, int divot
, int end
)
216 DotAccessorNode
* node
= new (m_globalData
) DotAccessorNode(lineNumber
, base
, *property
);
217 setExceptionLocation(node
, start
, divot
, end
);
221 ExpressionNode
* createRegExp(int lineNumber
, const Identifier
& pattern
, const Identifier
& flags
, int start
)
223 if (Yarr::checkSyntax(pattern
.ustring()))
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
);
231 ExpressionNode
* createNewExpr(int lineNumber
, ExpressionNode
* expr
, ArgumentsNode
* arguments
, int start
, int divot
, int end
)
233 NewExprNode
* node
= new (m_globalData
) NewExprNode(lineNumber
, expr
, arguments
);
234 setExceptionLocation(node
, start
, divot
, end
);
238 ExpressionNode
* createNewExpr(int lineNumber
, ExpressionNode
* expr
, int start
, int end
)
240 NewExprNode
* node
= new (m_globalData
) NewExprNode(lineNumber
, expr
);
241 setExceptionLocation(node
, start
, end
, end
);
245 ExpressionNode
* createConditionalExpr(int lineNumber
, ExpressionNode
* condition
, ExpressionNode
* lhs
, ExpressionNode
* rhs
)
247 return new (m_globalData
) ConditionalNode(lineNumber
, condition
, lhs
, rhs
);
250 ExpressionNode
* createAssignResolve(int lineNumber
, const Identifier
& ident
, ExpressionNode
* rhs
, bool rhsHasAssignment
, int start
, int divot
, int end
)
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
);
259 ExpressionNode
* createFunctionExpr(int lineNumber
, const Identifier
* name
, FunctionBodyNode
* body
, ParameterNode
* parameters
, int openBracePos
, int closeBracePos
, int bodyStartLine
, int bodyEndLine
)
261 FuncExprNode
* result
= new (m_globalData
) FuncExprNode(lineNumber
, *name
, body
, m_sourceCode
->subExpression(openBracePos
, closeBracePos
, bodyStartLine
), parameters
);
262 body
->setLoc(bodyStartLine
, bodyEndLine
);
266 FunctionBodyNode
* createFunctionBody(int lineNumber
, bool inStrictContext
)
268 return FunctionBodyNode::create(m_globalData
, lineNumber
, inStrictContext
);
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
)
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
);
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
)
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
);
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
); }
290 template <bool> PropertyNode
* createProperty(const Identifier
* propertyName
, ExpressionNode
* node
, PropertyNode::Type type
)
292 if (node
->isFuncExprNode())
293 static_cast<FuncExprNode
*>(node
)->body()->setInferredName(*propertyName
);
294 return new (m_globalData
) PropertyNode(m_globalData
, *propertyName
, node
, type
);
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
); }
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
); }
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
); }
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
); }
310 void setUsesArguments(FunctionBodyNode
* node
) { node
->setUsesArguments(); }
312 StatementNode
* createFuncDeclStatement(int lineNumber
, const Identifier
* name
, FunctionBodyNode
* body
, ParameterNode
* parameters
, int openBracePos
, int closeBracePos
, int bodyStartLine
, int bodyEndLine
)
314 FuncDeclNode
* decl
= new (m_globalData
) FuncDeclNode(lineNumber
, *name
, body
, m_sourceCode
->subExpression(openBracePos
, closeBracePos
, bodyStartLine
), parameters
);
315 if (*name
== m_globalData
->propertyNames
->arguments
)
317 m_scope
.m_funcDeclarations
->data
.append(decl
->body());
318 body
->setLoc(bodyStartLine
, bodyEndLine
);
322 StatementNode
* createBlockStatement(int lineNumber
, JSC::SourceElements
* elements
, int startLine
, int endLine
)
324 BlockNode
* block
= new (m_globalData
) BlockNode(lineNumber
, elements
);
325 block
->setLoc(startLine
, endLine
);
329 StatementNode
* createExprStatement(int lineNumber
, ExpressionNode
* expr
, int start
, int end
)
331 ExprStatementNode
* result
= new (m_globalData
) ExprStatementNode(lineNumber
, expr
);
332 result
->setLoc(start
, end
);
336 StatementNode
* createIfStatement(int lineNumber
, ExpressionNode
* condition
, StatementNode
* trueBlock
, int start
, int end
)
338 IfNode
* result
= new (m_globalData
) IfNode(lineNumber
, condition
, trueBlock
);
339 result
->setLoc(start
, end
);
343 StatementNode
* createIfStatement(int lineNumber
, ExpressionNode
* condition
, StatementNode
* trueBlock
, StatementNode
* falseBlock
, int start
, int end
)
345 IfNode
* result
= new (m_globalData
) IfElseNode(lineNumber
, condition
, trueBlock
, falseBlock
);
346 result
->setLoc(start
, end
);
350 StatementNode
* createForLoop(int lineNumber
, ExpressionNode
* initializer
, ExpressionNode
* condition
, ExpressionNode
* iter
, StatementNode
* statements
, bool b
, int start
, int end
)
352 ForNode
* result
= new (m_globalData
) ForNode(lineNumber
, initializer
, condition
, iter
, statements
, b
);
353 result
->setLoc(start
, end
);
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
)
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
);
365 StatementNode
* createForInLoop(int lineNumber
, ExpressionNode
* lhs
, ExpressionNode
* iter
, StatementNode
* statements
, int eStart
, int eDivot
, int eEnd
, int start
, int end
)
367 ForInNode
* result
= new (m_globalData
) ForInNode(m_globalData
, lineNumber
, lhs
, iter
, statements
);
368 result
->setLoc(start
, end
);
369 setExceptionLocation(result
, eStart
, eDivot
, eEnd
);
373 StatementNode
* createEmptyStatement(int lineNumber
) { return new (m_globalData
) EmptyStatementNode(lineNumber
); }
375 StatementNode
* createVarStatement(int lineNumber
, ExpressionNode
* expr
, int start
, int end
)
377 StatementNode
* result
;
379 result
= new (m_globalData
) EmptyStatementNode(lineNumber
);
381 result
= new (m_globalData
) VarStatementNode(lineNumber
, expr
);
382 result
->setLoc(start
, end
);
386 StatementNode
* createReturnStatement(int lineNumber
, ExpressionNode
* expression
, int eStart
, int eEnd
, int startLine
, int endLine
)
388 ReturnNode
* result
= new (m_globalData
) ReturnNode(lineNumber
, expression
);
389 setExceptionLocation(result
, eStart
, eEnd
, eEnd
);
390 result
->setLoc(startLine
, endLine
);
394 StatementNode
* createBreakStatement(int lineNumber
, int eStart
, int eEnd
, int startLine
, int endLine
)
396 BreakNode
* result
= new (m_globalData
) BreakNode(m_globalData
, lineNumber
);
397 setExceptionLocation(result
, eStart
, eEnd
, eEnd
);
398 result
->setLoc(startLine
, endLine
);
402 StatementNode
* createBreakStatement(int lineNumber
, const Identifier
* ident
, int eStart
, int eEnd
, int startLine
, int endLine
)
404 BreakNode
* result
= new (m_globalData
) BreakNode(lineNumber
, *ident
);
405 setExceptionLocation(result
, eStart
, eEnd
, eEnd
);
406 result
->setLoc(startLine
, endLine
);
410 StatementNode
* createContinueStatement(int lineNumber
, int eStart
, int eEnd
, int startLine
, int endLine
)
412 ContinueNode
* result
= new (m_globalData
) ContinueNode(m_globalData
, lineNumber
);
413 setExceptionLocation(result
, eStart
, eEnd
, eEnd
);
414 result
->setLoc(startLine
, endLine
);
418 StatementNode
* createContinueStatement(int lineNumber
, const Identifier
* ident
, int eStart
, int eEnd
, int startLine
, int endLine
)
420 ContinueNode
* result
= new (m_globalData
) ContinueNode(lineNumber
, *ident
);
421 setExceptionLocation(result
, eStart
, eEnd
, eEnd
);
422 result
->setLoc(startLine
, endLine
);
426 StatementNode
* createTryStatement(int lineNumber
, StatementNode
* tryBlock
, const Identifier
* ident
, StatementNode
* catchBlock
, StatementNode
* finallyBlock
, int startLine
, int endLine
)
428 TryNode
* result
= new (m_globalData
) TryNode(lineNumber
, tryBlock
, *ident
, catchBlock
, finallyBlock
);
431 result
->setLoc(startLine
, endLine
);
435 StatementNode
* createSwitchStatement(int lineNumber
, ExpressionNode
* expr
, ClauseListNode
* firstClauses
, CaseClauseNode
* defaultClause
, ClauseListNode
* secondClauses
, int startLine
, int endLine
)
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
);
443 StatementNode
* createWhileStatement(int lineNumber
, ExpressionNode
* expr
, StatementNode
* statement
, int startLine
, int endLine
)
445 WhileNode
* result
= new (m_globalData
) WhileNode(lineNumber
, expr
, statement
);
446 result
->setLoc(startLine
, endLine
);
450 StatementNode
* createDoWhileStatement(int lineNumber
, StatementNode
* statement
, ExpressionNode
* expr
, int startLine
, int endLine
)
452 DoWhileNode
* result
= new (m_globalData
) DoWhileNode(lineNumber
, statement
, expr
);
453 result
->setLoc(startLine
, endLine
);
457 StatementNode
* createLabelStatement(int lineNumber
, const Identifier
* ident
, StatementNode
* statement
, int start
, int end
)
459 LabelNode
* result
= new (m_globalData
) LabelNode(lineNumber
, *ident
, statement
);
460 setExceptionLocation(result
, start
, end
, end
);
464 StatementNode
* createWithStatement(int lineNumber
, ExpressionNode
* expr
, StatementNode
* statement
, int start
, int end
, int startLine
, int endLine
)
467 WithNode
* result
= new (m_globalData
) WithNode(lineNumber
, expr
, statement
, end
, end
- start
);
468 result
->setLoc(startLine
, endLine
);
472 StatementNode
* createThrowStatement(int lineNumber
, ExpressionNode
* expr
, int start
, int end
, int startLine
, int endLine
)
474 ThrowNode
* result
= new (m_globalData
) ThrowNode(lineNumber
, expr
);
475 result
->setLoc(startLine
, endLine
);
476 setExceptionLocation(result
, start
, end
, end
);
480 StatementNode
* createDebugger(int lineNumber
, int startLine
, int endLine
)
482 DebuggerStatementNode
* result
= new (m_globalData
) DebuggerStatementNode(lineNumber
);
483 result
->setLoc(startLine
, endLine
);
487 StatementNode
* createConstStatement(int lineNumber
, ConstDeclNode
* decls
, int startLine
, int endLine
)
489 ConstStatementNode
* result
= new (m_globalData
) ConstStatementNode(lineNumber
, decls
);
490 result
->setLoc(startLine
, endLine
);
494 ConstDeclNode
* appendConstDecl(int lineNumber
, ConstDeclNode
* tail
, const Identifier
* name
, ExpressionNode
* initializer
)
496 ConstDeclNode
* result
= new (m_globalData
) ConstDeclNode(lineNumber
, *name
, initializer
);
498 tail
->m_next
= result
;
502 void appendStatement(JSC::SourceElements
* elements
, JSC::StatementNode
* statement
)
504 elements
->append(statement
);
507 void addVar(const Identifier
* ident
, int attrs
)
509 if (m_globalData
->propertyNames
->arguments
== *ident
)
511 m_scope
.m_varDeclarations
->data
.append(std::make_pair(ident
, attrs
));
514 ExpressionNode
* combineCommaNodes(int lineNumber
, ExpressionNode
* list
, ExpressionNode
* init
)
518 if (list
->isCommaNode()) {
519 static_cast<CommaNode
*>(list
)->append(init
);
522 return new (m_globalData
) CommaNode(lineNumber
, list
, init
);
525 int evalCount() const { return m_evalCount
; }
527 void appendBinaryExpressionInfo(int& operandStackDepth
, ExpressionNode
* current
, int exprStart
, int lhs
, int rhs
, bool hasAssignments
)
530 m_binaryOperandStack
.append(std::make_pair(current
, BinaryOpInfo(exprStart
, lhs
, rhs
, hasAssignments
)));
533 // Logic to handle datastructures used during parsing of binary expressions
534 void operatorStackPop(int& operatorStackDepth
)
536 operatorStackDepth
--;
537 m_binaryOperatorStack
.removeLast();
539 bool operatorStackHasHigherPrecedence(int&, int precedence
)
541 return precedence
<= m_binaryOperatorStack
.last().second
;
543 const BinaryOperand
& getFromOperandStack(int i
) { return m_binaryOperandStack
[m_binaryOperandStack
.size() + i
]; }
544 void shrinkOperandStackBy(int& operandStackDepth
, int amount
)
546 operandStackDepth
-= amount
;
547 ASSERT(operandStackDepth
>= 0);
548 m_binaryOperandStack
.resize(m_binaryOperandStack
.size() - amount
);
550 void appendBinaryOperation(int lineNumber
, int& operandStackDepth
, int&, const BinaryOperand
& lhs
, const BinaryOperand
& rhs
)
553 m_binaryOperandStack
.append(std::make_pair(makeBinaryNode(lineNumber
, m_binaryOperatorStack
.last().first
, lhs
, rhs
), BinaryOpInfo(lhs
.second
, rhs
.second
)));
555 void operatorStackAppend(int& operatorStackDepth
, int op
, int precedence
)
557 operatorStackDepth
++;
558 m_binaryOperatorStack
.append(std::make_pair(op
, precedence
));
560 ExpressionNode
* popOperandStack(int&)
562 ExpressionNode
* result
= m_binaryOperandStack
.last().first
;
563 m_binaryOperandStack
.removeLast();
567 void appendUnaryToken(int& tokenStackDepth
, int type
, int start
)
570 m_unaryTokenStack
.append(std::make_pair(type
, start
));
573 int unaryTokenStackLastType(int&)
575 return m_unaryTokenStack
.last().first
;
578 int unaryTokenStackLastStart(int&)
580 return m_unaryTokenStack
.last().second
;
583 void unaryTokenStackRemoveLast(int& tokenStackDepth
)
586 m_unaryTokenStack
.removeLast();
589 void assignmentStackAppend(int& assignmentStackDepth
, ExpressionNode
* node
, int start
, int divot
, int assignmentCount
, Operator op
)
591 assignmentStackDepth
++;
592 m_assignmentInfoStack
.append(AssignmentInfo(node
, start
, divot
, assignmentCount
, op
));
595 ExpressionNode
* createAssignment(int lineNumber
, int& assignmentStackDepth
, ExpressionNode
* rhs
, int initialAssignmentCount
, int currentAssignmentCount
, int lastTokenEnd
)
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
--;
603 const Identifier
& getName(Property property
) const { return property
->name(); }
604 PropertyNode::Type
getType(Property property
) const { return property
->type(); }
606 bool isResolve(ExpressionNode
* expr
) const { return expr
->isResolveNode(); }
610 Scope(JSGlobalData
* globalData
)
611 : m_varDeclarations(new (globalData
) ParserArenaData
<DeclarationStacks::VarStack
>)
612 , m_funcDeclarations(new (globalData
) ParserArenaData
<DeclarationStacks::FunctionStack
>)
617 ParserArenaData
<DeclarationStacks::VarStack
>* m_varDeclarations
;
618 ParserArenaData
<DeclarationStacks::FunctionStack
>* m_funcDeclarations
;
623 static void setExceptionLocation(ThrowableExpressionData
* node
, unsigned start
, unsigned divot
, unsigned end
)
625 node
->setExceptionSourceCode(divot
, divot
- start
, end
- divot
);
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
; }
636 m_scope
.m_features
|= EvalFeature
;
638 ExpressionNode
* createNumber(int lineNumber
, double d
)
640 return new (m_globalData
) NumberNode(lineNumber
, d
);
643 JSGlobalData
* m_globalData
;
644 SourceCode
* m_sourceCode
;
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
;
653 ExpressionNode
* ASTBuilder::makeTypeOfNode(int lineNumber
, ExpressionNode
* expr
)
655 if (expr
->isResolveNode()) {
656 ResolveNode
* resolve
= static_cast<ResolveNode
*>(expr
);
657 return new (m_globalData
) TypeOfResolveNode(lineNumber
, resolve
->identifier());
659 return new (m_globalData
) TypeOfValueNode(lineNumber
, expr
);
662 ExpressionNode
* ASTBuilder::makeDeleteNode(int lineNumber
, ExpressionNode
* expr
, int start
, int divot
, int end
)
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
);
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
);
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
);
679 ExpressionNode
* ASTBuilder::makeNegateNode(int lineNumber
, ExpressionNode
* n
)
682 NumberNode
* numberNode
= static_cast<NumberNode
*>(n
);
683 numberNode
->setValue(-numberNode
->value());
687 return new (m_globalData
) NegateNode(lineNumber
, n
);
690 ExpressionNode
* ASTBuilder::makeBitwiseNotNode(int lineNumber
, ExpressionNode
* expr
)
692 if (expr
->isNumber())
693 return createNumber(lineNumber
, ~toInt32(static_cast<NumberNode
*>(expr
)->value()));
694 return new (m_globalData
) BitwiseNotNode(lineNumber
, expr
);
697 ExpressionNode
* ASTBuilder::makeMultNode(int lineNumber
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
699 expr1
= expr1
->stripUnaryPlus();
700 expr2
= expr2
->stripUnaryPlus();
702 if (expr1
->isNumber() && expr2
->isNumber())
703 return createNumber(lineNumber
, static_cast<NumberNode
*>(expr1
)->value() * static_cast<NumberNode
*>(expr2
)->value());
705 if (expr1
->isNumber() && static_cast<NumberNode
*>(expr1
)->value() == 1)
706 return new (m_globalData
) UnaryPlusNode(lineNumber
, expr2
);
708 if (expr2
->isNumber() && static_cast<NumberNode
*>(expr2
)->value() == 1)
709 return new (m_globalData
) UnaryPlusNode(lineNumber
, expr1
);
711 return new (m_globalData
) MultNode(lineNumber
, expr1
, expr2
, rightHasAssignments
);
714 ExpressionNode
* ASTBuilder::makeDivNode(int lineNumber
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
716 expr1
= expr1
->stripUnaryPlus();
717 expr2
= expr2
->stripUnaryPlus();
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
);
724 ExpressionNode
* ASTBuilder::makeModNode(int lineNumber
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
726 expr1
= expr1
->stripUnaryPlus();
727 expr2
= expr2
->stripUnaryPlus();
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
);
734 ExpressionNode
* ASTBuilder::makeAddNode(int lineNumber
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
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
);
741 ExpressionNode
* ASTBuilder::makeSubNode(int lineNumber
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
743 expr1
= expr1
->stripUnaryPlus();
744 expr2
= expr2
->stripUnaryPlus();
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
);
751 ExpressionNode
* ASTBuilder::makeLeftShiftNode(int lineNumber
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
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
);
758 ExpressionNode
* ASTBuilder::makeRightShiftNode(int lineNumber
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
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
);
765 ExpressionNode
* ASTBuilder::makeURightShiftNode(int lineNumber
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
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
);
772 ExpressionNode
* ASTBuilder::makeBitOrNode(int lineNumber
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
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
);
779 ExpressionNode
* ASTBuilder::makeBitAndNode(int lineNumber
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
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
);
786 ExpressionNode
* ASTBuilder::makeBitXOrNode(int lineNumber
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
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
);
793 ExpressionNode
* ASTBuilder::makeFunctionCallNode(int lineNumber
, ExpressionNode
* func
, ArgumentsNode
* args
, int start
, int divot
, int end
)
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
) {
802 return new (m_globalData
) EvalFunctionCallNode(lineNumber
, args
, divot
, divot
- start
, end
- divot
);
804 return new (m_globalData
) FunctionCallResolveNode(lineNumber
, identifier
, args
, divot
, divot
- start
, end
- divot
);
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());
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
);
820 node
= new (m_globalData
) FunctionCallDotNode(lineNumber
, dot
->base(), dot
->identifier(), args
, divot
, divot
- start
, end
- divot
);
821 node
->setSubexpressionInfo(dot
->divot(), dot
->endOffset());
825 ExpressionNode
* ASTBuilder::makeBinaryNode(int lineNumber
, int token
, pair
<ExpressionNode
*, BinaryOpInfo
> lhs
, pair
<ExpressionNode
*, BinaryOpInfo
> rhs
)
829 return new (m_globalData
) LogicalOpNode(lineNumber
, lhs
.first
, rhs
.first
, OpLogicalOr
);
832 return new (m_globalData
) LogicalOpNode(lineNumber
, lhs
.first
, rhs
.first
, OpLogicalAnd
);
835 return makeBitOrNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
838 return makeBitXOrNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
841 return makeBitAndNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
844 return new (m_globalData
) EqualNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
847 return new (m_globalData
) NotEqualNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
850 return new (m_globalData
) StrictEqualNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
853 return new (m_globalData
) NotStrictEqualNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
856 return new (m_globalData
) LessNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
859 return new (m_globalData
) GreaterNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
862 return new (m_globalData
) LessEqNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
865 return new (m_globalData
) GreaterEqNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
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
);
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
);
880 return makeLeftShiftNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
883 return makeRightShiftNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
886 return makeURightShiftNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
889 return makeAddNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
892 return makeSubNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
895 return makeMultNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
898 return makeDivNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
901 return makeModNode(lineNumber
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
907 ExpressionNode
* ASTBuilder::makeAssignNode(int lineNumber
, ExpressionNode
* loc
, Operator op
, ExpressionNode
* expr
, bool locHasAssignments
, bool exprHasAssignments
, int start
, int divot
, int end
)
909 if (!loc
->isLocation())
910 return new (m_globalData
) AssignErrorNode(lineNumber
, loc
, op
, expr
, divot
, divot
- start
, end
- divot
);
912 if (loc
->isResolveNode()) {
913 ResolveNode
* resolve
= static_cast<ResolveNode
*>(loc
);
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
);
921 return new (m_globalData
) ReadModifyResolveNode(lineNumber
, resolve
->identifier(), op
, expr
, exprHasAssignments
, divot
, divot
- start
, end
- divot
);
923 if (loc
->isBracketAccessorNode()) {
924 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(loc
);
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());
931 ASSERT(loc
->isDotAccessorNode());
932 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(loc
);
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());
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());
944 ExpressionNode
* ASTBuilder::makePrefixNode(int lineNumber
, ExpressionNode
* expr
, Operator op
, int start
, int divot
, int end
)
946 if (!expr
->isLocation())
947 return new (m_globalData
) PrefixErrorNode(lineNumber
, expr
, op
, divot
, divot
- start
, end
- divot
);
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
);
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());
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());
966 ExpressionNode
* ASTBuilder::makePostfixNode(int lineNumber
, ExpressionNode
* expr
, Operator op
, int start
, int divot
, int end
)
968 if (!expr
->isLocation())
969 return new (m_globalData
) PostfixErrorNode(lineNumber
, expr
, op
, divot
, divot
- start
, end
- divot
);
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
);
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());
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());