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 // No linting for pure C file
17 // NOLINTBEGIN
18
19 #include "public/es2panda_lib.h"
20 #include <algorithm>
21 #include <cstddef>
22 #include <iostream>
23
24 static es2panda_Impl const *impl = nullptr;
25 static const std::string mainName = "main";
26 static const std::string funcName1 = "foo";
27 static const std::string funcName2 = "goo";
28
29 extern "C" {
e2p_test_plugin_change_func_Initialize()30 void e2p_test_plugin_change_func_Initialize()
31 {
32 impl = es2panda_GetImpl(ES2PANDA_LIB_VERSION);
33 }
34
ChangeCall(es2panda_AstNode * node,void * arg)35 static void ChangeCall(es2panda_AstNode *node, void *arg)
36 {
37 es2panda_Context *ctx = static_cast<es2panda_Context *>(arg);
38 if (impl->IsCallExpression(node)) {
39 auto *callee = impl->CallExpressionCallee(ctx, node);
40 if (callee == nullptr || !impl->IsIdentifier(impl->CallExpressionCallee(ctx, node))) {
41 return;
42 }
43 std::string name = impl->IdentifierName(ctx, callee);
44 if (name == funcName1) {
45 auto *memForIdent = static_cast<char *>(impl->AllocMemory(ctx, funcName2.size() + 1, 1));
46 std::copy_n(funcName2.c_str(), funcName2.size() + 1, memForIdent);
47 auto *newIdent = impl->CreateIdentifier1(ctx, memForIdent);
48 impl->CallExpressionSetCallee(ctx, node, newIdent);
49 }
50 }
51 }
52
e2p_test_plugin_change_func_AfterParse(es2panda_Context * ctx)53 void e2p_test_plugin_change_func_AfterParse(es2panda_Context *ctx)
54 {
55 auto *ast = impl->ProgramAst(impl->ContextProgram(ctx));
56 std::cout << "Origin code (False Assert):" << std::endl;
57 std::cout << impl->AstNodeDumpEtsSrcConst(ctx, ast) << std::endl;
58 size_t n = 0;
59 auto **statements = impl->BlockStatementStatementsConst(ctx, ast, &n);
60 es2panda_AstNode *mainScriptFunc = nullptr;
61 for (size_t i = 0; i < n; i++) {
62 if (!impl->IsFunctionDeclaration(statements[i])) {
63 continue;
64 }
65 auto *scriptFunc = impl->FunctionDeclarationFunction(ctx, statements[i]);
66 if (scriptFunc != nullptr && impl->ScriptFunctionId(ctx, scriptFunc) != nullptr &&
67 impl->IdentifierName(ctx, impl->ScriptFunctionId(ctx, scriptFunc)) == mainName) {
68 mainScriptFunc = scriptFunc;
69 break;
70 }
71 }
72 if (mainScriptFunc == nullptr) {
73 return;
74 }
75 impl->AstNodeForEach(mainScriptFunc, ChangeCall, ctx);
76 std::cout << "Modified code (True Assert):" << std::endl;
77 std::cout << impl->AstNodeDumpEtsSrcConst(ctx, ast) << std::endl;
78 }
79
e2p_test_plugin_change_func_AfterCheck(es2panda_Context * ctx)80 void e2p_test_plugin_change_func_AfterCheck([[maybe_unused]] es2panda_Context *ctx) {}
81
e2p_test_plugin_change_func_AfterLowerings(es2panda_Context * ctx)82 void e2p_test_plugin_change_func_AfterLowerings([[maybe_unused]] es2panda_Context *ctx) {}
83 }
84
85 // NOLINTEND
86