• 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 "checker.h"
17 
18 #include "public/public.h"
19 #include "checker/types/globalTypesHolder.h"
20 #include "checker/types/ts/unionType.h"
21 
22 namespace ark::es2panda::checker {
Checker(util::DiagnosticEngine & diagnosticEngine,ArenaAllocator * programAllocator)23 Checker::Checker(util::DiagnosticEngine &diagnosticEngine, ArenaAllocator *programAllocator)
24     : allocator_(SpaceType::SPACE_TYPE_COMPILER, nullptr, true),
25       programAllocator_(programAllocator),
26       context_(this, CheckerStatus::NO_OPTS),
27       diagnosticEngine_(diagnosticEngine)
28 {
29     relation_ = ProgramAllocator()->New<TypeRelation>(this);
30     globalTypes_ = ProgramAllocator()->New<GlobalTypesHolder>(ProgramAllocator());
31 }
32 
Initialize(varbinder::VarBinder * varbinder)33 void Checker::Initialize(varbinder::VarBinder *varbinder)
34 {
35     varbinder_ = varbinder;
36     scope_ = varbinder_->TopScope();
37     program_ = varbinder_->Program();
38 }
39 
LogError(const diagnostic::DiagnosticKind & diagnostic,const util::DiagnosticMessageParams & diagnosticParams,const lexer::SourcePosition & pos)40 void Checker::LogError(const diagnostic::DiagnosticKind &diagnostic,
41                        const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos)
42 {
43     diagnosticEngine_.LogDiagnostic(diagnostic, diagnosticParams, pos);
44 }
45 
LogError(const diagnostic::DiagnosticKind & diagnostic,const lexer::SourcePosition & pos)46 void Checker::LogError(const diagnostic::DiagnosticKind &diagnostic, const lexer::SourcePosition &pos)
47 {
48     LogError(diagnostic, {}, pos);
49 }
50 
LogTypeError(std::string_view message,const lexer::SourcePosition & pos)51 void Checker::LogTypeError(std::string_view message, const lexer::SourcePosition &pos)
52 {
53     diagnosticEngine_.LogSemanticError(message, pos);
54 }
55 
LogDiagnostic(const diagnostic::DiagnosticKind & kind,const util::DiagnosticMessageParams & list,const lexer::SourcePosition & pos)56 void Checker::LogDiagnostic(const diagnostic::DiagnosticKind &kind, const util::DiagnosticMessageParams &list,
57                             const lexer::SourcePosition &pos)
58 {
59     diagnosticEngine_.LogDiagnostic(kind, list, pos);
60 }
61 
IsAllTypesAssignableTo(Type * source,Type * target)62 bool Checker::IsAllTypesAssignableTo(Type *source, Type *target)
63 {
64     if (source->TypeFlags() == TypeFlag::UNION) {
65         auto &types = source->AsUnionType()->ConstituentTypes();
66 
67         return std::all_of(types.begin(), types.end(),
68                            [this, target](auto *it) { return IsAllTypesAssignableTo(it, target); });
69     }
70 
71     return relation_->IsAssignableTo(source, target);
72 }
73 
IsTypeIdenticalTo(Type * source,Type * target)74 bool Checker::IsTypeIdenticalTo(Type *source, Type *target)
75 {
76     return relation_->IsIdenticalTo(source, target);
77 }
78 
IsTypeIdenticalTo(Type * source,Type * target,const diagnostic::DiagnosticKind & diagKind,const util::DiagnosticMessageParams & diagParams,const lexer::SourcePosition & errPos)79 bool Checker::IsTypeIdenticalTo(Type *source, Type *target, const diagnostic::DiagnosticKind &diagKind,
80                                 const util::DiagnosticMessageParams &diagParams, const lexer::SourcePosition &errPos)
81 {
82     if (!IsTypeIdenticalTo(source, target)) {
83         relation_->GetChecker()->LogError(diagKind, diagParams, errPos);
84         return false;
85     }
86 
87     return true;
88 }
89 
IsTypeIdenticalTo(Type * source,Type * target,const diagnostic::DiagnosticKind & diagKind,const lexer::SourcePosition & errPos)90 bool Checker::IsTypeIdenticalTo(Type *source, Type *target, const diagnostic::DiagnosticKind &diagKind,
91                                 const lexer::SourcePosition &errPos)
92 {
93     return IsTypeIdenticalTo(source, target, diagKind, {}, errPos);
94 }
95 
IsTypeAssignableTo(Type * source,Type * target)96 bool Checker::IsTypeAssignableTo(Type *source, Type *target)
97 {
98     return relation_->IsAssignableTo(source, target);
99 }
100 
IsTypeAssignableTo(Type * source,Type * target,const diagnostic::DiagnosticKind & diagKind,const util::DiagnosticMessageParams & list,const lexer::SourcePosition & errPos)101 bool Checker::IsTypeAssignableTo(Type *source, Type *target, const diagnostic::DiagnosticKind &diagKind,
102                                  const util::DiagnosticMessageParams &list, const lexer::SourcePosition &errPos)
103 {
104     if (!IsTypeAssignableTo(source, target)) {
105         relation_->RaiseError(diagKind, list, errPos);
106     }
107 
108     return true;
109 }
110 
IsTypeComparableTo(Type * source,Type * target)111 bool Checker::IsTypeComparableTo(Type *source, Type *target)
112 {
113     return relation_->IsComparableTo(source, target);
114 }
115 
IsTypeComparableTo(Type * source,Type * target,const diagnostic::DiagnosticKind & diagKind,const util::DiagnosticMessageParams & list,const lexer::SourcePosition & errPos)116 bool Checker::IsTypeComparableTo(Type *source, Type *target, const diagnostic::DiagnosticKind &diagKind,
117                                  const util::DiagnosticMessageParams &list, const lexer::SourcePosition &errPos)
118 {
119     if (!IsTypeComparableTo(source, target)) {
120         relation_->RaiseError(diagKind, list, errPos);
121     }
122 
123     return true;
124 }
125 
AreTypesComparable(Type * source,Type * target)126 bool Checker::AreTypesComparable(Type *source, Type *target)
127 {
128     return IsTypeComparableTo(source, target) || IsTypeComparableTo(target, source);
129 }
130 
IsTypeEqualityComparableTo(Type * source,Type * target)131 bool Checker::IsTypeEqualityComparableTo(Type *source, Type *target)
132 {
133     return IsTypeComparableTo(source, target);
134 }
135 
Program() const136 parser::Program *Checker::Program() const
137 {
138     return program_;
139 }
140 
SetProgram(parser::Program * program)141 void Checker::SetProgram(parser::Program *program)
142 {
143     program_ = program;
144 }
145 
VarBinder() const146 varbinder::VarBinder *Checker::VarBinder() const
147 {
148     return varbinder_;
149 }
150 
SetAnalyzer(SemanticAnalyzer * analyzer)151 void Checker::SetAnalyzer(SemanticAnalyzer *analyzer)
152 {
153     analyzer_ = analyzer;
154 }
155 
GetAnalyzer() const156 checker::SemanticAnalyzer *Checker::GetAnalyzer() const
157 {
158     return analyzer_;
159 }
160 
IsAnyError()161 bool Checker::IsAnyError()
162 {
163     return DiagnosticEngine().IsAnyError();
164 }
165 
ScopeContext(Checker * checker,varbinder::Scope * newScope)166 ScopeContext::ScopeContext(Checker *checker, varbinder::Scope *newScope)
167     : checker_(checker), prevScope_(checker_->scope_), prevProgram_(checker_->Program())
168 {
169     checker_->scope_ = newScope;
170     if (newScope != nullptr && newScope->Node() != nullptr) {
171         auto *topStatement = newScope->Node()->GetTopStatement();
172         if (topStatement->IsETSModule()) {
173             checker_->SetProgram(topStatement->AsETSModule()->Program());
174         }
175     }
176 }
177 
CleanUp()178 void Checker::CleanUp()
179 {
180     context_ = CheckerContext(this, CheckerStatus::NO_OPTS);
181     globalTypes_ = allocator_.New<GlobalTypesHolder>(&allocator_);
182     relation_ = allocator_.New<TypeRelation>(this);
183     identicalResults_.cached.clear();
184     assignableResults_.cached.clear();
185     comparableResults_.cached.clear();
186     uncheckedCastableResults_.cached.clear();
187     supertypeResults_.cached.clear();
188     typeStack_.clear();
189     namedTypeStack_.clear();
190 }
191 
192 }  // namespace ark::es2panda::checker
193