1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "evaluate/evaluateContext.h"
17#include "ir/base/classDefinition.h"
18#include "ir/base/methodDefinition.h"
19#include "ir/base/scriptFunction.h"
20#include "ir/expressions/functionExpression.h"
21#include "ir/statements/blockStatement.h"
22#include "ir/statements/classDeclaration.h"
23#include "parser/program/program.h"
24
25#include <algorithm>
26
27namespace ark::es2panda::evaluate {
28
29void EvaluateContext::FindEvaluationMethod(parser::Program *evalMethodProgram)
30{
31    ASSERT(evalMethodProgram);
32    auto &topLevelStatements = evalMethodProgram->Ast()->Statements();
33
34    // Find evaluation class.
35    auto evalClassDefIter = std::find_if(topLevelStatements.begin(), topLevelStatements.end(), [](auto *stmt) {
36        return stmt->IsClassDeclaration() &&
37               !stmt->AsClassDeclaration()->Definition()->Ident()->Name().Is(compiler::Signatures::ETS_GLOBAL);
38    });
39    ASSERT(evalClassDefIter != topLevelStatements.end());
40    auto *methodClass = (*evalClassDefIter)->AsClassDeclaration()->Definition();
41    const auto &expectedMethodName = methodClass->Ident()->Name();
42
43    // Find evaluation method.
44    auto evalMethodIter =
45        std::find_if(methodClass->Body().begin(), methodClass->Body().end(), [expectedMethodName](auto *iter) {
46            return iter->IsMethodDefinition() &&
47                   iter->AsMethodDefinition()->Key()->AsIdentifier()->Name() == expectedMethodName;
48        });
49    ASSERT(evalMethodIter != methodClass->Body().end());
50    auto *method = (*evalMethodIter)->AsMethodDefinition();
51    auto *scriptFunction = method->Value()->AsFunctionExpression()->Function();
52    ASSERT(scriptFunction != nullptr);
53
54    // Extract method statements and last statement.
55    methodStatements = scriptFunction->Body()->AsBlockStatement();
56    ASSERT(!methodStatements->Statements().empty());
57    auto *stmt = methodStatements->Statements().back();
58    if (stmt->IsExpressionStatement()) {
59        lastStatement = stmt->AsExpressionStatement();
60    }
61}
62
63}  // namespace ark::es2panda::evaluate
64