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 "tsIndexSignature.h"
17
18#include <typescript/checker.h>
19#include <ir/astDump.h>
20#include <ir/typeNode.h>
21#include <ir/expressions/identifier.h>
22
23namespace panda::es2panda::ir {
24
25TSIndexSignature::TSIndexSignatureKind TSIndexSignature::Kind() const
26{
27    return param_->AsIdentifier()->TypeAnnotation()->IsTSNumberKeyword() ? TSIndexSignatureKind::NUMBER
28                                                                         : TSIndexSignatureKind::STRING;
29}
30
31void TSIndexSignature::Iterate(const NodeTraverser &cb) const
32{
33    cb(param_);
34    cb(typeAnnotation_);
35}
36
37void TSIndexSignature::Dump(ir::AstDumper *dumper) const
38{
39    dumper->Add({{"type", "TSIndexSignature"},
40                 {"parameters", param_},
41                 {"typeAnnotation", typeAnnotation_},
42                 {"readonly", readonly_},
43                 {"static", static_}});
44}
45
46void TSIndexSignature::Compile([[maybe_unused]] compiler::PandaGen *pg) const {}
47
48checker::Type *TSIndexSignature::Check(checker::Checker *checker) const
49{
50    auto found = checker->NodeCache().find(this);
51    if (found != checker->NodeCache().end()) {
52        return found->second;
53    }
54
55    const util::StringView &paramName = param_->AsIdentifier()->Name();
56    typeAnnotation_->Check(checker);
57    checker::Type *indexType = typeAnnotation_->AsTypeNode()->GetType(checker);
58    checker::IndexInfo *info =
59        checker->Allocator()->New<checker::IndexInfo>(indexType, paramName, readonly_, this->Start());
60    checker::ObjectDescriptor *desc = checker->Allocator()->New<checker::ObjectDescriptor>(checker->Allocator());
61    checker::ObjectType *placeholder = checker->Allocator()->New<checker::ObjectLiteralType>(desc);
62
63    CHECK_NOT_NULL(placeholder);
64    if (Kind() == ir::TSIndexSignature::TSIndexSignatureKind::NUMBER) {
65        placeholder->Desc()->numberIndexInfo = info;
66    } else {
67        placeholder->Desc()->stringIndexInfo = info;
68    }
69
70    checker->NodeCache().insert({this, placeholder});
71
72    return placeholder;
73}
74
75void TSIndexSignature::UpdateSelf(const NodeUpdater &cb, [[maybe_unused]] binder::Binder *binder)
76{
77    param_ = std::get<ir::AstNode *>(cb(param_))->AsExpression();
78    typeAnnotation_ = std::get<ir::AstNode *>(cb(typeAnnotation_))->AsExpression();
79}
80
81}  // namespace panda::es2panda::ir
82