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
, Lexer
* lexer
)
77 : m_globalData(globalData
)
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 token
, std::pair
<ExpressionNode
*, BinaryOpInfo
>, std::pair
<ExpressionNode
*, BinaryOpInfo
>);
116 ExpressionNode
* makeFunctionCallNode(ExpressionNode
* func
, ArgumentsNode
* args
, int start
, int divot
, int end
);
118 JSC::SourceElements
* createSourceElements() { return new (m_globalData
) JSC::SourceElements(m_globalData
); }
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(ExpressionNode
* lhs
, ExpressionNode
* rhs
) { return new (m_globalData
) CommaNode(m_globalData
, lhs
, rhs
); }
129 ExpressionNode
* makeAssignNode(ExpressionNode
* left
, Operator
, ExpressionNode
* right
, bool leftHasAssignments
, bool rightHasAssignments
, int start
, int divot
, int end
);
130 ExpressionNode
* makePrefixNode(ExpressionNode
*, Operator
, int start
, int divot
, int end
);
131 ExpressionNode
* makePostfixNode(ExpressionNode
*, Operator
, int start
, int divot
, int end
);
132 ExpressionNode
* makeTypeOfNode(ExpressionNode
*);
133 ExpressionNode
* makeDeleteNode(ExpressionNode
*, int start
, int divot
, int end
);
134 ExpressionNode
* makeNegateNode(ExpressionNode
*);
135 ExpressionNode
* makeBitwiseNotNode(ExpressionNode
*);
136 ExpressionNode
* makeMultNode(ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
137 ExpressionNode
* makeDivNode(ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
138 ExpressionNode
* makeModNode(ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
139 ExpressionNode
* makeAddNode(ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
140 ExpressionNode
* makeSubNode(ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
141 ExpressionNode
* makeBitXOrNode(ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
142 ExpressionNode
* makeBitAndNode(ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
143 ExpressionNode
* makeBitOrNode(ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
144 ExpressionNode
* makeLeftShiftNode(ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
145 ExpressionNode
* makeRightShiftNode(ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
146 ExpressionNode
* makeURightShiftNode(ExpressionNode
* left
, ExpressionNode
* right
, bool rightHasAssignments
);
148 ExpressionNode
* createLogicalNot(ExpressionNode
* expr
) { return new (m_globalData
) LogicalNotNode(m_globalData
, expr
); }
149 ExpressionNode
* createUnaryPlus(ExpressionNode
* expr
) { return new (m_globalData
) UnaryPlusNode(m_globalData
, expr
); }
150 ExpressionNode
* createVoid(ExpressionNode
* expr
)
153 return new (m_globalData
) VoidNode(m_globalData
, expr
);
155 ExpressionNode
* thisExpr()
158 return new (m_globalData
) ThisNode(m_globalData
);
160 ExpressionNode
* createResolve(const Identifier
* ident
, int start
)
162 if (m_globalData
->propertyNames
->arguments
== *ident
)
164 return new (m_globalData
) ResolveNode(m_globalData
, *ident
, start
);
166 ExpressionNode
* createObjectLiteral() { return new (m_globalData
) ObjectLiteralNode(m_globalData
); }
167 ExpressionNode
* createObjectLiteral(PropertyListNode
* properties
) { return new (m_globalData
) ObjectLiteralNode(m_globalData
, properties
); }
169 ExpressionNode
* createArray(int elisions
)
173 return new (m_globalData
) ArrayNode(m_globalData
, elisions
);
176 ExpressionNode
* createArray(ElementNode
* elems
) { return new (m_globalData
) ArrayNode(m_globalData
, elems
); }
177 ExpressionNode
* createArray(int elisions
, ElementNode
* elems
)
181 return new (m_globalData
) ArrayNode(m_globalData
, elisions
, elems
);
183 ExpressionNode
* createNumberExpr(double d
)
186 return new (m_globalData
) NumberNode(m_globalData
, d
);
189 ExpressionNode
* createString(const Identifier
* string
)
192 return new (m_globalData
) StringNode(m_globalData
, *string
);
195 ExpressionNode
* createBoolean(bool b
)
198 return new (m_globalData
) BooleanNode(m_globalData
, b
);
201 ExpressionNode
* createNull()
204 return new (m_globalData
) NullNode(m_globalData
);
207 ExpressionNode
* createBracketAccess(ExpressionNode
* base
, ExpressionNode
* property
, bool propertyHasAssignments
, int start
, int divot
, int end
)
209 BracketAccessorNode
* node
= new (m_globalData
) BracketAccessorNode(m_globalData
, base
, property
, propertyHasAssignments
);
210 setExceptionLocation(node
, start
, divot
, end
);
214 ExpressionNode
* createDotAccess(ExpressionNode
* base
, const Identifier
* property
, int start
, int divot
, int end
)
216 DotAccessorNode
* node
= new (m_globalData
) DotAccessorNode(m_globalData
, base
, *property
);
217 setExceptionLocation(node
, start
, divot
, end
);
221 ExpressionNode
* createRegExp(const Identifier
& pattern
, const Identifier
& flags
, int start
)
223 if (Yarr::checkSyntax(pattern
.ustring()))
225 RegExpNode
* node
= new (m_globalData
) RegExpNode(m_globalData
, pattern
, flags
);
226 int size
= pattern
.length() + 2; // + 2 for the two /'s
227 setExceptionLocation(node
, start
, start
+ size
, start
+ size
);
231 ExpressionNode
* createNewExpr(ExpressionNode
* expr
, ArgumentsNode
* arguments
, int start
, int divot
, int end
)
233 NewExprNode
* node
= new (m_globalData
) NewExprNode(m_globalData
, expr
, arguments
);
234 setExceptionLocation(node
, start
, divot
, end
);
238 ExpressionNode
* createNewExpr(ExpressionNode
* expr
, int start
, int end
)
240 NewExprNode
* node
= new (m_globalData
) NewExprNode(m_globalData
, expr
);
241 setExceptionLocation(node
, start
, end
, end
);
245 ExpressionNode
* createConditionalExpr(ExpressionNode
* condition
, ExpressionNode
* lhs
, ExpressionNode
* rhs
)
247 return new (m_globalData
) ConditionalNode(m_globalData
, condition
, lhs
, rhs
);
250 ExpressionNode
* createAssignResolve(const Identifier
& ident
, ExpressionNode
* rhs
, bool rhsHasAssignment
, int start
, int divot
, int end
)
252 AssignResolveNode
* node
= new (m_globalData
) AssignResolveNode(m_globalData
, ident
, rhs
, rhsHasAssignment
);
253 setExceptionLocation(node
, start
, divot
, end
);
257 ExpressionNode
* createFunctionExpr(const Identifier
* name
, FunctionBodyNode
* body
, ParameterNode
* parameters
, int openBracePos
, int closeBracePos
, int bodyStartLine
, int bodyEndLine
)
259 FuncExprNode
* result
= new (m_globalData
) FuncExprNode(m_globalData
, *name
, body
, m_lexer
->sourceCode(openBracePos
, closeBracePos
, bodyStartLine
), parameters
);
260 body
->setLoc(bodyStartLine
, bodyEndLine
);
264 FunctionBodyNode
* createFunctionBody(bool inStrictContext
)
267 return FunctionBodyNode::create(m_globalData
, inStrictContext
);
270 template <bool> PropertyNode
* createGetterOrSetterProperty(PropertyNode::Type type
, const Identifier
* name
, ParameterNode
* params
, FunctionBodyNode
* body
, int openBracePos
, int closeBracePos
, int bodyStartLine
, int bodyEndLine
)
273 body
->setLoc(bodyStartLine
, bodyEndLine
);
274 return new (m_globalData
) PropertyNode(m_globalData
, *name
, new (m_globalData
) FuncExprNode(m_globalData
, m_globalData
->propertyNames
->nullIdentifier
, body
, m_lexer
->sourceCode(openBracePos
, closeBracePos
, bodyStartLine
), params
), type
);
278 ArgumentsNode
* createArguments() { return new (m_globalData
) ArgumentsNode(m_globalData
); }
279 ArgumentsNode
* createArguments(ArgumentListNode
* args
) { return new (m_globalData
) ArgumentsNode(m_globalData
, args
); }
280 ArgumentListNode
* createArgumentsList(ExpressionNode
* arg
) { return new (m_globalData
) ArgumentListNode(m_globalData
, arg
); }
281 ArgumentListNode
* createArgumentsList(ArgumentListNode
* args
, ExpressionNode
* arg
) { return new (m_globalData
) ArgumentListNode(m_globalData
, args
, arg
); }
283 template <bool> PropertyNode
* createProperty(const Identifier
* propertyName
, ExpressionNode
* node
, PropertyNode::Type type
) { return new (m_globalData
) PropertyNode(m_globalData
, *propertyName
, node
, type
); }
284 template <bool> PropertyNode
* createProperty(JSGlobalData
*, double propertyName
, ExpressionNode
* node
, PropertyNode::Type type
) { return new (m_globalData
) PropertyNode(m_globalData
, propertyName
, node
, type
); }
285 PropertyListNode
* createPropertyList(PropertyNode
* property
) { return new (m_globalData
) PropertyListNode(m_globalData
, property
); }
286 PropertyListNode
* createPropertyList(PropertyNode
* property
, PropertyListNode
* tail
) { return new (m_globalData
) PropertyListNode(m_globalData
, property
, tail
); }
288 ElementNode
* createElementList(int elisions
, ExpressionNode
* expr
) { return new (m_globalData
) ElementNode(m_globalData
, elisions
, expr
); }
289 ElementNode
* createElementList(ElementNode
* elems
, int elisions
, ExpressionNode
* expr
) { return new (m_globalData
) ElementNode(m_globalData
, elems
, elisions
, expr
); }
291 ParameterNode
* createFormalParameterList(const Identifier
& ident
) { return new (m_globalData
) ParameterNode(m_globalData
, ident
); }
292 ParameterNode
* createFormalParameterList(ParameterNode
* list
, const Identifier
& ident
) { return new (m_globalData
) ParameterNode(m_globalData
, list
, ident
); }
294 CaseClauseNode
* createClause(ExpressionNode
* expr
, JSC::SourceElements
* statements
) { return new (m_globalData
) CaseClauseNode(m_globalData
, expr
, statements
); }
295 ClauseListNode
* createClauseList(CaseClauseNode
* clause
) { return new (m_globalData
) ClauseListNode(m_globalData
, clause
); }
296 ClauseListNode
* createClauseList(ClauseListNode
* tail
, CaseClauseNode
* clause
) { return new (m_globalData
) ClauseListNode(m_globalData
, tail
, clause
); }
298 void setUsesArguments(FunctionBodyNode
* node
) { node
->setUsesArguments(); }
300 StatementNode
* createFuncDeclStatement(const Identifier
* name
, FunctionBodyNode
* body
, ParameterNode
* parameters
, int openBracePos
, int closeBracePos
, int bodyStartLine
, int bodyEndLine
)
302 FuncDeclNode
* decl
= new (m_globalData
) FuncDeclNode(m_globalData
, *name
, body
, m_lexer
->sourceCode(openBracePos
, closeBracePos
, bodyStartLine
), parameters
);
303 if (*name
== m_globalData
->propertyNames
->arguments
)
305 m_scope
.m_funcDeclarations
->data
.append(decl
->body());
306 body
->setLoc(bodyStartLine
, bodyEndLine
);
310 StatementNode
* createBlockStatement(JSC::SourceElements
* elements
, int startLine
, int endLine
)
312 BlockNode
* block
= new (m_globalData
) BlockNode(m_globalData
, elements
);
313 block
->setLoc(startLine
, endLine
);
317 StatementNode
* createExprStatement(ExpressionNode
* expr
, int start
, int end
)
319 ExprStatementNode
* result
= new (m_globalData
) ExprStatementNode(m_globalData
, expr
);
320 result
->setLoc(start
, end
);
324 StatementNode
* createIfStatement(ExpressionNode
* condition
, StatementNode
* trueBlock
, int start
, int end
)
326 IfNode
* result
= new (m_globalData
) IfNode(m_globalData
, condition
, trueBlock
);
327 result
->setLoc(start
, end
);
331 StatementNode
* createIfStatement(ExpressionNode
* condition
, StatementNode
* trueBlock
, StatementNode
* falseBlock
, int start
, int end
)
333 IfNode
* result
= new (m_globalData
) IfElseNode(m_globalData
, condition
, trueBlock
, falseBlock
);
334 result
->setLoc(start
, end
);
338 StatementNode
* createForLoop(ExpressionNode
* initializer
, ExpressionNode
* condition
, ExpressionNode
* iter
, StatementNode
* statements
, bool b
, int start
, int end
)
340 ForNode
* result
= new (m_globalData
) ForNode(m_globalData
, initializer
, condition
, iter
, statements
, b
);
341 result
->setLoc(start
, end
);
345 StatementNode
* createForInLoop(const Identifier
* ident
, ExpressionNode
* initializer
, ExpressionNode
* iter
, StatementNode
* statements
, int start
, int divot
, int end
, int initStart
, int initEnd
, int startLine
, int endLine
)
347 ForInNode
* result
= new (m_globalData
) ForInNode(m_globalData
, *ident
, initializer
, iter
, statements
, initStart
, initStart
- start
, initEnd
- initStart
);
348 result
->setLoc(startLine
, endLine
);
349 setExceptionLocation(result
, start
, divot
+ 1, end
);
353 StatementNode
* createForInLoop(ExpressionNode
* lhs
, ExpressionNode
* iter
, StatementNode
* statements
, int eStart
, int eDivot
, int eEnd
, int start
, int end
)
355 ForInNode
* result
= new (m_globalData
) ForInNode(m_globalData
, lhs
, iter
, statements
);
356 result
->setLoc(start
, end
);
357 setExceptionLocation(result
, eStart
, eDivot
, eEnd
);
361 StatementNode
* createEmptyStatement() { return new (m_globalData
) EmptyStatementNode(m_globalData
); }
363 StatementNode
* createVarStatement(ExpressionNode
* expr
, int start
, int end
)
365 StatementNode
* result
;
367 result
= new (m_globalData
) EmptyStatementNode(m_globalData
);
369 result
= new (m_globalData
) VarStatementNode(m_globalData
, expr
);
370 result
->setLoc(start
, end
);
374 StatementNode
* createReturnStatement(ExpressionNode
* expression
, int eStart
, int eEnd
, int startLine
, int endLine
)
376 ReturnNode
* result
= new (m_globalData
) ReturnNode(m_globalData
, expression
);
377 setExceptionLocation(result
, eStart
, eEnd
, eEnd
);
378 result
->setLoc(startLine
, endLine
);
382 StatementNode
* createBreakStatement(int eStart
, int eEnd
, int startLine
, int endLine
)
384 BreakNode
* result
= new (m_globalData
) BreakNode(m_globalData
);
385 setExceptionLocation(result
, eStart
, eEnd
, eEnd
);
386 result
->setLoc(startLine
, endLine
);
390 StatementNode
* createBreakStatement(const Identifier
* ident
, int eStart
, int eEnd
, int startLine
, int endLine
)
392 BreakNode
* result
= new (m_globalData
) BreakNode(m_globalData
, *ident
);
393 setExceptionLocation(result
, eStart
, eEnd
, eEnd
);
394 result
->setLoc(startLine
, endLine
);
398 StatementNode
* createContinueStatement(int eStart
, int eEnd
, int startLine
, int endLine
)
400 ContinueNode
* result
= new (m_globalData
) ContinueNode(m_globalData
);
401 setExceptionLocation(result
, eStart
, eEnd
, eEnd
);
402 result
->setLoc(startLine
, endLine
);
406 StatementNode
* createContinueStatement(const Identifier
* ident
, int eStart
, int eEnd
, int startLine
, int endLine
)
408 ContinueNode
* result
= new (m_globalData
) ContinueNode(m_globalData
, *ident
);
409 setExceptionLocation(result
, eStart
, eEnd
, eEnd
);
410 result
->setLoc(startLine
, endLine
);
414 StatementNode
* createTryStatement(StatementNode
* tryBlock
, const Identifier
* ident
, bool catchHasEval
, StatementNode
* catchBlock
, StatementNode
* finallyBlock
, int startLine
, int endLine
)
416 TryNode
* result
= new (m_globalData
) TryNode(m_globalData
, tryBlock
, *ident
, catchHasEval
, catchBlock
, finallyBlock
);
419 result
->setLoc(startLine
, endLine
);
423 StatementNode
* createSwitchStatement(ExpressionNode
* expr
, ClauseListNode
* firstClauses
, CaseClauseNode
* defaultClause
, ClauseListNode
* secondClauses
, int startLine
, int endLine
)
425 CaseBlockNode
* cases
= new (m_globalData
) CaseBlockNode(m_globalData
, firstClauses
, defaultClause
, secondClauses
);
426 SwitchNode
* result
= new (m_globalData
) SwitchNode(m_globalData
, expr
, cases
);
427 result
->setLoc(startLine
, endLine
);
431 StatementNode
* createWhileStatement(ExpressionNode
* expr
, StatementNode
* statement
, int startLine
, int endLine
)
433 WhileNode
* result
= new (m_globalData
) WhileNode(m_globalData
, expr
, statement
);
434 result
->setLoc(startLine
, endLine
);
438 StatementNode
* createDoWhileStatement(StatementNode
* statement
, ExpressionNode
* expr
, int startLine
, int endLine
)
440 DoWhileNode
* result
= new (m_globalData
) DoWhileNode(m_globalData
, statement
, expr
);
441 result
->setLoc(startLine
, endLine
);
445 StatementNode
* createLabelStatement(const Identifier
* ident
, StatementNode
* statement
, int start
, int end
)
447 LabelNode
* result
= new (m_globalData
) LabelNode(m_globalData
, *ident
, statement
);
448 setExceptionLocation(result
, start
, end
, end
);
452 StatementNode
* createWithStatement(ExpressionNode
* expr
, StatementNode
* statement
, int start
, int end
, int startLine
, int endLine
)
455 WithNode
* result
= new (m_globalData
) WithNode(m_globalData
, expr
, statement
, end
, end
- start
);
456 result
->setLoc(startLine
, endLine
);
460 StatementNode
* createThrowStatement(ExpressionNode
* expr
, int start
, int end
, int startLine
, int endLine
)
462 ThrowNode
* result
= new (m_globalData
) ThrowNode(m_globalData
, expr
);
463 result
->setLoc(startLine
, endLine
);
464 setExceptionLocation(result
, start
, end
, end
);
468 StatementNode
* createDebugger(int startLine
, int endLine
)
470 DebuggerStatementNode
* result
= new (m_globalData
) DebuggerStatementNode(m_globalData
);
471 result
->setLoc(startLine
, endLine
);
475 StatementNode
* createConstStatement(ConstDeclNode
* decls
, int startLine
, int endLine
)
477 ConstStatementNode
* result
= new (m_globalData
) ConstStatementNode(m_globalData
, decls
);
478 result
->setLoc(startLine
, endLine
);
482 ConstDeclNode
* appendConstDecl(ConstDeclNode
* tail
, const Identifier
* name
, ExpressionNode
* initializer
)
484 ConstDeclNode
* result
= new (m_globalData
) ConstDeclNode(m_globalData
, *name
, initializer
);
486 tail
->m_next
= result
;
490 void appendStatement(JSC::SourceElements
* elements
, JSC::StatementNode
* statement
)
492 elements
->append(statement
);
495 void addVar(const Identifier
* ident
, int attrs
)
497 if (m_globalData
->propertyNames
->arguments
== *ident
)
499 m_scope
.m_varDeclarations
->data
.append(std::make_pair(ident
, attrs
));
502 ExpressionNode
* combineCommaNodes(ExpressionNode
* list
, ExpressionNode
* init
)
506 if (list
->isCommaNode()) {
507 static_cast<CommaNode
*>(list
)->append(init
);
510 return new (m_globalData
) CommaNode(m_globalData
, list
, init
);
513 int evalCount() const { return m_evalCount
; }
515 void appendBinaryExpressionInfo(int& operandStackDepth
, ExpressionNode
* current
, int exprStart
, int lhs
, int rhs
, bool hasAssignments
)
518 m_binaryOperandStack
.append(std::make_pair(current
, BinaryOpInfo(exprStart
, lhs
, rhs
, hasAssignments
)));
521 // Logic to handle datastructures used during parsing of binary expressions
522 void operatorStackPop(int& operatorStackDepth
)
524 operatorStackDepth
--;
525 m_binaryOperatorStack
.removeLast();
527 bool operatorStackHasHigherPrecedence(int&, int precedence
)
529 return precedence
<= m_binaryOperatorStack
.last().second
;
531 const BinaryOperand
& getFromOperandStack(int i
) { return m_binaryOperandStack
[m_binaryOperandStack
.size() + i
]; }
532 void shrinkOperandStackBy(int& operandStackDepth
, int amount
)
534 operandStackDepth
-= amount
;
535 ASSERT(operandStackDepth
>= 0);
536 m_binaryOperandStack
.resize(m_binaryOperandStack
.size() - amount
);
538 void appendBinaryOperation(int& operandStackDepth
, int&, const BinaryOperand
& lhs
, const BinaryOperand
& rhs
)
541 m_binaryOperandStack
.append(std::make_pair(makeBinaryNode(m_binaryOperatorStack
.last().first
, lhs
, rhs
), BinaryOpInfo(lhs
.second
, rhs
.second
)));
543 void operatorStackAppend(int& operatorStackDepth
, int op
, int precedence
)
545 operatorStackDepth
++;
546 m_binaryOperatorStack
.append(std::make_pair(op
, precedence
));
548 ExpressionNode
* popOperandStack(int&)
550 ExpressionNode
* result
= m_binaryOperandStack
.last().first
;
551 m_binaryOperandStack
.removeLast();
555 void appendUnaryToken(int& tokenStackDepth
, int type
, int start
)
558 m_unaryTokenStack
.append(std::make_pair(type
, start
));
561 int unaryTokenStackLastType(int&)
563 return m_unaryTokenStack
.last().first
;
566 int unaryTokenStackLastStart(int&)
568 return m_unaryTokenStack
.last().second
;
571 void unaryTokenStackRemoveLast(int& tokenStackDepth
)
574 m_unaryTokenStack
.removeLast();
577 void assignmentStackAppend(int& assignmentStackDepth
, ExpressionNode
* node
, int start
, int divot
, int assignmentCount
, Operator op
)
579 assignmentStackDepth
++;
580 m_assignmentInfoStack
.append(AssignmentInfo(node
, start
, divot
, assignmentCount
, op
));
583 ExpressionNode
* createAssignment(int& assignmentStackDepth
, ExpressionNode
* rhs
, int initialAssignmentCount
, int currentAssignmentCount
, int lastTokenEnd
)
585 ExpressionNode
* result
= makeAssignNode(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
);
586 m_assignmentInfoStack
.removeLast();
587 assignmentStackDepth
--;
591 const Identifier
& getName(Property property
) const { return property
->name(); }
592 PropertyNode::Type
getType(Property property
) const { return property
->type(); }
594 bool isResolve(ExpressionNode
* expr
) const { return expr
->isResolveNode(); }
598 Scope(JSGlobalData
* globalData
)
599 : m_varDeclarations(new (globalData
) ParserArenaData
<DeclarationStacks::VarStack
>)
600 , m_funcDeclarations(new (globalData
) ParserArenaData
<DeclarationStacks::FunctionStack
>)
605 ParserArenaData
<DeclarationStacks::VarStack
>* m_varDeclarations
;
606 ParserArenaData
<DeclarationStacks::FunctionStack
>* m_funcDeclarations
;
611 static void setExceptionLocation(ThrowableExpressionData
* node
, unsigned start
, unsigned divot
, unsigned end
)
613 node
->setExceptionSourceCode(divot
, divot
- start
, end
- divot
);
616 void incConstants() { m_scope
.m_numConstants
++; }
617 void usesThis() { m_scope
.m_features
|= ThisFeature
; }
618 void usesCatch() { m_scope
.m_features
|= CatchFeature
; }
619 void usesClosures() { m_scope
.m_features
|= ClosureFeature
; }
620 void usesArguments() { m_scope
.m_features
|= ArgumentsFeature
; }
621 void usesAssignment() { m_scope
.m_features
|= AssignFeature
; }
622 void usesWith() { m_scope
.m_features
|= WithFeature
; }
626 m_scope
.m_features
|= EvalFeature
;
628 ExpressionNode
* createNumber(double d
)
630 return new (m_globalData
) NumberNode(m_globalData
, d
);
633 JSGlobalData
* m_globalData
;
636 Vector
<BinaryOperand
, 10> m_binaryOperandStack
;
637 Vector
<AssignmentInfo
, 10> m_assignmentInfoStack
;
638 Vector
<pair
<int, int>, 10> m_binaryOperatorStack
;
639 Vector
<pair
<int, int>, 10> m_unaryTokenStack
;
643 ExpressionNode
* ASTBuilder::makeTypeOfNode(ExpressionNode
* expr
)
645 if (expr
->isResolveNode()) {
646 ResolveNode
* resolve
= static_cast<ResolveNode
*>(expr
);
647 return new (m_globalData
) TypeOfResolveNode(m_globalData
, resolve
->identifier());
649 return new (m_globalData
) TypeOfValueNode(m_globalData
, expr
);
652 ExpressionNode
* ASTBuilder::makeDeleteNode(ExpressionNode
* expr
, int start
, int divot
, int end
)
654 if (!expr
->isLocation())
655 return new (m_globalData
) DeleteValueNode(m_globalData
, expr
);
656 if (expr
->isResolveNode()) {
657 ResolveNode
* resolve
= static_cast<ResolveNode
*>(expr
);
658 return new (m_globalData
) DeleteResolveNode(m_globalData
, resolve
->identifier(), divot
, divot
- start
, end
- divot
);
660 if (expr
->isBracketAccessorNode()) {
661 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(expr
);
662 return new (m_globalData
) DeleteBracketNode(m_globalData
, bracket
->base(), bracket
->subscript(), divot
, divot
- start
, end
- divot
);
664 ASSERT(expr
->isDotAccessorNode());
665 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(expr
);
666 return new (m_globalData
) DeleteDotNode(m_globalData
, dot
->base(), dot
->identifier(), divot
, divot
- start
, end
- divot
);
669 ExpressionNode
* ASTBuilder::makeNegateNode(ExpressionNode
* n
)
672 NumberNode
* numberNode
= static_cast<NumberNode
*>(n
);
673 numberNode
->setValue(-numberNode
->value());
677 return new (m_globalData
) NegateNode(m_globalData
, n
);
680 ExpressionNode
* ASTBuilder::makeBitwiseNotNode(ExpressionNode
* expr
)
682 if (expr
->isNumber())
683 return createNumber(~toInt32(static_cast<NumberNode
*>(expr
)->value()));
684 return new (m_globalData
) BitwiseNotNode(m_globalData
, expr
);
687 ExpressionNode
* ASTBuilder::makeMultNode(ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
689 expr1
= expr1
->stripUnaryPlus();
690 expr2
= expr2
->stripUnaryPlus();
692 if (expr1
->isNumber() && expr2
->isNumber())
693 return createNumber(static_cast<NumberNode
*>(expr1
)->value() * static_cast<NumberNode
*>(expr2
)->value());
695 if (expr1
->isNumber() && static_cast<NumberNode
*>(expr1
)->value() == 1)
696 return new (m_globalData
) UnaryPlusNode(m_globalData
, expr2
);
698 if (expr2
->isNumber() && static_cast<NumberNode
*>(expr2
)->value() == 1)
699 return new (m_globalData
) UnaryPlusNode(m_globalData
, expr1
);
701 return new (m_globalData
) MultNode(m_globalData
, expr1
, expr2
, rightHasAssignments
);
704 ExpressionNode
* ASTBuilder::makeDivNode(ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
706 expr1
= expr1
->stripUnaryPlus();
707 expr2
= expr2
->stripUnaryPlus();
709 if (expr1
->isNumber() && expr2
->isNumber())
710 return createNumber(static_cast<NumberNode
*>(expr1
)->value() / static_cast<NumberNode
*>(expr2
)->value());
711 return new (m_globalData
) DivNode(m_globalData
, expr1
, expr2
, rightHasAssignments
);
714 ExpressionNode
* ASTBuilder::makeModNode(ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
716 expr1
= expr1
->stripUnaryPlus();
717 expr2
= expr2
->stripUnaryPlus();
719 if (expr1
->isNumber() && expr2
->isNumber())
720 return createNumber(fmod(static_cast<NumberNode
*>(expr1
)->value(), static_cast<NumberNode
*>(expr2
)->value()));
721 return new (m_globalData
) ModNode(m_globalData
, expr1
, expr2
, rightHasAssignments
);
724 ExpressionNode
* ASTBuilder::makeAddNode(ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
726 if (expr1
->isNumber() && expr2
->isNumber())
727 return createNumber(static_cast<NumberNode
*>(expr1
)->value() + static_cast<NumberNode
*>(expr2
)->value());
728 return new (m_globalData
) AddNode(m_globalData
, expr1
, expr2
, rightHasAssignments
);
731 ExpressionNode
* ASTBuilder::makeSubNode(ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
733 expr1
= expr1
->stripUnaryPlus();
734 expr2
= expr2
->stripUnaryPlus();
736 if (expr1
->isNumber() && expr2
->isNumber())
737 return createNumber(static_cast<NumberNode
*>(expr1
)->value() - static_cast<NumberNode
*>(expr2
)->value());
738 return new (m_globalData
) SubNode(m_globalData
, expr1
, expr2
, rightHasAssignments
);
741 ExpressionNode
* ASTBuilder::makeLeftShiftNode(ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
743 if (expr1
->isNumber() && expr2
->isNumber())
744 return createNumber(toInt32(static_cast<NumberNode
*>(expr1
)->value()) << (toUInt32(static_cast<NumberNode
*>(expr2
)->value()) & 0x1f));
745 return new (m_globalData
) LeftShiftNode(m_globalData
, expr1
, expr2
, rightHasAssignments
);
748 ExpressionNode
* ASTBuilder::makeRightShiftNode(ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
750 if (expr1
->isNumber() && expr2
->isNumber())
751 return createNumber(toInt32(static_cast<NumberNode
*>(expr1
)->value()) >> (toUInt32(static_cast<NumberNode
*>(expr2
)->value()) & 0x1f));
752 return new (m_globalData
) RightShiftNode(m_globalData
, expr1
, expr2
, rightHasAssignments
);
755 ExpressionNode
* ASTBuilder::makeURightShiftNode(ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
757 if (expr1
->isNumber() && expr2
->isNumber())
758 return createNumber(toUInt32(static_cast<NumberNode
*>(expr1
)->value()) >> (toUInt32(static_cast<NumberNode
*>(expr2
)->value()) & 0x1f));
759 return new (m_globalData
) UnsignedRightShiftNode(m_globalData
, expr1
, expr2
, rightHasAssignments
);
762 ExpressionNode
* ASTBuilder::makeBitOrNode(ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
764 if (expr1
->isNumber() && expr2
->isNumber())
765 return createNumber(toInt32(static_cast<NumberNode
*>(expr1
)->value()) | toInt32(static_cast<NumberNode
*>(expr2
)->value()));
766 return new (m_globalData
) BitOrNode(m_globalData
, expr1
, expr2
, rightHasAssignments
);
769 ExpressionNode
* ASTBuilder::makeBitAndNode(ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
771 if (expr1
->isNumber() && expr2
->isNumber())
772 return createNumber(toInt32(static_cast<NumberNode
*>(expr1
)->value()) & toInt32(static_cast<NumberNode
*>(expr2
)->value()));
773 return new (m_globalData
) BitAndNode(m_globalData
, expr1
, expr2
, rightHasAssignments
);
776 ExpressionNode
* ASTBuilder::makeBitXOrNode(ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
)
778 if (expr1
->isNumber() && expr2
->isNumber())
779 return createNumber(toInt32(static_cast<NumberNode
*>(expr1
)->value()) ^ toInt32(static_cast<NumberNode
*>(expr2
)->value()));
780 return new (m_globalData
) BitXOrNode(m_globalData
, expr1
, expr2
, rightHasAssignments
);
783 ExpressionNode
* ASTBuilder::makeFunctionCallNode(ExpressionNode
* func
, ArgumentsNode
* args
, int start
, int divot
, int end
)
785 if (!func
->isLocation())
786 return new (m_globalData
) FunctionCallValueNode(m_globalData
, func
, args
, divot
, divot
- start
, end
- divot
);
787 if (func
->isResolveNode()) {
788 ResolveNode
* resolve
= static_cast<ResolveNode
*>(func
);
789 const Identifier
& identifier
= resolve
->identifier();
790 if (identifier
== m_globalData
->propertyNames
->eval
) {
792 return new (m_globalData
) EvalFunctionCallNode(m_globalData
, args
, divot
, divot
- start
, end
- divot
);
794 return new (m_globalData
) FunctionCallResolveNode(m_globalData
, identifier
, args
, divot
, divot
- start
, end
- divot
);
796 if (func
->isBracketAccessorNode()) {
797 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(func
);
798 FunctionCallBracketNode
* node
= new (m_globalData
) FunctionCallBracketNode(m_globalData
, bracket
->base(), bracket
->subscript(), args
, divot
, divot
- start
, end
- divot
);
799 node
->setSubexpressionInfo(bracket
->divot(), bracket
->endOffset());
802 ASSERT(func
->isDotAccessorNode());
803 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(func
);
804 FunctionCallDotNode
* node
;
805 if (dot
->identifier() == m_globalData
->propertyNames
->call
)
806 node
= new (m_globalData
) CallFunctionCallDotNode(m_globalData
, dot
->base(), dot
->identifier(), args
, divot
, divot
- start
, end
- divot
);
807 else if (dot
->identifier() == m_globalData
->propertyNames
->apply
)
808 node
= new (m_globalData
) ApplyFunctionCallDotNode(m_globalData
, dot
->base(), dot
->identifier(), args
, divot
, divot
- start
, end
- divot
);
810 node
= new (m_globalData
) FunctionCallDotNode(m_globalData
, dot
->base(), dot
->identifier(), args
, divot
, divot
- start
, end
- divot
);
811 node
->setSubexpressionInfo(dot
->divot(), dot
->endOffset());
815 ExpressionNode
* ASTBuilder::makeBinaryNode(int token
, pair
<ExpressionNode
*, BinaryOpInfo
> lhs
, pair
<ExpressionNode
*, BinaryOpInfo
> rhs
)
819 return new (m_globalData
) LogicalOpNode(m_globalData
, lhs
.first
, rhs
.first
, OpLogicalOr
);
822 return new (m_globalData
) LogicalOpNode(m_globalData
, lhs
.first
, rhs
.first
, OpLogicalAnd
);
825 return makeBitOrNode(lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
828 return makeBitXOrNode(lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
831 return makeBitAndNode(lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
834 return new (m_globalData
) EqualNode(m_globalData
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
837 return new (m_globalData
) NotEqualNode(m_globalData
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
840 return new (m_globalData
) StrictEqualNode(m_globalData
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
843 return new (m_globalData
) NotStrictEqualNode(m_globalData
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
846 return new (m_globalData
) LessNode(m_globalData
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
849 return new (m_globalData
) GreaterNode(m_globalData
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
852 return new (m_globalData
) LessEqNode(m_globalData
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
855 return new (m_globalData
) GreaterEqNode(m_globalData
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
858 InstanceOfNode
* node
= new (m_globalData
) InstanceOfNode(m_globalData
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
859 setExceptionLocation(node
, lhs
.second
.start
, rhs
.second
.start
, rhs
.second
.end
);
864 InNode
* node
= new (m_globalData
) InNode(m_globalData
, lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
865 setExceptionLocation(node
, lhs
.second
.start
, rhs
.second
.start
, rhs
.second
.end
);
870 return makeLeftShiftNode(lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
873 return makeRightShiftNode(lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
876 return makeURightShiftNode(lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
879 return makeAddNode(lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
882 return makeSubNode(lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
885 return makeMultNode(lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
888 return makeDivNode(lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
891 return makeModNode(lhs
.first
, rhs
.first
, rhs
.second
.hasAssignment
);
897 ExpressionNode
* ASTBuilder::makeAssignNode(ExpressionNode
* loc
, Operator op
, ExpressionNode
* expr
, bool locHasAssignments
, bool exprHasAssignments
, int start
, int divot
, int end
)
900 if (!loc
->isLocation())
901 return new (m_globalData
) AssignErrorNode(m_globalData
, loc
, op
, expr
, divot
, divot
- start
, end
- divot
);
903 if (loc
->isResolveNode()) {
904 ResolveNode
* resolve
= static_cast<ResolveNode
*>(loc
);
906 AssignResolveNode
* node
= new (m_globalData
) AssignResolveNode(m_globalData
, resolve
->identifier(), expr
, exprHasAssignments
);
907 setExceptionLocation(node
, start
, divot
, end
);
910 return new (m_globalData
) ReadModifyResolveNode(m_globalData
, resolve
->identifier(), op
, expr
, exprHasAssignments
, divot
, divot
- start
, end
- divot
);
912 if (loc
->isBracketAccessorNode()) {
913 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(loc
);
915 return new (m_globalData
) AssignBracketNode(m_globalData
, bracket
->base(), bracket
->subscript(), expr
, locHasAssignments
, exprHasAssignments
, bracket
->divot(), bracket
->divot() - start
, end
- bracket
->divot());
916 ReadModifyBracketNode
* node
= new (m_globalData
) ReadModifyBracketNode(m_globalData
, bracket
->base(), bracket
->subscript(), op
, expr
, locHasAssignments
, exprHasAssignments
, divot
, divot
- start
, end
- divot
);
917 node
->setSubexpressionInfo(bracket
->divot(), bracket
->endOffset());
920 ASSERT(loc
->isDotAccessorNode());
921 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(loc
);
923 return new (m_globalData
) AssignDotNode(m_globalData
, dot
->base(), dot
->identifier(), expr
, exprHasAssignments
, dot
->divot(), dot
->divot() - start
, end
- dot
->divot());
925 ReadModifyDotNode
* node
= new (m_globalData
) ReadModifyDotNode(m_globalData
, dot
->base(), dot
->identifier(), op
, expr
, exprHasAssignments
, divot
, divot
- start
, end
- divot
);
926 node
->setSubexpressionInfo(dot
->divot(), dot
->endOffset());
930 ExpressionNode
* ASTBuilder::makePrefixNode(ExpressionNode
* expr
, Operator op
, int start
, int divot
, int end
)
933 if (!expr
->isLocation())
934 return new (m_globalData
) PrefixErrorNode(m_globalData
, expr
, op
, divot
, divot
- start
, end
- divot
);
936 if (expr
->isResolveNode()) {
937 ResolveNode
* resolve
= static_cast<ResolveNode
*>(expr
);
938 return new (m_globalData
) PrefixResolveNode(m_globalData
, resolve
->identifier(), op
, divot
, divot
- start
, end
- divot
);
940 if (expr
->isBracketAccessorNode()) {
941 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(expr
);
942 PrefixBracketNode
* node
= new (m_globalData
) PrefixBracketNode(m_globalData
, bracket
->base(), bracket
->subscript(), op
, divot
, divot
- start
, end
- divot
);
943 node
->setSubexpressionInfo(bracket
->divot(), bracket
->startOffset());
946 ASSERT(expr
->isDotAccessorNode());
947 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(expr
);
948 PrefixDotNode
* node
= new (m_globalData
) PrefixDotNode(m_globalData
, dot
->base(), dot
->identifier(), op
, divot
, divot
- start
, end
- divot
);
949 node
->setSubexpressionInfo(dot
->divot(), dot
->startOffset());
953 ExpressionNode
* ASTBuilder::makePostfixNode(ExpressionNode
* expr
, Operator op
, int start
, int divot
, int end
)
956 if (!expr
->isLocation())
957 return new (m_globalData
) PostfixErrorNode(m_globalData
, expr
, op
, divot
, divot
- start
, end
- divot
);
959 if (expr
->isResolveNode()) {
960 ResolveNode
* resolve
= static_cast<ResolveNode
*>(expr
);
961 return new (m_globalData
) PostfixResolveNode(m_globalData
, resolve
->identifier(), op
, divot
, divot
- start
, end
- divot
);
963 if (expr
->isBracketAccessorNode()) {
964 BracketAccessorNode
* bracket
= static_cast<BracketAccessorNode
*>(expr
);
965 PostfixBracketNode
* node
= new (m_globalData
) PostfixBracketNode(m_globalData
, bracket
->base(), bracket
->subscript(), op
, divot
, divot
- start
, end
- divot
);
966 node
->setSubexpressionInfo(bracket
->divot(), bracket
->endOffset());
970 ASSERT(expr
->isDotAccessorNode());
971 DotAccessorNode
* dot
= static_cast<DotAccessorNode
*>(expr
);
972 PostfixDotNode
* node
= new (m_globalData
) PostfixDotNode(m_globalData
, dot
->base(), dot
->identifier(), op
, divot
, divot
- start
, end
- divot
);
973 node
->setSubexpressionInfo(dot
->divot(), dot
->endOffset());