2 * Copyright (C) 2010, 2013 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.
26 #ifndef SyntaxChecker_h
27 #define SyntaxChecker_h
30 #include "ParserFunctionInfo.h"
31 #include "YarrSyntaxChecker.h"
37 struct BinaryExprContext
{
38 BinaryExprContext(SyntaxChecker
& context
)
41 m_context
->m_topBinaryExprs
.append(m_context
->m_topBinaryExpr
);
42 m_context
->m_topBinaryExpr
= 0;
46 m_context
->m_topBinaryExpr
= m_context
->m_topBinaryExprs
.last();
47 m_context
->m_topBinaryExprs
.removeLast();
50 SyntaxChecker
* m_context
;
52 struct UnaryExprContext
{
53 UnaryExprContext(SyntaxChecker
& context
)
56 m_context
->m_topUnaryTokens
.append(m_context
->m_topUnaryToken
);
57 m_context
->m_topUnaryToken
= 0;
61 m_context
->m_topUnaryToken
= m_context
->m_topUnaryTokens
.last();
62 m_context
->m_topUnaryTokens
.removeLast();
65 SyntaxChecker
* m_context
;
68 SyntaxChecker(VM
* , void*)
72 typedef SyntaxChecker FunctionBodyBuilder
;
74 ResolveEvalExpr
, ResolveExpr
, IntegerExpr
, DoubleExpr
, StringExpr
,
75 ThisExpr
, NullExpr
, BoolExpr
, RegExpExpr
, ObjectLiteralExpr
,
76 FunctionExpr
, ClassExpr
, SuperExpr
, BracketExpr
, DotExpr
, CallExpr
,
77 NewExpr
, PreExpr
, PostExpr
, UnaryExpr
, BinaryExpr
,
78 ConditionalExpr
, AssignmentExpr
, TypeofExpr
,
79 DeleteExpr
, ArrayLiteralExpr
, BindingDestructuring
,
80 ArrayDestructuring
, ObjectDestructuring
, SourceElementsResult
,
81 FunctionBodyResult
, SpreadExpr
, ArgumentsResult
,
82 PropertyListResult
, ArgumentsListResult
, ElementsListResult
,
83 StatementResult
, FormalParameterListResult
, ClauseResult
,
84 ClauseListResult
, CommaExpr
, DestructuringAssignment
,
85 TemplateStringResult
, TemplateStringListResult
,
86 TemplateExpressionListResult
, TemplateExpr
,
89 typedef int ExpressionType
;
91 typedef ExpressionType Expression
;
92 typedef int SourceElements
;
93 typedef int Arguments
;
94 typedef ExpressionType Comma
;
96 ALWAYS_INLINE
Property(void* = 0)
97 : type((PropertyNode::Type
)0)
100 ALWAYS_INLINE
Property(const Identifier
* ident
, PropertyNode::Type ty
)
105 ALWAYS_INLINE
Property(PropertyNode::Type ty
)
110 ALWAYS_INLINE
bool operator!() { return !type
; }
111 const Identifier
* name
;
112 PropertyNode::Type type
;
114 typedef int PropertyList
;
115 typedef int ElementList
;
116 typedef int ArgumentsList
;
117 #if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
118 typedef int TemplateExpressionList
;
119 typedef int TemplateString
;
120 typedef int TemplateStringList
;
121 typedef int TemplateLiteral
;
123 typedef int FormalParameterList
;
124 typedef int FunctionBody
;
125 #if ENABLE(ES6_CLASS_SYNTAX)
126 typedef int ClassExpression
;
128 typedef int Statement
;
129 typedef int ClauseList
;
131 typedef int ConstDeclList
;
132 typedef int BinaryOperand
;
133 typedef int DestructuringPattern
;
134 typedef DestructuringPattern ArrayPattern
;
135 typedef DestructuringPattern ObjectPattern
;
137 static const bool CreatesAST
= false;
138 static const bool NeedsFreeVariableInfo
= false;
139 static const bool CanUseFunctionCache
= true;
140 static const unsigned DontBuildKeywords
= LexexFlagsDontBuildKeywords
;
141 static const unsigned DontBuildStrings
= LexerFlagsDontBuildStrings
;
143 int createSourceElements() { return SourceElementsResult
; }
144 ExpressionType
makeFunctionCallNode(const JSTokenLocation
&, int, int, int, int, int) { return CallExpr
; }
145 ExpressionType
createCommaExpr(const JSTokenLocation
&, ExpressionType expr
) { return expr
; }
146 ExpressionType
appendToCommaExpr(const JSTokenLocation
&, ExpressionType
& head
, ExpressionType
, ExpressionType next
) { head
= next
; return next
; }
147 ExpressionType
makeAssignNode(const JSTokenLocation
&, ExpressionType
, Operator
, ExpressionType
, bool, bool, int, int, int) { return AssignmentExpr
; }
148 ExpressionType
makePrefixNode(const JSTokenLocation
&, ExpressionType
, Operator
, int, int, int) { return PreExpr
; }
149 ExpressionType
makePostfixNode(const JSTokenLocation
&, ExpressionType
, Operator
, int, int, int) { return PostExpr
; }
150 ExpressionType
makeTypeOfNode(const JSTokenLocation
&, ExpressionType
) { return TypeofExpr
; }
151 ExpressionType
makeDeleteNode(const JSTokenLocation
&, ExpressionType
, int, int, int) { return DeleteExpr
; }
152 ExpressionType
makeNegateNode(const JSTokenLocation
&, ExpressionType
) { return UnaryExpr
; }
153 ExpressionType
makeBitwiseNotNode(const JSTokenLocation
&, ExpressionType
) { return UnaryExpr
; }
154 ExpressionType
createLogicalNot(const JSTokenLocation
&, ExpressionType
) { return UnaryExpr
; }
155 ExpressionType
createUnaryPlus(const JSTokenLocation
&, ExpressionType
) { return UnaryExpr
; }
156 ExpressionType
createVoid(const JSTokenLocation
&, ExpressionType
) { return UnaryExpr
; }
157 ExpressionType
thisExpr(const JSTokenLocation
&, ThisTDZMode
) { return ThisExpr
; }
158 ExpressionType
superExpr(const JSTokenLocation
&) { return SuperExpr
; }
159 ExpressionType
createResolve(const JSTokenLocation
&, const Identifier
*, int) { return ResolveExpr
; }
160 ExpressionType
createObjectLiteral(const JSTokenLocation
&) { return ObjectLiteralExpr
; }
161 ExpressionType
createObjectLiteral(const JSTokenLocation
&, int) { return ObjectLiteralExpr
; }
162 ExpressionType
createArray(const JSTokenLocation
&, int) { return ArrayLiteralExpr
; }
163 ExpressionType
createArray(const JSTokenLocation
&, int, int) { return ArrayLiteralExpr
; }
164 ExpressionType
createDoubleExpr(const JSTokenLocation
&, double) { return DoubleExpr
; }
165 ExpressionType
createIntegerExpr(const JSTokenLocation
&, double) { return IntegerExpr
; }
166 ExpressionType
createString(const JSTokenLocation
&, const Identifier
*) { return StringExpr
; }
167 ExpressionType
createBoolean(const JSTokenLocation
&, bool) { return BoolExpr
; }
168 ExpressionType
createNull(const JSTokenLocation
&) { return NullExpr
; }
169 ExpressionType
createBracketAccess(const JSTokenLocation
&, ExpressionType
, ExpressionType
, bool, int, int, int) { return BracketExpr
; }
170 ExpressionType
createDotAccess(const JSTokenLocation
&, ExpressionType
, const Identifier
*, int, int, int) { return DotExpr
; }
171 ExpressionType
createRegExp(const JSTokenLocation
&, const Identifier
& pattern
, const Identifier
&, int) { return Yarr::checkSyntax(pattern
.string()) ? 0 : RegExpExpr
; }
172 ExpressionType
createNewExpr(const JSTokenLocation
&, ExpressionType
, int, int, int, int) { return NewExpr
; }
173 ExpressionType
createNewExpr(const JSTokenLocation
&, ExpressionType
, int, int) { return NewExpr
; }
174 ExpressionType
createConditionalExpr(const JSTokenLocation
&, ExpressionType
, ExpressionType
, ExpressionType
) { return ConditionalExpr
; }
175 ExpressionType
createAssignResolve(const JSTokenLocation
&, const Identifier
&, ExpressionType
, int, int, int) { return AssignmentExpr
; }
176 ExpressionType
createEmptyVarExpression(const JSTokenLocation
&, const Identifier
&) { return AssignmentExpr
; }
177 #if ENABLE(ES6_CLASS_SYNTAX)
178 ClassExpression
createClassExpr(const JSTokenLocation
&, const Identifier
&, ExpressionType
, ExpressionType
, PropertyList
, PropertyList
) { return ClassExpr
; }
180 ExpressionType
createFunctionExpr(const JSTokenLocation
&, const ParserFunctionInfo
<SyntaxChecker
>&) { return FunctionExpr
; }
181 int createFunctionBody(const JSTokenLocation
&, const JSTokenLocation
&, int, int, bool, int, int, int, ConstructorKind
) { return FunctionBodyResult
; }
182 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
183 ExpressionType
createArrowFunctionExpr(const JSTokenLocation
&, const ParserFunctionInfo
<SyntaxChecker
>&) { return FunctionExpr
; }
185 void setFunctionNameStart(int, int) { }
186 int createArguments() { return ArgumentsResult
; }
187 int createArguments(int) { return ArgumentsResult
; }
188 ExpressionType
createSpreadExpression(const JSTokenLocation
&, ExpressionType
, int, int, int) { return SpreadExpr
; }
189 #if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
190 TemplateString
createTemplateString(const JSTokenLocation
&, const Identifier
&, const Identifier
&) { return TemplateStringResult
; }
191 TemplateStringList
createTemplateStringList(TemplateString
) { return TemplateStringListResult
; }
192 TemplateStringList
createTemplateStringList(TemplateStringList
, TemplateString
) { return TemplateStringListResult
; }
193 TemplateExpressionList
createTemplateExpressionList(Expression
) { return TemplateExpressionListResult
; }
194 TemplateExpressionList
createTemplateExpressionList(TemplateExpressionList
, Expression
) { return TemplateExpressionListResult
; }
195 TemplateLiteral
createTemplateLiteral(const JSTokenLocation
&, TemplateStringList
) { return TemplateExpr
; }
196 TemplateLiteral
createTemplateLiteral(const JSTokenLocation
&, TemplateStringList
, TemplateExpressionList
) { return TemplateExpr
; }
197 ExpressionType
createTaggedTemplate(const JSTokenLocation
&, ExpressionType
, TemplateLiteral
, int, int, int) { return TaggedTemplateExpr
; }
200 int createArgumentsList(const JSTokenLocation
&, int) { return ArgumentsListResult
; }
201 int createArgumentsList(const JSTokenLocation
&, int, int) { return ArgumentsListResult
; }
202 Property
createProperty(const Identifier
* name
, int, PropertyNode::Type type
, PropertyNode::PutType
, bool complete
, SuperBinding
= SuperBinding::NotNeeded
)
205 return Property(type
);
207 return Property(name
, type
);
209 Property
createProperty(VM
* vm
, ParserArena
& parserArena
, double name
, int, PropertyNode::Type type
, PropertyNode::PutType
, bool complete
)
212 return Property(type
);
213 return Property(&parserArena
.identifierArena().makeNumericIdentifier(vm
, name
), type
);
215 Property
createProperty(int, int, PropertyNode::Type type
, PropertyNode::PutType
, bool)
217 return Property(type
);
219 int createPropertyList(const JSTokenLocation
&, Property
) { return PropertyListResult
; }
220 int createPropertyList(const JSTokenLocation
&, Property
, int) { return PropertyListResult
; }
221 int createElementList(int, int) { return ElementsListResult
; }
222 int createElementList(int, int, int) { return ElementsListResult
; }
223 int createFormalParameterList(DestructuringPattern
) { return FormalParameterListResult
; }
224 int createFormalParameterList(int, DestructuringPattern
) { return FormalParameterListResult
; }
225 int createClause(int, int) { return ClauseResult
; }
226 int createClauseList(int) { return ClauseListResult
; }
227 int createClauseList(int, int) { return ClauseListResult
; }
228 int createFuncDeclStatement(const JSTokenLocation
&, const ParserFunctionInfo
<SyntaxChecker
>&) { return StatementResult
; }
229 #if ENABLE(ES6_CLASS_SYNTAX)
230 int createClassDeclStatement(const JSTokenLocation
&, ClassExpression
,
231 const JSTextPosition
&, const JSTextPosition
&, int, int) { return StatementResult
; }
233 int createBlockStatement(const JSTokenLocation
&, int, int, int) { return StatementResult
; }
234 int createExprStatement(const JSTokenLocation
&, int, int, int) { return StatementResult
; }
235 int createIfStatement(const JSTokenLocation
&, int, int, int, int) { return StatementResult
; }
236 int createIfStatement(const JSTokenLocation
&, int, int, int, int, int) { return StatementResult
; }
237 int createForLoop(const JSTokenLocation
&, int, int, int, int, int, int) { return StatementResult
; }
238 int createForInLoop(const JSTokenLocation
&, int, int, int, int, int, int, int, int) { return StatementResult
; }
239 int createForOfLoop(const JSTokenLocation
&, int, int, int, int, int, int, int, int) { return StatementResult
; }
240 int createEmptyStatement(const JSTokenLocation
&) { return StatementResult
; }
241 int createVarStatement(const JSTokenLocation
&, int, int, int) { return StatementResult
; }
242 int createReturnStatement(const JSTokenLocation
&, int, int, int) { return StatementResult
; }
243 int createBreakStatement(const JSTokenLocation
&, int, int) { return StatementResult
; }
244 int createBreakStatement(const JSTokenLocation
&, const Identifier
*, int, int) { return StatementResult
; }
245 int createContinueStatement(const JSTokenLocation
&, int, int) { return StatementResult
; }
246 int createContinueStatement(const JSTokenLocation
&, const Identifier
*, int, int) { return StatementResult
; }
247 int createTryStatement(const JSTokenLocation
&, int, const Identifier
*, int, int, int, int) { return StatementResult
; }
248 int createSwitchStatement(const JSTokenLocation
&, int, int, int, int, int, int) { return StatementResult
; }
249 int createWhileStatement(const JSTokenLocation
&, int, int, int, int) { return StatementResult
; }
250 int createWithStatement(const JSTokenLocation
&, int, int, int, int, int, int) { return StatementResult
; }
251 int createDoWhileStatement(const JSTokenLocation
&, int, int, int, int) { return StatementResult
; }
252 int createLabelStatement(const JSTokenLocation
&, const Identifier
*, int, int, int) { return StatementResult
; }
253 int createThrowStatement(const JSTokenLocation
&, int, int, int) { return StatementResult
; }
254 int createDebugger(const JSTokenLocation
&, int, int) { return StatementResult
; }
255 int createConstStatement(const JSTokenLocation
&, int, int, int) { return StatementResult
; }
256 int appendConstDecl(const JSTokenLocation
&, int, const Identifier
*, int) { return StatementResult
; }
257 Property
createGetterOrSetterProperty(const JSTokenLocation
&, PropertyNode::Type type
, bool strict
, const Identifier
* name
, const ParserFunctionInfo
<SyntaxChecker
>&, SuperBinding
)
261 return Property(type
);
262 return Property(name
, type
);
264 Property
createGetterOrSetterProperty(VM
* vm
, ParserArena
& parserArena
, const JSTokenLocation
&, PropertyNode::Type type
, bool strict
, double name
, const ParserFunctionInfo
<SyntaxChecker
>&, SuperBinding
)
267 return Property(type
);
268 return Property(&parserArena
.identifierArena().makeNumericIdentifier(vm
, name
), type
);
271 void appendStatement(int, int) { }
272 void addVar(const Identifier
*, bool) { }
273 int combineCommaNodes(const JSTokenLocation
&, int, int) { return CommaExpr
; }
274 int evalCount() const { return 0; }
275 void appendBinaryExpressionInfo(int& operandStackDepth
, int expr
, int, int, int, bool)
277 if (!m_topBinaryExpr
)
278 m_topBinaryExpr
= expr
;
280 m_topBinaryExpr
= BinaryExpr
;
284 // Logic to handle datastructures used during parsing of binary expressions
285 void operatorStackPop(int& operatorStackDepth
) { operatorStackDepth
--; }
286 bool operatorStackHasHigherPrecedence(int&, int) { return true; }
287 BinaryOperand
getFromOperandStack(int) { return m_topBinaryExpr
; }
288 void shrinkOperandStackBy(int& operandStackDepth
, int amount
) { operandStackDepth
-= amount
; }
289 void appendBinaryOperation(const JSTokenLocation
&, int& operandStackDepth
, int&, BinaryOperand
, BinaryOperand
) { operandStackDepth
++; }
290 void operatorStackAppend(int& operatorStackDepth
, int, int) { operatorStackDepth
++; }
291 int popOperandStack(int&) { int res
= m_topBinaryExpr
; m_topBinaryExpr
= 0; return res
; }
293 void appendUnaryToken(int& stackDepth
, int tok
, int) { stackDepth
= 1; m_topUnaryToken
= tok
; }
294 int unaryTokenStackLastType(int&) { return m_topUnaryToken
; }
295 JSTextPosition
unaryTokenStackLastStart(int&) { return JSTextPosition(0, 0, 0); }
296 void unaryTokenStackRemoveLast(int& stackDepth
) { stackDepth
= 0; }
298 void assignmentStackAppend(int, int, int, int, int, Operator
) { }
299 int createAssignment(const JSTokenLocation
&, int, int, int, int, int) { RELEASE_ASSERT_NOT_REACHED(); return AssignmentExpr
; }
300 const Identifier
* getName(const Property
& property
) const { return property
.name
; }
301 PropertyNode::Type
getType(const Property
& property
) const { return property
.type
; }
302 bool isResolve(ExpressionType expr
) const { return expr
== ResolveExpr
|| expr
== ResolveEvalExpr
; }
303 ExpressionType
createDestructuringAssignment(const JSTokenLocation
&, int, ExpressionType
)
305 return DestructuringAssignment
;
308 ArrayPattern
createArrayPattern(const JSTokenLocation
&)
310 return ArrayDestructuring
;
312 void appendArrayPatternSkipEntry(ArrayPattern
, const JSTokenLocation
&)
315 void appendArrayPatternEntry(ArrayPattern
, const JSTokenLocation
&, DestructuringPattern
, int)
318 void appendArrayPatternRestEntry(ArrayPattern
, const JSTokenLocation
&, DestructuringPattern
)
321 void finishArrayPattern(ArrayPattern
, const JSTextPosition
&, const JSTextPosition
&, const JSTextPosition
&)
324 ObjectPattern
createObjectPattern(const JSTokenLocation
&)
326 return ObjectDestructuring
;
328 void appendObjectPatternEntry(ArrayPattern
, const JSTokenLocation
&, bool, const Identifier
&, DestructuringPattern
, int)
331 DestructuringPattern
createBindingLocation(const JSTokenLocation
&, const Identifier
&, const JSTextPosition
&, const JSTextPosition
&)
333 return BindingDestructuring
;
336 bool isBindingNode(DestructuringPattern pattern
)
338 return pattern
== BindingDestructuring
;
341 void setEndOffset(int, int) { }
342 int endOffset(int) { return 0; }
343 void setStartOffset(int, int) { }
348 Vector
<int, 8> m_topBinaryExprs
;
349 Vector
<int, 8> m_topUnaryTokens
;