• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021 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 "typeRelation.h"
17 
18 #include <typescript/checker.h>
19 #include <typescript/types/indexInfo.h>
20 #include <typescript/types/signature.h>
21 
22 namespace panda::es2panda::checker {
23 
GetType() const24 const Type *AsSrc::GetType() const
25 {
26     return type_;
27 }
28 
TypeRelation(Checker * checker)29 TypeRelation::TypeRelation(Checker *checker) : checker_(checker), result_(RelationResult::FALSE) {}
30 
IsTrue() const31 bool TypeRelation::IsTrue() const
32 {
33     return result_ == RelationResult::TRUE;
34 }
35 
GetChecker() const36 const Checker *TypeRelation::GetChecker() const
37 {
38     return checker_;
39 }
40 
GetChecker()41 Checker *TypeRelation::GetChecker()
42 {
43     return checker_;
44 }
45 
Allocator()46 ArenaAllocator *TypeRelation::Allocator()
47 {
48     return checker_->Allocator();
49 }
50 
CacheLookup(const Type * source,const Type * target,const RelationHolder & holder,RelationType type) const51 RelationResult TypeRelation::CacheLookup(const Type *source, const Type *target, const RelationHolder &holder,
52                                          RelationType type) const
53 {
54     if (result_ == RelationResult::CACHE_MISS) {
55         return result_;
56     }
57 
58     RelationKey relationKey {source->Id(), target->Id()};
59     auto res = holder.cached.find(relationKey);
60     if (res == holder.cached.end()) {
61         return RelationResult::CACHE_MISS;
62     }
63 
64     if (res->second.type >= type && res->second.result == RelationResult::TRUE) {
65         return RelationResult::TRUE;
66     }
67 
68     if (res->second.type <= type && res->second.result == RelationResult::FALSE) {
69         return RelationResult::FALSE;
70     }
71 
72     return RelationResult::CACHE_MISS;
73 }
74 
IsIdenticalTo(Type * source,Type * target)75 bool TypeRelation::IsIdenticalTo(Type *source, Type *target)
76 {
77     if (source == target) {
78         Result(true);
79         return true;
80     }
81 
82     result_ = CacheLookup(source, target, checker_->IdenticalResults(), RelationType::IDENTICAL);
83     if (result_ == RelationResult::CACHE_MISS) {
84         checker_->ResolveStructuredTypeMembers(source);
85         checker_->ResolveStructuredTypeMembers(target);
86         result_ = RelationResult::FALSE;
87         target->Identical(this, source);
88         checker_->IdenticalResults().cached.insert({{source->Id(), target->Id()}, {result_, RelationType::IDENTICAL}});
89     }
90 
91     return result_ == RelationResult::TRUE;
92 }
93 
IsIdenticalTo(Signature * source,Signature * target)94 bool TypeRelation::IsIdenticalTo(Signature *source, Signature *target)
95 {
96     if (source == target) {
97         Result(true);
98         return true;
99     }
100 
101     result_ = RelationResult::FALSE;
102     target->Identical(this, source);
103 
104     return result_ == RelationResult::TRUE;
105 }
106 
IsIdenticalTo(IndexInfo * source,IndexInfo * target)107 bool TypeRelation::IsIdenticalTo(IndexInfo *source, IndexInfo *target)
108 {
109     if (source == target) {
110         Result(true);
111         return true;
112     }
113 
114     result_ = RelationResult::FALSE;
115     target->Identical(this, source);
116 
117     return result_ == RelationResult::TRUE;
118 }
119 
IsAssignableTo(Type * source,Type * target)120 bool TypeRelation::IsAssignableTo(Type *source, Type *target)
121 {
122     result_ = CacheLookup(source, target, checker_->AssignableResults(), RelationType::ASSIGNABLE);
123     if (result_ == RelationResult::CACHE_MISS) {
124         if (IsIdenticalTo(source, target)) {
125             return true;
126         }
127 
128         result_ = RelationResult::FALSE;
129 
130         if (!source->AssignmentSource(this, target)) {
131             target->AssignmentTarget(this, source);
132         }
133 
134         checker_->AssignableResults().cached.insert(
135             {{source->Id(), target->Id()}, {result_, RelationType::ASSIGNABLE}});
136     }
137 
138     return result_ == RelationResult::TRUE;
139 }
140 
IsComparableTo(Type * source,Type * target)141 bool TypeRelation::IsComparableTo(Type *source, Type *target)
142 {
143     result_ = CacheLookup(source, target, checker_->ComparableResults(), RelationType::COMPARABLE);
144 
145     if (result_ == RelationResult::CACHE_MISS) {
146         if (IsAssignableTo(source, target)) {
147             return true;
148         }
149 
150         result_ = RelationResult::FALSE;
151         target->Compare(this, source);
152         checker_->ComparableResults().cached.insert(
153             {{source->Id(), target->Id()}, {result_, RelationType::COMPARABLE}});
154     }
155 
156     return result_ == RelationResult::TRUE;
157 }
158 
RaiseError(const std::string & errMsg,const lexer::SourcePosition & loc) const159 void TypeRelation::RaiseError(const std::string &errMsg, const lexer::SourcePosition &loc) const
160 {
161     checker_->ThrowTypeError(errMsg, loc);
162 }
163 
RaiseError(std::initializer_list<TypeErrorMessageElement> list,const lexer::SourcePosition & loc) const164 void TypeRelation::RaiseError(std::initializer_list<TypeErrorMessageElement> list,
165                               const lexer::SourcePosition &loc) const
166 {
167     checker_->ThrowTypeError(list, loc);
168 }
169 
Result(bool res)170 void TypeRelation::Result(bool res)
171 {
172     result_ = res ? RelationResult::TRUE : RelationResult::FALSE;
173 }
174 
175 }  // namespace panda::es2panda::checker
176