Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
3 : * This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : /*
8 : * A variant-like class abstracting operations on a Parser with a given ParseHandler but
9 : * unspecified character type.
10 : */
11 :
12 : #ifndef frontend_EitherParser_h
13 : #define frontend_EitherParser_h
14 :
15 : #include "mozilla/Attributes.h"
16 : #include "mozilla/IndexSequence.h"
17 : #include "mozilla/Move.h"
18 : #include "mozilla/Tuple.h"
19 : #include "mozilla/Variant.h"
20 :
21 : #include "frontend/Parser.h"
22 : #include "frontend/TokenStream.h"
23 :
24 : namespace js {
25 : namespace frontend {
26 :
27 : template<class ParseHandler>
28 13038 : class EitherParser
29 : {
30 : const mozilla::Variant<Parser<ParseHandler, char16_t>* const> parser;
31 :
32 : using Node = typename ParseHandler::Node;
33 :
34 : public:
35 : template<class Parser>
36 1691 : explicit EitherParser(Parser* parser) : parser(parser) {}
37 :
38 : private:
39 : struct TokenStreamMatcher
40 : {
41 : template<class Parser>
42 410271 : TokenStreamAnyChars& match(Parser* parser) {
43 410271 : return parser->tokenStream;
44 : }
45 : };
46 :
47 : public:
48 404882 : TokenStreamAnyChars& tokenStream() {
49 404882 : return parser.match(TokenStreamMatcher());
50 : }
51 :
52 5389 : const TokenStreamAnyChars& tokenStream() const {
53 5389 : return parser.match(TokenStreamMatcher());
54 : }
55 :
56 : private:
57 : struct ScriptSourceMatcher
58 : {
59 : template<class Parser>
60 2 : ScriptSource* match(Parser* parser) {
61 2 : return parser->ss;
62 : }
63 : };
64 :
65 : public:
66 2 : ScriptSource* ss() {
67 2 : return parser.match(ScriptSourceMatcher());
68 : }
69 :
70 : private:
71 : struct OptionsMatcher
72 : {
73 : template<class Parser>
74 12230 : const JS::ReadOnlyCompileOptions& match(Parser* parser) {
75 12230 : return parser->options();
76 : }
77 : };
78 :
79 : public:
80 12230 : const JS::ReadOnlyCompileOptions& options() {
81 12230 : return parser.match(OptionsMatcher());
82 : }
83 :
84 : private:
85 : struct ComputeErrorMetadataMatcher
86 : {
87 : ErrorMetadata* metadata;
88 : uint32_t offset;
89 :
90 0 : ComputeErrorMetadataMatcher(ErrorMetadata* metadata, uint32_t offset)
91 0 : : metadata(metadata), offset(offset)
92 0 : {}
93 :
94 : template<class Parser>
95 0 : MOZ_MUST_USE bool match(Parser* parser) {
96 0 : return parser->tokenStream.computeErrorMetadata(metadata, offset);
97 : }
98 : };
99 :
100 : public:
101 0 : MOZ_MUST_USE bool computeErrorMetadata(ErrorMetadata* metadata, uint32_t offset) {
102 0 : return parser.match(ComputeErrorMetadataMatcher(metadata, offset));
103 : }
104 :
105 : private:
106 : struct NewObjectBoxMatcher
107 : {
108 : JSObject* obj;
109 :
110 2009 : explicit NewObjectBoxMatcher(JSObject* obj) : obj(obj) {}
111 :
112 : template<class Parser>
113 2009 : ObjectBox* match(Parser* parser) {
114 2009 : return parser->newObjectBox(obj);
115 : }
116 : };
117 :
118 : public:
119 2009 : ObjectBox* newObjectBox(JSObject* obj) {
120 2009 : return parser.match(NewObjectBoxMatcher(obj));
121 : }
122 :
123 : private:
124 : struct SingleBindingFromDeclarationMatcher
125 : {
126 : Node decl;
127 :
128 408 : explicit SingleBindingFromDeclarationMatcher(Node decl) : decl(decl) {}
129 :
130 : template<class Parser>
131 408 : Node match(Parser* parser) {
132 408 : return parser->handler.singleBindingFromDeclaration(decl);
133 : }
134 : };
135 :
136 : public:
137 408 : Node singleBindingFromDeclaration(Node decl) {
138 408 : return parser.match(SingleBindingFromDeclarationMatcher(decl));
139 : }
140 :
141 : private:
142 : struct IsDeclarationListMatcher
143 : {
144 : Node node;
145 :
146 408 : explicit IsDeclarationListMatcher(Node node) : node(node) {}
147 :
148 : template<class Parser>
149 408 : bool match(Parser* parser) {
150 408 : return parser->handler.isDeclarationList(node);
151 : }
152 : };
153 :
154 : public:
155 408 : bool isDeclarationList(Node node) {
156 408 : return parser.match(IsDeclarationListMatcher(node));
157 : }
158 :
159 : private:
160 : struct IsSuperBaseMatcher
161 : {
162 : Node node;
163 :
164 13 : explicit IsSuperBaseMatcher(Node node) : node(node) {}
165 :
166 : template<class Parser>
167 13 : bool match(Parser* parser) {
168 13 : return parser->handler.isSuperBase(node);
169 : }
170 : };
171 :
172 : public:
173 13 : bool isSuperBase(Node node) {
174 13 : return parser.match(IsSuperBaseMatcher(node));
175 : }
176 :
177 : private:
178 : template<typename Function, class This, typename... Args, size_t... Indices>
179 : static auto
180 0 : CallGenericFunction(Function func, This* obj,
181 : mozilla::Tuple<Args...>& args, mozilla::IndexSequence<Indices...>)
182 : -> decltype(((*obj).*func)(mozilla::Get<Indices>(args)...))
183 : {
184 0 : return ((*obj).*func)(mozilla::Get<Indices>(args)...);
185 : }
186 :
187 : template<typename... StoredArgs>
188 : struct ReportErrorMatcher
189 : {
190 : mozilla::Tuple<StoredArgs...> args;
191 :
192 : template<typename... Args>
193 0 : explicit ReportErrorMatcher(Args&&... actualArgs)
194 0 : : args { mozilla::Forward<Args>(actualArgs)... }
195 0 : {}
196 :
197 : template<class Parser>
198 0 : void match(Parser* parser) {
199 0 : return CallGenericFunction(&TokenStream::reportError,
200 : &parser->tokenStream,
201 : args,
202 0 : typename mozilla::IndexSequenceFor<StoredArgs...>::Type());
203 : }
204 : };
205 :
206 : public:
207 : template<typename... Args>
208 0 : void reportError(Args&&... args) {
209 : ReportErrorMatcher<typename mozilla::Decay<Args>::Type...>
210 0 : matcher { mozilla::Forward<Args>(args)... };
211 0 : return parser.match(mozilla::Move(matcher));
212 : }
213 :
214 : private:
215 : struct ParserBaseMatcher
216 : {
217 : template<class Parser>
218 0 : ParserBase& match(Parser* parser) {
219 0 : return *parser;
220 : }
221 : };
222 :
223 : public:
224 : template<typename... Args>
225 0 : MOZ_MUST_USE bool reportNoOffset(Args&&... args) {
226 0 : return parser.match(ParserBaseMatcher()).reportNoOffset(mozilla::Forward<Args>(args)...);
227 : }
228 :
229 : private:
230 : template<typename... StoredArgs>
231 : struct ReportExtraWarningMatcher
232 : {
233 : mozilla::Tuple<StoredArgs...> args;
234 :
235 : template<typename... Args>
236 0 : explicit ReportExtraWarningMatcher(Args&&... actualArgs)
237 0 : : args { mozilla::Forward<Args>(actualArgs)... }
238 0 : {}
239 :
240 : template<class Parser>
241 0 : MOZ_MUST_USE bool match(Parser* parser) {
242 0 : return CallGenericFunction(&TokenStream::reportExtraWarningErrorNumberVA,
243 : &parser->tokenStream,
244 : args,
245 0 : typename mozilla::IndexSequenceFor<StoredArgs...>::Type());
246 : }
247 : };
248 :
249 : public:
250 : template<typename... Args>
251 0 : MOZ_MUST_USE bool reportExtraWarningErrorNumberVA(Args&&... args) {
252 : ReportExtraWarningMatcher<typename mozilla::Decay<Args>::Type...>
253 0 : matcher { mozilla::Forward<Args>(args)... };
254 0 : return parser.match(mozilla::Move(matcher));
255 : }
256 :
257 : private:
258 : template<typename... StoredArgs>
259 : struct ReportStrictModeErrorMatcher
260 : {
261 : mozilla::Tuple<StoredArgs...> args;
262 :
263 : template<typename... Args>
264 0 : explicit ReportStrictModeErrorMatcher(Args&&... actualArgs)
265 0 : : args { mozilla::Forward<Args>(actualArgs)... }
266 0 : {}
267 :
268 : template<class Parser>
269 0 : MOZ_MUST_USE bool match(Parser* parser) {
270 0 : return CallGenericFunction(&TokenStream::reportStrictModeErrorNumberVA,
271 : &parser->tokenStream,
272 : args,
273 0 : typename mozilla::IndexSequenceFor<StoredArgs...>::Type());
274 : }
275 : };
276 :
277 : public:
278 : template<typename... Args>
279 0 : MOZ_MUST_USE bool reportStrictModeErrorNumberVA(Args&&... args) {
280 : ReportStrictModeErrorMatcher<typename mozilla::Decay<Args>::Type...>
281 0 : matcher { mozilla::Forward<Args>(args)... };
282 0 : return parser.match(mozilla::Move(matcher));
283 : }
284 : };
285 :
286 : } /* namespace frontend */
287 : } /* namespace js */
288 :
289 : #endif /* frontend_EitherParser_h */
|