1 /*
2 * Copyright (c) 2021-2025 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/statements/annotationDeclaration.h"
22 #include "ir/ts/tsEnumDeclaration.h"
23 #include "ir/ts/tsInterfaceDeclaration.h"
24 #include "checker/types/ets/etsObjectType.h"
25 #include "generated/signatures.h"
26
27 namespace ark::es2panda::varbinder {
BoundContext(RecordTable * recordTable,ir::ClassDefinition * classDef,bool force)28 BoundContext::BoundContext(RecordTable *recordTable, ir::ClassDefinition *classDef, bool force)
29 : prev_(recordTable->boundCtx_),
30 recordTable_(recordTable),
31 currentRecord_(classDef),
32 savedRecord_(recordTable->record_)
33 {
34 if (classDef == nullptr || (!force && !recordTable_->classDefinitions_.insert(classDef).second)) {
35 return;
36 }
37
38 recordTable_->boundCtx_ = this;
39 recordTable_->record_ = classDef;
40 recordIdent_ = classDef->Ident();
41 if (classDef->InternalName().Empty()) {
42 classDef->SetInternalName(FormRecordName());
43 }
44 }
45
BoundContext(RecordTable * recordTable,ir::TSInterfaceDeclaration * interfaceDecl,bool force)46 BoundContext::BoundContext(RecordTable *recordTable, ir::TSInterfaceDeclaration *interfaceDecl, bool force)
47 : prev_(recordTable->boundCtx_),
48 recordTable_(recordTable),
49 currentRecord_(interfaceDecl),
50 savedRecord_(recordTable->record_)
51 {
52 if (interfaceDecl == nullptr || (!force && !recordTable_->interfaceDeclarations_.insert(interfaceDecl).second)) {
53 return;
54 }
55
56 recordTable_->boundCtx_ = this;
57 recordTable_->record_ = interfaceDecl;
58 recordIdent_ = interfaceDecl->Id();
59 if (interfaceDecl->InternalName().Empty()) {
60 interfaceDecl->SetInternalName(FormRecordName());
61 }
62 }
63
BoundContext(RecordTable * recordTable,ir::AnnotationDeclaration * annotationDecl,bool force)64 BoundContext::BoundContext(RecordTable *recordTable, ir::AnnotationDeclaration *annotationDecl, bool force)
65 : prev_(recordTable->boundCtx_),
66 recordTable_(recordTable),
67 currentRecord_(annotationDecl),
68 savedRecord_(recordTable->record_)
69 {
70 if (annotationDecl == nullptr || (!force && !recordTable_->annotationDeclarations_.insert(annotationDecl).second)) {
71 return;
72 }
73
74 recordTable_->boundCtx_ = this;
75 recordTable_->record_ = annotationDecl;
76 recordIdent_ = annotationDecl->GetBaseName();
77 if (annotationDecl->InternalName().Empty()) {
78 annotationDecl->SetInternalName(FormRecordName());
79 }
80 }
81
~BoundContext()82 BoundContext::~BoundContext()
83 {
84 recordTable_->record_ = savedRecord_;
85 recordTable_->boundCtx_ = prev_;
86 }
87
FormRecordName() const88 util::StringView BoundContext::FormRecordName() const
89 {
90 if (prev_ == nullptr) {
91 util::UString recordName(recordTable_->program_->Allocator());
92 recordName.Append(recordTable_->program_->ModulePrefix());
93 recordName.Append(recordIdent_->Name());
94 return recordName.View();
95 }
96
97 util::UString recordName(recordTable_->program_->Allocator());
98 recordName.Append(prev_->FormRecordName());
99 recordName.Append(compiler::Signatures::METHOD_SEPARATOR);
100 if (std::holds_alternative<ir::ClassDefinition *>(currentRecord_)) {
101 const auto *classDef = std::get<ir::ClassDefinition *>(currentRecord_);
102 if (classDef->IsLocal()) {
103 recordName.Append(classDef->LocalPrefix());
104 }
105 }
106
107 recordName.Append(recordIdent_->Name());
108 return recordName.View();
109 }
110
RecordName() const111 util::StringView RecordTable::RecordName() const
112 {
113 if (std::holds_alternative<ir::ClassDefinition *>(record_)) {
114 return std::get<ir::ClassDefinition *>(record_)->InternalName();
115 }
116
117 ES2PANDA_ASSERT(std::holds_alternative<ir::TSInterfaceDeclaration *>(record_));
118 return std::get<ir::TSInterfaceDeclaration *>(record_)->InternalName();
119 }
120
121 } // namespace ark::es2panda::varbinder
122