71e871a8e98a686473a7ca7855133205207efe27
[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 "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, int, bool) { return 1; }
157     void setFunctionNameStart(int, int) { }
158     int createArguments() { return 1; }
159     int createArguments(int) { return 1; }
160     ExpressionType createSpreadExpression(const JSTokenLocation&, ExpressionType, int, int, int) { return 1; }
161     int createArgumentsList(const JSTokenLocation&, int) { return 1; }
162     int createArgumentsList(const JSTokenLocation&, int, int) { return 1; }
163     Property createProperty(const Identifier* name, int, PropertyNode::Type type, bool complete)
164     {
165         if (!complete)
166             return Property(type);
167         ASSERT(name);
168         return Property(name, type);
169     }
170     Property createProperty(VM* vm, double name, int, PropertyNode::Type type, bool complete)
171     {
172         if (!complete)
173             return Property(type);
174         return Property(&vm->parserArena->identifierArena().makeNumericIdentifier(vm, name), type);
175     }
176     Property createProperty(VM*, ExpressionNode*, int, PropertyNode::Type type, bool)
177     {
178         return Property(type);
179     }
180     int createPropertyList(const JSTokenLocation&, Property) { return 1; }
181     int createPropertyList(const JSTokenLocation&, Property, int) { return 1; }
182     int createElementList(int, int) { return 1; }
183     int createElementList(int, int, int) { return 1; }
184     int createFormalParameterList(DeconstructionPattern) { return 1; }
185     int createFormalParameterList(int, DeconstructionPattern) { return 1; }
186     int createClause(int, int) { return 1; }
187     int createClauseList(int) { return 1; }
188     int createClauseList(int, int) { return 1; }
189     void setUsesArguments(int) { }
190     int createFuncDeclStatement(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int) { return 1; }
191     int createBlockStatement(const JSTokenLocation&, int, int, int) { return 1; }
192     int createExprStatement(const JSTokenLocation&, int, int, int) { return 1; }
193     int createIfStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
194     int createIfStatement(const JSTokenLocation&, int, int, int, int, int) { return 1; }
195     int createForLoop(const JSTokenLocation&, int, int, int, int, int, int) { return 1; }
196     int createForInLoop(const JSTokenLocation&, int, int, int, int, int, int, int, int) { return 1; }
197     int createForOfLoop(const JSTokenLocation&, int, int, int, int, int, int, int, int) { return 1; }
198     int createEmptyStatement(const JSTokenLocation&) { return 1; }
199     int createVarStatement(const JSTokenLocation&, int, int, int) { return 1; }
200     int createReturnStatement(const JSTokenLocation&, int, int, int) { return 1; }
201     int createBreakStatement(const JSTokenLocation&, int, int) { return 1; }
202     int createBreakStatement(const JSTokenLocation&, const Identifier*, int, int) { return 1; }
203     int createContinueStatement(const JSTokenLocation&, int, int) { return 1; }
204     int createContinueStatement(const JSTokenLocation&, const Identifier*, int, int) { return 1; }
205     int createTryStatement(const JSTokenLocation&, int, const Identifier*, int, int, int, int) { return 1; }
206     int createSwitchStatement(const JSTokenLocation&, int, int, int, int, int, int) { return 1; }
207     int createWhileStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
208     int createWithStatement(const JSTokenLocation&, int, int, int, int, int, int) { return 1; }
209     int createDoWhileStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
210     int createLabelStatement(const JSTokenLocation&, const Identifier*, int, int, int) { return 1; }
211     int createThrowStatement(const JSTokenLocation&, int, int, int) { return 1; }
212     int createDebugger(const JSTokenLocation&, int, int) { return 1; }
213     int createConstStatement(const JSTokenLocation&, int, int, int) { return 1; }
214     int appendConstDecl(const JSTokenLocation&, int, const Identifier*, int) { return 1; }
215     Property createGetterOrSetterProperty(const JSTokenLocation&, PropertyNode::Type type, bool strict, const Identifier* name, int, int, int, int, int, int, int)
216     {
217         ASSERT(name);
218         if (!strict)
219             return Property(type);
220         return Property(name, type);
221     }
222     Property createGetterOrSetterProperty(VM* vm, const JSTokenLocation&, PropertyNode::Type type, bool strict, double name, int, int, int, int, int, int, int)
223     {
224         if (!strict)
225             return Property(type);
226         return Property(&vm->parserArena->identifierArena().makeNumericIdentifier(vm, name), type);
227     }
228
229     void appendStatement(int, int) { }
230     void addVar(const Identifier*, bool) { }
231     int combineCommaNodes(const JSTokenLocation&, int, int) { return 1; }
232     int evalCount() const { return 0; }
233     void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, bool)
234     {
235         if (!m_topBinaryExpr)
236             m_topBinaryExpr = expr;
237         else
238             m_topBinaryExpr = BinaryExpr;
239         operandStackDepth++;
240     }
241     
242     // Logic to handle datastructures used during parsing of binary expressions
243     void operatorStackPop(int& operatorStackDepth) { operatorStackDepth--; }
244     bool operatorStackHasHigherPrecedence(int&, int) { return true; }
245     BinaryOperand getFromOperandStack(int) { return m_topBinaryExpr; }
246     void shrinkOperandStackBy(int& operandStackDepth, int amount) { operandStackDepth -= amount; }
247     void appendBinaryOperation(const JSTokenLocation&, int& operandStackDepth, int&, BinaryOperand, BinaryOperand) { operandStackDepth++; }
248     void operatorStackAppend(int& operatorStackDepth, int, int) { operatorStackDepth++; }
249     int popOperandStack(int&) { int res = m_topBinaryExpr; m_topBinaryExpr = 0; return res; }
250     
251     void appendUnaryToken(int& stackDepth, int tok, int) { stackDepth = 1; m_topUnaryToken = tok; }
252     int unaryTokenStackLastType(int&) { return m_topUnaryToken; }
253     JSTextPosition unaryTokenStackLastStart(int&) { return JSTextPosition(0, 0, 0); }
254     void unaryTokenStackRemoveLast(int& stackDepth) { stackDepth = 0; }
255     
256     void assignmentStackAppend(int, int, int, int, int, Operator) { }
257     int createAssignment(const JSTokenLocation&, int, int, int, int, int) { RELEASE_ASSERT_NOT_REACHED(); return 1; }
258     const Identifier* getName(const Property& property) const { ASSERT(property.name); return property.name; }
259     PropertyNode::Type getType(const Property& property) const { return property.type; }
260     bool isResolve(ExpressionType expr) const { return expr == ResolveExpr || expr == ResolveEvalExpr; }
261     ExpressionType createDeconstructingAssignment(const JSTokenLocation&, int, ExpressionType)
262     {
263         return 1;
264     }
265     
266     ArrayPattern createArrayPattern(const JSTokenLocation&)
267     {
268         return 1;
269     }
270     void appendArrayPatternSkipEntry(ArrayPattern, const JSTokenLocation&)
271     {
272     }
273     void appendArrayPatternEntry(ArrayPattern, const JSTokenLocation&, DeconstructionPattern)
274     {
275     }
276     ObjectPattern createObjectPattern(const JSTokenLocation&)
277     {
278         return 1;
279     }
280     void appendObjectPatternEntry(ArrayPattern, const JSTokenLocation&, bool, const Identifier&, DeconstructionPattern)
281     {
282     }
283     DeconstructionPattern createBindingLocation(const JSTokenLocation&, const Identifier&, const JSTextPosition&, const JSTextPosition&, const JSTextPosition&)
284     {
285         return 1;
286     }
287 private:
288     int m_topBinaryExpr;
289     int m_topUnaryToken;
290     Vector<int, 8> m_topBinaryExprs;
291     Vector<int, 8> m_topUnaryTokens;
292 };
293
294 }
295
296 #endif