/** * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "checker.h" #include #include #include #include #include #include #include #include #include #include #include namespace panda::es2panda::checker { Checker::Checker(ArenaAllocator *allocator, binder::Binder *binder) : allocator_(allocator), binder_(binder), rootNode_(binder->TopScope()->Node()->AsBlockStatement()), scope_(binder->TopScope()), context_(CheckerStatus::NO_OPTS) { scopeStack_.push_back(scope_); globalTypes_ = allocator_->New(allocator_); relation_ = allocator_->New(this); } void Checker::StartChecker() { ASSERT(rootNode_->IsProgram()); rootNode_->Check(this); } void Checker::ThrowTypeError(std::initializer_list list, const lexer::SourcePosition &pos) { std::stringstream ss; for (const auto &it : list) { if (std::holds_alternative(it)) { ss << std::get(it); } else if (std::holds_alternative(it)) { ss << std::get(it); } else if (std::holds_alternative(it)) { ss << TokenToString(std::get(it)); } else if (std::holds_alternative(it)) { std::get(it)->ToString(ss); } else if (std::holds_alternative(it)) { std::get(it).GetType()->ToStringAsSrc(ss); } else if (std::holds_alternative(it)) { ss << std::to_string(std::get(it)); } else { UNREACHABLE(); } } std::string err = ss.str(); ThrowTypeError(err, pos); } void Checker::ThrowTypeError(std::string_view message, const lexer::SourcePosition &pos) { lexer::LineIndex index(binder_->Program()->SourceCode()); lexer::SourceLocation loc = index.GetLocation(pos); throw Error {ErrorType::TYPE, message, loc.line, loc.col}; } Type *Checker::CheckTypeCached(const ir::Expression *expr) { auto res = nodeCache_.find(expr); if (res != nodeCache_.end()) { return res->second; } Type *returnType = expr->Check(this); nodeCache_.insert({expr, returnType}); return returnType; } } // namespace panda::es2panda::checker