1 /*
2 * Copyright (c) 2021-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 "recordTable.h"
17 #include "parser/program/program.h"
18 #include "varbinder/ETSBinder.h"
19 #include "ir/base/classDefinition.h"
20 #include "ir/expressions/identifier.h"
21 #include "ir/ts/tsEnumDeclaration.h"
22 #include "ir/ts/tsInterfaceDeclaration.h"
23 #include "checker/types/ets/etsObjectType.h"
24 #include "generated/signatures.h"
25
26 namespace ark::es2panda::varbinder {
BoundContext(RecordTable *recordTable, ir::ClassDefinition *classDef, bool force)27 BoundContext::BoundContext(RecordTable *recordTable, ir::ClassDefinition *classDef, bool force)
28 : prev_(recordTable->boundCtx_),
29 recordTable_(recordTable),
30 currentRecord_(classDef),
31 savedRecord_(recordTable->record_)
32 {
33 if (classDef == nullptr || (!force && !recordTable_->classDefinitions_.insert(classDef).second)) {
34 return;
35 }
36
37 recordTable_->boundCtx_ = this;
38 recordTable_->record_ = classDef;
39 recordIdent_ = classDef->Ident();
40 if (classDef->InternalName().Empty()) {
41 classDef->SetInternalName(FormRecordName());
42 }
43 }
44
BoundContext(RecordTable *recordTable, ir::TSInterfaceDeclaration *interfaceDecl, bool force)45 BoundContext::BoundContext(RecordTable *recordTable, ir::TSInterfaceDeclaration *interfaceDecl, bool force)
46 : prev_(recordTable->boundCtx_),
47 recordTable_(recordTable),
48 currentRecord_(interfaceDecl),
49 savedRecord_(recordTable->record_)
50 {
51 if (interfaceDecl == nullptr || (!force && !recordTable_->interfaceDeclarations_.insert(interfaceDecl).second)) {
52 return;
53 }
54
55 recordTable_->boundCtx_ = this;
56 recordTable_->record_ = interfaceDecl;
57 recordIdent_ = interfaceDecl->Id();
58 if (interfaceDecl->InternalName() == "") {
59 interfaceDecl->SetInternalName(FormRecordName());
60 }
61 }
62
~BoundContext()63 BoundContext::~BoundContext()
64 {
65 recordTable_->record_ = savedRecord_;
66 recordTable_->boundCtx_ = prev_;
67 }
68
FormRecordName() const69 util::StringView BoundContext::FormRecordName() const
70 {
71 if (prev_ == nullptr) {
72 if (recordTable_->program_->OmitModuleName()) {
73 return recordIdent_->Name();
74 }
75
76 const auto &moduleName = recordTable_->program_->ModuleName();
77
78 // concatenate the module name with the record ident
79 return util::UString(moduleName.Mutf8() + compiler::Signatures::METHOD_SEPARATOR.data() +
80 recordIdent_->Name().Mutf8(),
81 recordTable_->program_->Allocator())
82 .View();
83 }
84
85 util::UString recordName(recordTable_->program_->Allocator());
86 recordName.Append(prev_->FormRecordName());
87 recordName.Append(compiler::Signatures::METHOD_SEPARATOR);
88 if (std::holds_alternative<ir::ClassDefinition *>(currentRecord_)) {
89 const auto *classDef = std::get<ir::ClassDefinition *>(currentRecord_);
90 if (classDef->IsLocal()) {
91 recordName.Append(classDef->LocalPrefix());
92 }
93 }
94
95 recordName.Append(recordIdent_->Name());
96 return recordName.View();
97 }
98
RecordName() const99 util::StringView RecordTable::RecordName() const
100 {
101 if (std::holds_alternative<ir::ClassDefinition *>(record_)) {
102 return std::get<ir::ClassDefinition *>(record_)->InternalName();
103 }
104
105 ASSERT(std::holds_alternative<ir::TSInterfaceDeclaration *>(record_));
106 return std::get<ir::TSInterfaceDeclaration *>(record_)->InternalName();
107 }
108
109 } // namespace ark::es2panda::varbinder
110