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 "constStringToCharLowering.h"
17
18 #include "checker/ETSchecker.h"
19
20 namespace ark::es2panda::compiler {
21
Name() const22 std::string_view ConstStringToCharLowering::Name() const
23 {
24 return "ConstStringToCharLowering";
25 }
26
TryConvertToCharLiteral(checker::ETSChecker * checker,ir::AstNode * ast)27 ir::AstNode *TryConvertToCharLiteral(checker::ETSChecker *checker, ir::AstNode *ast)
28 {
29 if (!ast->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOX_TO_CHAR) || !ast->IsExpression() ||
30 ast->AsExpression()->TsType() == nullptr || !ast->AsExpression()->TsType()->IsETSStringType()) {
31 return nullptr;
32 }
33
34 auto type = ast->AsExpression()->TsType()->AsETSStringType();
35 if (!type->IsConstantType() || !type->GetValue().IsConvertibleToChar()) {
36 return nullptr;
37 }
38
39 auto parent = ast->Parent();
40 util::StringView::Iterator it(type->GetValue());
41 auto value = static_cast<char16_t>(it.PeekCp());
42
43 auto newValue = checker->Allocator()->New<ir::CharLiteral>(value);
44 newValue->SetParent(parent);
45 newValue->SetRange(ast->Range());
46 if (ast->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_CHAR)) {
47 newValue->AddBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_CHAR);
48 }
49
50 newValue->Check(checker);
51 return newValue;
52 }
53
Perform(public_lib::Context * const ctx,parser::Program * const program)54 bool ConstStringToCharLowering::Perform(public_lib::Context *const ctx, parser::Program *const program)
55 {
56 for (const auto &[_, ext_programs] : program->ExternalSources()) {
57 (void)_;
58 for (auto *const extProg : ext_programs) {
59 Perform(ctx, extProg);
60 }
61 }
62
63 auto *const checker = ctx->checker->AsETSChecker();
64
65 program->Ast()->TransformChildrenRecursively(
66 // CC-OFFNXT(G.FMT.14-CPP) project code style
67 [checker](ir::AstNode *ast) -> ir::AstNode * {
68 if (auto newValue = TryConvertToCharLiteral(checker, ast); newValue != nullptr) {
69 return newValue;
70 }
71
72 return ast;
73 },
74 Name());
75
76 return true;
77 }
78
79 } // namespace ark::es2panda::compiler
80