1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #include "qmljsevaluate.h"
27 #include "qmljscontext.h"
28 #include "qmljsscopechain.h"
29 #include "qmljsvalueowner.h"
30 #include "parser/qmljsast_p.h"
31 
32 #include <QDebug>
33 
34 using namespace QmlJS;
35 
36 /*!
37     \class QmlJS::Evaluate
38     \brief The Evaluate class evaluates \l{AST::Node}s to \l{Value}s.
39     \sa Value ScopeChain
40 
41     The Evaluate visitor is constructed with a ScopeChain and accepts JavaScript
42     expressions as well as some other AST::Nodes. It evaluates the expression in
43     the given ScopeChain and returns a Value representing the result.
44 
45     Example: Pass in the AST for "1 + 2" and NumberValue will be returned.
46 
47     In normal cases only the call operator (or the equivalent value() function)
48     will be used.
49 
50     The reference() function has the special behavior of not resolving \l{Reference}s
51     which can be useful when interested in the identity of a variable instead
52     of its value.
53 
54     Example: In a scope where "var a = 1"
55     \list
56     \li value(Identifier-a) will return NumberValue
57     \li reference(Identifier-a) will return the ASTVariableReference for the declaration of "a"
58     \endlist
59 */
60 
Evaluate(const ScopeChain * scopeChain,ReferenceContext * referenceContext)61 Evaluate::Evaluate(const ScopeChain *scopeChain, ReferenceContext *referenceContext)
62     : _valueOwner(scopeChain->context()->valueOwner()),
63       _context(scopeChain->context()),
64       _referenceContext(referenceContext),
65       _scopeChain(scopeChain),
66       _result(nullptr)
67 {
68 }
69 
~Evaluate()70 Evaluate::~Evaluate()
71 {
72 }
73 
operator ()(AST::Node * ast)74 const Value *Evaluate::operator()(AST::Node *ast)
75 {
76     return value(ast);
77 }
78 
value(AST::Node * ast)79 const Value *Evaluate::value(AST::Node *ast)
80 {
81     const Value *result = reference(ast);
82 
83     if (const Reference *ref = value_cast<Reference>(result)) {
84         if (_referenceContext)
85             result = _referenceContext->lookupReference(ref);
86         else
87             result = _context->lookupReference(ref);
88     }
89 
90     // if evaluation fails, return an unknown value
91     if (! result)
92         result = _valueOwner->unknownValue();
93 
94     return result;
95 }
96 
reference(AST::Node * ast)97 const Value *Evaluate::reference(AST::Node *ast)
98 {
99     // save the result
100     const Value *previousResult = switchResult(nullptr);
101 
102     // process the expression
103     accept(ast);
104 
105     // restore the previous result
106     return switchResult(previousResult);
107 }
108 
switchResult(const Value * result)109 const Value *Evaluate::switchResult(const Value *result)
110 {
111     const Value *previousResult = _result;
112     _result = result;
113     return previousResult;
114 }
115 
accept(AST::Node * node)116 void Evaluate::accept(AST::Node *node)
117 {
118     AST::Node::accept(node, this);
119 }
120 
visit(AST::UiProgram *)121 bool Evaluate::visit(AST::UiProgram *)
122 {
123     return false;
124 }
125 
visit(AST::UiHeaderItemList *)126 bool Evaluate::visit(AST::UiHeaderItemList *)
127 {
128     return false;
129 }
130 
visit(AST::UiPragma *)131 bool Evaluate::visit(AST::UiPragma *)
132 {
133     return false;
134 }
135 
visit(AST::UiImport *)136 bool Evaluate::visit(AST::UiImport *)
137 {
138     return false;
139 }
140 
visit(AST::UiPublicMember *)141 bool Evaluate::visit(AST::UiPublicMember *)
142 {
143     return false;
144 }
145 
visit(AST::UiSourceElement *)146 bool Evaluate::visit(AST::UiSourceElement *)
147 {
148     return false;
149 }
150 
visit(AST::UiObjectDefinition *)151 bool Evaluate::visit(AST::UiObjectDefinition *)
152 {
153     return false;
154 }
155 
visit(AST::UiObjectInitializer *)156 bool Evaluate::visit(AST::UiObjectInitializer *)
157 {
158     return false;
159 }
160 
visit(AST::UiObjectBinding *)161 bool Evaluate::visit(AST::UiObjectBinding *)
162 {
163     return false;
164 }
165 
visit(AST::UiScriptBinding *)166 bool Evaluate::visit(AST::UiScriptBinding *)
167 {
168     return false;
169 }
170 
visit(AST::UiArrayBinding *)171 bool Evaluate::visit(AST::UiArrayBinding *)
172 {
173     return false;
174 }
175 
visit(AST::UiObjectMemberList *)176 bool Evaluate::visit(AST::UiObjectMemberList *)
177 {
178     return false;
179 }
180 
visit(AST::UiArrayMemberList *)181 bool Evaluate::visit(AST::UiArrayMemberList *)
182 {
183     return false;
184 }
185 
visit(AST::UiQualifiedId * ast)186 bool Evaluate::visit(AST::UiQualifiedId *ast)
187 {
188     if (ast->name.isEmpty())
189          return false;
190 
191     const Value *value = _scopeChain->lookup(ast->name.toString());
192     if (! ast->next) {
193         _result = value;
194 
195     } else {
196         const ObjectValue *base = value_cast<ObjectValue>(value);
197 
198         for (AST::UiQualifiedId *it = ast->next; base && it; it = it->next) {
199             const QString &name = it->name.toString();
200             if (name.isEmpty())
201                 break;
202 
203             const Value *value = base->lookupMember(name, _context);
204             if (! it->next)
205                 _result = value;
206             else
207                 base = value_cast<ObjectValue>(value);
208         }
209     }
210 
211     return false;
212 }
213 
visit(AST::ThisExpression *)214 bool Evaluate::visit(AST::ThisExpression *)
215 {
216     return false;
217 }
218 
visit(AST::IdentifierExpression * ast)219 bool Evaluate::visit(AST::IdentifierExpression *ast)
220 {
221     if (ast->name.isEmpty())
222         return false;
223 
224     _result = _scopeChain->lookup(ast->name.toString());
225     return false;
226 }
227 
visit(AST::NullExpression *)228 bool Evaluate::visit(AST::NullExpression *)
229 {
230     _result = _valueOwner->nullValue();
231     return false;
232 }
233 
visit(AST::TrueLiteral *)234 bool Evaluate::visit(AST::TrueLiteral *)
235 {
236     _result = _valueOwner->booleanValue();
237     return false;
238 }
239 
visit(AST::FalseLiteral *)240 bool Evaluate::visit(AST::FalseLiteral *)
241 {
242     _result = _valueOwner->booleanValue();
243     return false;
244 }
245 
visit(AST::StringLiteral *)246 bool Evaluate::visit(AST::StringLiteral *)
247 {
248     _result = _valueOwner->stringValue();
249     return false;
250 }
251 
visit(AST::NumericLiteral *)252 bool Evaluate::visit(AST::NumericLiteral *)
253 {
254     _result = _valueOwner->numberValue();
255     return false;
256 }
257 
visit(AST::RegExpLiteral *)258 bool Evaluate::visit(AST::RegExpLiteral *)
259 {
260     _result = _valueOwner->regexpCtor()->returnValue();
261     return false;
262 }
263 
visit(AST::ArrayPattern *)264 bool Evaluate::visit(AST::ArrayPattern *)
265 {
266     _result = _valueOwner->arrayCtor()->returnValue();
267     return false;
268 }
269 
visit(AST::ObjectPattern *)270 bool Evaluate::visit(AST::ObjectPattern *)
271 {
272     // ### properties
273     _result = _valueOwner->newObject();
274     return false;
275 }
276 
visit(AST::PatternElementList *)277 bool Evaluate::visit(AST::PatternElementList *)
278 {
279     return false;
280 }
281 
visit(AST::Elision *)282 bool Evaluate::visit(AST::Elision *)
283 {
284     return false;
285 }
286 
visit(AST::PatternPropertyList *)287 bool Evaluate::visit(AST::PatternPropertyList *)
288 {
289     return false;
290 }
291 
visit(AST::PatternProperty *)292 bool Evaluate::visit(AST::PatternProperty *)
293 {
294     return false;
295 }
296 
visit(AST::NestedExpression *)297 bool Evaluate::visit(AST::NestedExpression *)
298 {
299     return true; // visit the child expression
300 }
301 
visit(AST::IdentifierPropertyName *)302 bool Evaluate::visit(AST::IdentifierPropertyName *)
303 {
304     return false;
305 }
306 
visit(AST::StringLiteralPropertyName *)307 bool Evaluate::visit(AST::StringLiteralPropertyName *)
308 {
309     return false;
310 }
311 
visit(AST::NumericLiteralPropertyName *)312 bool Evaluate::visit(AST::NumericLiteralPropertyName *)
313 {
314     return false;
315 }
316 
visit(AST::ArrayMemberExpression *)317 bool Evaluate::visit(AST::ArrayMemberExpression *)
318 {
319     return false;
320 }
321 
visit(AST::FieldMemberExpression * ast)322 bool Evaluate::visit(AST::FieldMemberExpression *ast)
323 {
324     if (ast->name.isEmpty())
325         return false;
326 
327     if (const Value *base = _valueOwner->convertToObject(value(ast->base))) {
328         if (const ObjectValue *obj = base->asObjectValue())
329             _result = obj->lookupMember(ast->name.toString(), _context);
330     }
331 
332     return false;
333 }
334 
visit(AST::NewMemberExpression * ast)335 bool Evaluate::visit(AST::NewMemberExpression *ast)
336 {
337     if (const FunctionValue *ctor = value_cast<FunctionValue>(value(ast->base)))
338         _result = ctor->returnValue();
339     return false;
340 }
341 
visit(AST::NewExpression * ast)342 bool Evaluate::visit(AST::NewExpression *ast)
343 {
344     if (const FunctionValue *ctor = value_cast<FunctionValue>(value(ast->expression)))
345         _result = ctor->returnValue();
346     return false;
347 }
348 
visit(AST::CallExpression * ast)349 bool Evaluate::visit(AST::CallExpression *ast)
350 {
351     if (const Value *base = value(ast->base)) {
352         if (const FunctionValue *obj = base->asFunctionValue())
353             _result = obj->returnValue();
354     }
355     return false;
356 }
357 
visit(AST::ArgumentList *)358 bool Evaluate::visit(AST::ArgumentList *)
359 {
360     return false;
361 }
362 
visit(AST::PostIncrementExpression *)363 bool Evaluate::visit(AST::PostIncrementExpression *)
364 {
365     _result = _valueOwner->numberValue();
366     return false;
367 }
368 
visit(AST::PostDecrementExpression *)369 bool Evaluate::visit(AST::PostDecrementExpression *)
370 {
371     _result = _valueOwner->numberValue();
372     return false;
373 }
374 
visit(AST::DeleteExpression *)375 bool Evaluate::visit(AST::DeleteExpression *)
376 {
377     _result = _valueOwner->booleanValue();
378     return false;
379 }
380 
visit(AST::VoidExpression *)381 bool Evaluate::visit(AST::VoidExpression *)
382 {
383     _result = _valueOwner->undefinedValue();
384     return false;
385 }
386 
visit(AST::TypeOfExpression *)387 bool Evaluate::visit(AST::TypeOfExpression *)
388 {
389     _result = _valueOwner->stringValue();
390     return false;
391 }
392 
visit(AST::PreIncrementExpression *)393 bool Evaluate::visit(AST::PreIncrementExpression *)
394 {
395     _result = _valueOwner->numberValue();
396     return false;
397 }
398 
visit(AST::PreDecrementExpression *)399 bool Evaluate::visit(AST::PreDecrementExpression *)
400 {
401     _result = _valueOwner->numberValue();
402     return false;
403 }
404 
visit(AST::UnaryPlusExpression *)405 bool Evaluate::visit(AST::UnaryPlusExpression *)
406 {
407     _result = _valueOwner->numberValue();
408     return false;
409 }
410 
visit(AST::UnaryMinusExpression *)411 bool Evaluate::visit(AST::UnaryMinusExpression *)
412 {
413     _result = _valueOwner->numberValue();
414     return false;
415 }
416 
visit(AST::TildeExpression *)417 bool Evaluate::visit(AST::TildeExpression *)
418 {
419     _result = _valueOwner->numberValue();
420     return false;
421 }
422 
visit(AST::NotExpression *)423 bool Evaluate::visit(AST::NotExpression *)
424 {
425     _result = _valueOwner->booleanValue();
426     return false;
427 }
428 
visit(AST::BinaryExpression * ast)429 bool Evaluate::visit(AST::BinaryExpression *ast)
430 {
431     const Value *lhs = nullptr;
432     const Value *rhs = nullptr;
433     switch (ast->op) {
434     case QSOperator::Add:
435     case QSOperator::InplaceAdd:
436     //case QSOperator::And: // ### enable once implemented below
437     //case QSOperator::Or:
438         lhs = value(ast->left);
439         Q_FALLTHROUGH();
440     case QSOperator::Assign:
441         rhs = value(ast->right);
442         break;
443     default:
444         break;
445     }
446 
447     switch (ast->op) {
448     case QSOperator::Add:
449     case QSOperator::InplaceAdd:
450         if (lhs->asStringValue() || rhs->asStringValue())
451             _result = _valueOwner->stringValue();
452         else
453             _result = _valueOwner->numberValue();
454         break;
455 
456     case QSOperator::Sub:
457     case QSOperator::InplaceSub:
458     case QSOperator::Mul:
459     case QSOperator::InplaceMul:
460     case QSOperator::Div:
461     case QSOperator::InplaceDiv:
462     case QSOperator::Mod:
463     case QSOperator::InplaceMod:
464     case QSOperator::BitAnd:
465     case QSOperator::InplaceAnd:
466     case QSOperator::BitXor:
467     case QSOperator::InplaceXor:
468     case QSOperator::BitOr:
469     case QSOperator::InplaceOr:
470     case QSOperator::LShift:
471     case QSOperator::InplaceLeftShift:
472     case QSOperator::RShift:
473     case QSOperator::InplaceRightShift:
474     case QSOperator::URShift:
475     case QSOperator::InplaceURightShift:
476         _result = _valueOwner->numberValue();
477         break;
478 
479     case QSOperator::Le:
480     case QSOperator::Ge:
481     case QSOperator::Lt:
482     case QSOperator::Gt:
483     case QSOperator::Equal:
484     case QSOperator::NotEqual:
485     case QSOperator::StrictEqual:
486     case QSOperator::StrictNotEqual:
487     case QSOperator::InstanceOf:
488     case QSOperator::In:
489         _result = _valueOwner->booleanValue();
490         break;
491 
492     case QSOperator::And:
493     case QSOperator::Or:
494         // ### either lhs or rhs
495         _result = _valueOwner->unknownValue();
496         break;
497 
498     case QSOperator::Assign:
499         _result = rhs;
500         break;
501 
502     default:
503         break;
504     }
505 
506     return false;
507 }
508 
visit(AST::ConditionalExpression *)509 bool Evaluate::visit(AST::ConditionalExpression *)
510 {
511     return false;
512 }
513 
visit(AST::Expression *)514 bool Evaluate::visit(AST::Expression *)
515 {
516     return false;
517 }
518 
visit(AST::Block *)519 bool Evaluate::visit(AST::Block *)
520 {
521     return false;
522 }
523 
visit(AST::VariableStatement *)524 bool Evaluate::visit(AST::VariableStatement *)
525 {
526     return false;
527 }
528 
visit(AST::VariableDeclarationList *)529 bool Evaluate::visit(AST::VariableDeclarationList *)
530 {
531     return false;
532 }
533 
visit(AST::PatternElement *)534 bool Evaluate::visit(AST::PatternElement *)
535 {
536     return false;
537 }
538 
visit(AST::EmptyStatement *)539 bool Evaluate::visit(AST::EmptyStatement *)
540 {
541     return false;
542 }
543 
visit(AST::ExpressionStatement *)544 bool Evaluate::visit(AST::ExpressionStatement *)
545 {
546     return true;
547 }
548 
visit(AST::IfStatement *)549 bool Evaluate::visit(AST::IfStatement *)
550 {
551     return false;
552 }
553 
visit(AST::DoWhileStatement *)554 bool Evaluate::visit(AST::DoWhileStatement *)
555 {
556     return false;
557 }
558 
visit(AST::WhileStatement *)559 bool Evaluate::visit(AST::WhileStatement *)
560 {
561     return false;
562 }
563 
visit(AST::ForStatement *)564 bool Evaluate::visit(AST::ForStatement *)
565 {
566     return false;
567 }
568 
visit(AST::ForEachStatement *)569 bool Evaluate::visit(AST::ForEachStatement *)
570 {
571     return false;
572 }
573 
visit(AST::ContinueStatement *)574 bool Evaluate::visit(AST::ContinueStatement *)
575 {
576     return false;
577 }
578 
visit(AST::BreakStatement *)579 bool Evaluate::visit(AST::BreakStatement *)
580 {
581     return false;
582 }
583 
visit(AST::ReturnStatement *)584 bool Evaluate::visit(AST::ReturnStatement *)
585 {
586     return true;
587 }
588 
visit(AST::WithStatement *)589 bool Evaluate::visit(AST::WithStatement *)
590 {
591     return false;
592 }
593 
visit(AST::SwitchStatement *)594 bool Evaluate::visit(AST::SwitchStatement *)
595 {
596     return false;
597 }
598 
visit(AST::CaseBlock *)599 bool Evaluate::visit(AST::CaseBlock *)
600 {
601     return false;
602 }
603 
visit(AST::CaseClauses *)604 bool Evaluate::visit(AST::CaseClauses *)
605 {
606     return false;
607 }
608 
visit(AST::CaseClause *)609 bool Evaluate::visit(AST::CaseClause *)
610 {
611     return false;
612 }
613 
visit(AST::DefaultClause *)614 bool Evaluate::visit(AST::DefaultClause *)
615 {
616     return false;
617 }
618 
visit(AST::LabelledStatement *)619 bool Evaluate::visit(AST::LabelledStatement *)
620 {
621     return false;
622 }
623 
visit(AST::ThrowStatement *)624 bool Evaluate::visit(AST::ThrowStatement *)
625 {
626     return false;
627 }
628 
visit(AST::TryStatement *)629 bool Evaluate::visit(AST::TryStatement *)
630 {
631     return false;
632 }
633 
visit(AST::Catch *)634 bool Evaluate::visit(AST::Catch *)
635 {
636     return false;
637 }
638 
visit(AST::Finally *)639 bool Evaluate::visit(AST::Finally *)
640 {
641     return false;
642 }
643 
visit(AST::FunctionDeclaration *)644 bool Evaluate::visit(AST::FunctionDeclaration *)
645 {
646     return false;
647 }
648 
visit(AST::FunctionExpression *)649 bool Evaluate::visit(AST::FunctionExpression *)
650 {
651     return false;
652 }
653 
visit(AST::FormalParameterList *)654 bool Evaluate::visit(AST::FormalParameterList *)
655 {
656     return false;
657 }
658 
visit(AST::Program *)659 bool Evaluate::visit(AST::Program *)
660 {
661     return false;
662 }
663 
visit(AST::StatementList *)664 bool Evaluate::visit(AST::StatementList *)
665 {
666     return false;
667 }
668 
visit(AST::DebuggerStatement *)669 bool Evaluate::visit(AST::DebuggerStatement *)
670 {
671     return false;
672 }
673 
throwRecursionDepthError()674 void Evaluate::throwRecursionDepthError()
675 {
676     qWarning("Evaluate hit maximum recursion error when visiting AST");
677 }
678