• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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