Support for-of syntax
[WebKit-https.git] / Source / JavaScriptCore / parser / SyntaxChecker.h
1 /*
2  * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef SyntaxChecker_h
27 #define SyntaxChecker_h
28
29 #include "Lexer.h"
30 #include <yarr/YarrSyntaxChecker.h>
31
32 namespace JSC {
33     
34 class SyntaxChecker {
35 public:
36     struct BinaryExprContext {
37         BinaryExprContext(SyntaxChecker& context)
38             : m_context(&context)
39         {
40             m_context->m_topBinaryExprs.append(m_context->m_topBinaryExpr);
41             m_context->m_topBinaryExpr = 0;
42         }
43         ~BinaryExprContext()
44         {
45             m_context->m_topBinaryExpr = m_context->m_topBinaryExprs.last();
46             m_context->m_topBinaryExprs.removeLast();
47         }
48     private:
49         SyntaxChecker* m_context;
50     };
51     struct UnaryExprContext {
52         UnaryExprContext(SyntaxChecker& context)
53             : m_context(&context)
54         {
55             m_context->m_topUnaryTokens.append(m_context->m_topUnaryToken);
56             m_context->m_topUnaryToken = 0;
57         }
58         ~UnaryExprContext()
59         {
60             m_context->m_topUnaryToken = m_context->m_topUnaryTokens.last();
61             m_context->m_topUnaryTokens.removeLast();
62         }
63     private:
64         SyntaxChecker* m_context;
65     };
66     
67     SyntaxChecker(VM* , void*)
68     {
69     }
70
71     typedef SyntaxChecker FunctionBodyBuilder;
72     enum { NoneExpr = 0,
73         ResolveEvalExpr, ResolveExpr, NumberExpr, StringExpr,
74         ThisExpr, NullExpr, BoolExpr, RegExpExpr, ObjectLiteralExpr,
75         FunctionExpr, BracketExpr, DotExpr, CallExpr,
76         NewExpr, PreExpr, PostExpr, UnaryExpr, BinaryExpr,
77         ConditionalExpr, AssignmentExpr, TypeofExpr,
78         DeleteExpr, ArrayLiteralExpr };
79     typedef int ExpressionType;
80
81     typedef ExpressionType Expression;
82     typedef int SourceElements;
83     typedef int Arguments;
84     typedef ExpressionType Comma;
85     struct Property {
86         ALWAYS_INLINE Property(void* = 0)
87             : type((PropertyNode::Type)0)
88         {
89         }
90         ALWAYS_INLINE Property(const Identifier* ident, PropertyNode::Type ty)
91         : name(ident)
92         , type(ty)
93         {
94         }
95         ALWAYS_INLINE Property(PropertyNode::Type ty)
96             : name(0)
97             , type(ty)
98         {
99         }
100         ALWAYS_INLINE bool operator!() { return !type; }
101         const Identifier* name;
102         PropertyNode::Type type;
103     };
104     typedef int PropertyList;
105     typedef int ElementList;
106     typedef int ArgumentsList;
107     typedef int FormalParameterList;
108     typedef int FunctionBody;
109     typedef int Statement;
110     typedef int ClauseList;
111     typedef int Clause;
112     typedef int ConstDeclList;
113     typedef int BinaryOperand;
114     typedef int DeconstructionPattern;
115     typedef int ArrayPattern;
116     typedef int ObjectPattern;
117
118     static const bool CreatesAST = false;
119     static const bool NeedsFreeVariableInfo = false;
120     static const bool CanUseFunctionCache = true;
121     static const unsigned DontBuildKeywords = LexexFlagsDontBuildKeywords;
122     static const unsigned DontBuildStrings = LexerFlagsDontBuildStrings;
123
124     int createSourceElements() { return 1; }
125     ExpressionType makeFunctionCallNode(const JSTokenLocation&, int, int, int, int, int) { return CallExpr; }
126     void appendToComma(ExpressionType& base, ExpressionType right) { base = right; }
127     ExpressionType createCommaExpr(const JSTokenLocation&, ExpressionType, ExpressionType right) { return right; }
128     ExpressionType makeAssignNode(const JSTokenLocation&, ExpressionType, Operator, ExpressionType, bool, bool, int, int, int) { return AssignmentExpr; }
129     ExpressionType makePrefixNode(const JSTokenLocation&, ExpressionType, Operator, int, int, int) { return PreExpr; }
130     ExpressionType makePostfixNode(const JSTokenLocation&, ExpressionType, Operator, int, int, int) { return PostExpr; }
131     ExpressionType makeTypeOfNode(const JSTokenLocation&, ExpressionType) { return TypeofExpr; }
132     ExpressionType makeDeleteNode(const JSTokenLocation&, ExpressionType, int, int, int) { return DeleteExpr; }
133     ExpressionType makeNegateNode(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
134     ExpressionType makeBitwiseNotNode(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
135     ExpressionType createLogicalNot(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
136     ExpressionType createUnaryPlus(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
137     ExpressionType createVoid(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
138     ExpressionType thisExpr(const JSTokenLocation&) { return ThisExpr; }
139     ExpressionType createResolve(const JSTokenLocation&, const Identifier*, int) { return ResolveExpr; }
140     ExpressionType createObjectLiteral(const JSTokenLocation&) { return ObjectLiteralExpr; }
141     ExpressionType createObjectLiteral(const JSTokenLocation&, int) { return ObjectLiteralExpr; }
142     ExpressionType createArray(const JSTokenLocation&, int) { return ArrayLiteralExpr; }
143     ExpressionType createArray(const JSTokenLocation&, int, int) { return ArrayLiteralExpr; }
144     ExpressionType createNumberExpr(const JSTokenLocation&, double) { return NumberExpr; }
145     ExpressionType createString(const JSTokenLocation&, const Identifier*) { return StringExpr; }
146     ExpressionType createBoolean(const JSTokenLocation&, bool) { return BoolExpr; }
147     ExpressionType createNull(const JSTokenLocation&) { return NullExpr; }
148     ExpressionType createBracketAccess(const JSTokenLocation&, ExpressionType, ExpressionType, bool, int, int, int) { return BracketExpr; }
149     ExpressionType createDotAccess(const JSTokenLocation&, ExpressionType, const Identifier*, int, int, int) { return DotExpr; }
150     ExpressionType createRegExp(const JSTokenLocation&, const Identifier& pattern, const Identifier&, int) { return Yarr::checkSyntax(pattern.string()) ? 0 : RegExpExpr; }
151     ExpressionType createNewExpr(const JSTokenLocation&, ExpressionType, int, int, int, int) { return NewExpr; }
152     ExpressionType createNewExpr(const JSTokenLocation&, ExpressionType, int, int) { return NewExpr; }
153     ExpressionType createConditionalExpr(const JSTokenLocation&, ExpressionType, ExpressionType, ExpressionType) { return ConditionalExpr; }
154     ExpressionType createAssignResolve(const JSTokenLocation&, const Identifier&, ExpressionType, int, int, int) { return AssignmentExpr; }
155     ExpressionType createFunctionExpr(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int) { return FunctionExpr; }
156     int createFunctionBody(const JSTokenLocation&, const JSTokenLocation&, int, bool) { return 1; }
157     void setFunctionStart(int, int) { }
158     int createArguments() { return 1; }
159     int createArguments(int) { return 1; }
160     int createArgumentsList(const JSTokenLocation&, int) { return 1; }
161     int createArgumentsList(const JSTokenLocation&, int, int) { return 1; }
162     template <bool complete> Property createProperty(const Identifier* name, int, PropertyNode::Type type)
163     {
164         if (!complete)
165             return Property(type);
166         ASSERT(name);
167         return Property(name, type);
168     }
169     template <bool complete> Property createProperty(VM* vm, double name, int, PropertyNode::Type type)
170     {
171         if (!complete)
172             return Property(type);
173         return Property(&vm->parserArena->identifierArena().makeNumericIdentifier(vm, name), type);
174     }
175     int createPropertyList(const JSTokenLocation&, Property) { return 1; }
176     int createPropertyList(const JSTokenLocation&, Property, int) { return 1; }
177     int createElementList(int, int) { return 1; }
178     int createElementList(int, int, int) { return 1; }
179     int createFormalParameterList(DeconstructionPattern) { return 1; }
180     int createFormalParameterList(int, DeconstructionPattern) { return 1; }
181     int createClause(int, int) { return 1; }
182     int createClauseList(int) { return 1; }
183     int createClauseList(int, int) { return 1; }
184     void setUsesArguments(int) { }
185     int createFuncDeclStatement(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int) { return 1; }
186     int createBlockStatement(const JSTokenLocation&, int, int, int) { return 1; }
187     int createExprStatement(const JSTokenLocation&, int, int, int) { return 1; }
188     int createIfStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
189     int createIfStatement(const JSTokenLocation&, int, int, int, int, int) { return 1; }
190     int createForLoop(const JSTokenLocation&, int, int, int, int, int, int) { return 1; }
191     int createForInLoop(const JSTokenLocation&, int, int, int, int, int, int, int, int) { return 1; }
192     int createForOfLoop(const JSTokenLocation&, int, int, int, int, int, int, int, int) { return 1; }
193     int createEmptyStatement(const JSTokenLocation&) { return 1; }
194     int createVarStatement(const JSTokenLocation&, int, int, int) { return 1; }
195     int createReturnStatement(const JSTokenLocation&, int, int, int) { return 1; }
196     int createBreakStatement(const JSTokenLocation&, int, int) { return 1; }
197     int createBreakStatement(const JSTokenLocation&, const Identifier*, int, int) { return 1; }
198     int createContinueStatement(const JSTokenLocation&, int, int) { return 1; }
199     int createContinueStatement(const JSTokenLocation&, const Identifier*, int, int) { return 1; }
200     int createTryStatement(const JSTokenLocation&, int, const Identifier*, int, int, int, int) { return 1; }
201     int createSwitchStatement(const JSTokenLocation&, int, int, int, int, int, int) { return 1; }
202     int createWhileStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
203     int createWithStatement(const JSTokenLocation&, int, int, int, int, int, int) { return 1; }
204     int createDoWhileStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
205     int createLabelStatement(const JSTokenLocation&, const Identifier*, int, int, int) { return 1; }
206     int createThrowStatement(const JSTokenLocation&, int, int, int) { return 1; }
207     int createDebugger(const JSTokenLocation&, int, int) { return 1; }
208     int createConstStatement(const JSTokenLocation&, int, int, int) { return 1; }
209     int appendConstDecl(const JSTokenLocation&, int, const Identifier*, int) { return 1; }
210     template <bool strict> Property createGetterOrSetterProperty(const JSTokenLocation&, PropertyNode::Type type, const Identifier* name, int, int, int, int, int, int, int)
211     {
212         ASSERT(name);
213         if (!strict)
214             return Property(type);
215         return Property(name, type);
216     }
217     template <bool strict> Property createGetterOrSetterProperty(VM* vm, const JSTokenLocation&, PropertyNode::Type type, double name, int, int, int, int, int, int, int)
218     {
219         if (!strict)
220             return Property(type);
221         return Property(&vm->parserArena->identifierArena().makeNumericIdentifier(vm, name), type);
222     }
223
224     void appendStatement(int, int) { }
225     void addVar(const Identifier*, bool) { }
226     int combineCommaNodes(const JSTokenLocation&, int, int) { return 1; }
227     int evalCount() const { return 0; }
228     void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, bool)
229     {
230         if (!m_topBinaryExpr)
231             m_topBinaryExpr = expr;
232         else
233             m_topBinaryExpr = BinaryExpr;
234         operandStackDepth++;
235     }
236     
237     // Logic to handle datastructures used during parsing of binary expressions
238     void operatorStackPop(int& operatorStackDepth) { operatorStackDepth--; }
239     bool operatorStackHasHigherPrecedence(int&, int) { return true; }
240     BinaryOperand getFromOperandStack(int) { return m_topBinaryExpr; }
241     void shrinkOperandStackBy(int& operandStackDepth, int amount) { operandStackDepth -= amount; }
242     void appendBinaryOperation(const JSTokenLocation&, int& operandStackDepth, int&, BinaryOperand, BinaryOperand) { operandStackDepth++; }
243     void operatorStackAppend(int& operatorStackDepth, int, int) { operatorStackDepth++; }
244     int popOperandStack(int&) { int res = m_topBinaryExpr; m_topBinaryExpr = 0; return res; }
245     
246     void appendUnaryToken(int& stackDepth, int tok, int) { stackDepth = 1; m_topUnaryToken = tok; }
247     int unaryTokenStackLastType(int&) { return m_topUnaryToken; }
248     JSTextPosition unaryTokenStackLastStart(int&) { return JSTextPosition(0, 0, 0); }
249     void unaryTokenStackRemoveLast(int& stackDepth) { stackDepth = 0; }
250     
251     void assignmentStackAppend(int, int, int, int, int, Operator) { }
252     int createAssignment(const JSTokenLocation&, int, int, int, int, int) { RELEASE_ASSERT_NOT_REACHED(); return 1; }
253     const Identifier& getName(const Property& property) const { ASSERT(property.name); return *property.name; }
254     PropertyNode::Type getType(const Property& property) const { return property.type; }
255     bool isResolve(ExpressionType expr) const { return expr == ResolveExpr || expr == ResolveEvalExpr; }
256     ExpressionType createDeconstructingAssignment(const JSTokenLocation&, int, ExpressionType)
257     {
258         return 1;
259     }
260     
261     ArrayPattern createArrayPattern(const JSTokenLocation&)
262     {
263         return 1;
264     }
265     void appendArrayPatternSkipEntry(ArrayPattern, const JSTokenLocation&)
266     {
267     }
268     void appendArrayPatternEntry(ArrayPattern, const JSTokenLocation&, DeconstructionPattern)
269     {
270     }
271     ObjectPattern createObjectPattern(const JSTokenLocation&)
272     {
273         return 1;
274     }
275     void appendObjectPatternEntry(ArrayPattern, const JSTokenLocation&, bool, const Identifier&, DeconstructionPattern)
276     {
277     }
278     DeconstructionPattern createBindingLocation(const JSTokenLocation&, const Identifier&, const JSTextPosition&, const JSTextPosition&, const JSTextPosition&)
279     {
280         return 1;
281     }
282 private:
283     int m_topBinaryExpr;
284     int m_topUnaryToken;
285     Vector<int, 8> m_topBinaryExprs;
286     Vector<int, 8> m_topUnaryTokens;
287 };
288
289 }
290
291 #endif