13af6ab5fSopenharmony_ci/**
23af6ab5fSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ci#ifndef ES2PANDA_PARSER_INCLUDE_PROGRAM_H
173af6ab5fSopenharmony_ci#define ES2PANDA_PARSER_INCLUDE_PROGRAM_H
183af6ab5fSopenharmony_ci
193af6ab5fSopenharmony_ci#include "macros.h"
203af6ab5fSopenharmony_ci#include "mem/pool_manager.h"
213af6ab5fSopenharmony_ci#include "os/filesystem.h"
223af6ab5fSopenharmony_ci#include "util/ustring.h"
233af6ab5fSopenharmony_ci#include "util/path.h"
243af6ab5fSopenharmony_ci#include "varbinder/varbinder.h"
253af6ab5fSopenharmony_ci
263af6ab5fSopenharmony_ci#include "es2panda.h"
273af6ab5fSopenharmony_ci
283af6ab5fSopenharmony_ci#include <set>
293af6ab5fSopenharmony_ci
303af6ab5fSopenharmony_cinamespace ark::es2panda::ir {
313af6ab5fSopenharmony_ciclass BlockStatement;
323af6ab5fSopenharmony_ci}  // namespace ark::es2panda::ir
333af6ab5fSopenharmony_ci
343af6ab5fSopenharmony_cinamespace ark::es2panda::varbinder {
353af6ab5fSopenharmony_ciclass VarBinder;
363af6ab5fSopenharmony_ci}  // namespace ark::es2panda::varbinder
373af6ab5fSopenharmony_ci
383af6ab5fSopenharmony_cinamespace ark::es2panda::parser {
393af6ab5fSopenharmony_cienum class ScriptKind { SCRIPT, MODULE, STDLIB };
403af6ab5fSopenharmony_ci
413af6ab5fSopenharmony_ciclass Program {
423af6ab5fSopenharmony_cipublic:
433af6ab5fSopenharmony_ci    using ExternalSource = ArenaUnorderedMap<util::StringView, ArenaVector<Program *>>;
443af6ab5fSopenharmony_ci    using DirectExternalSource = ArenaUnorderedMap<util::StringView, ArenaVector<Program *>>;
453af6ab5fSopenharmony_ci
463af6ab5fSopenharmony_ci    using ETSNolintsCollectionMap = ArenaUnorderedMap<const ir::AstNode *, ArenaSet<ETSWarnings>>;
473af6ab5fSopenharmony_ci
483af6ab5fSopenharmony_ci    template <typename T>
493af6ab5fSopenharmony_ci    static Program NewProgram(ArenaAllocator *allocator)
503af6ab5fSopenharmony_ci    {
513af6ab5fSopenharmony_ci        auto *varbinder = allocator->New<T>(allocator);
523af6ab5fSopenharmony_ci        return Program(allocator, varbinder);
533af6ab5fSopenharmony_ci    }
543af6ab5fSopenharmony_ci
553af6ab5fSopenharmony_ci    Program(ArenaAllocator *allocator, varbinder::VarBinder *varbinder)
563af6ab5fSopenharmony_ci        : allocator_(allocator),
573af6ab5fSopenharmony_ci          varbinder_(varbinder),
583af6ab5fSopenharmony_ci          externalSources_(allocator_->Adapter()),
593af6ab5fSopenharmony_ci          directExternalSources_(allocator_->Adapter()),
603af6ab5fSopenharmony_ci          extension_(varbinder->Extension()),
613af6ab5fSopenharmony_ci          etsnolintCollection_(allocator_->Adapter())
623af6ab5fSopenharmony_ci    {
633af6ab5fSopenharmony_ci    }
643af6ab5fSopenharmony_ci
653af6ab5fSopenharmony_ci    void SetKind(ScriptKind kind)
663af6ab5fSopenharmony_ci    {
673af6ab5fSopenharmony_ci        kind_ = kind;
683af6ab5fSopenharmony_ci    }
693af6ab5fSopenharmony_ci
703af6ab5fSopenharmony_ci    NO_COPY_SEMANTIC(Program);
713af6ab5fSopenharmony_ci    DEFAULT_MOVE_SEMANTIC(Program);
723af6ab5fSopenharmony_ci
733af6ab5fSopenharmony_ci    ~Program() = default;
743af6ab5fSopenharmony_ci
753af6ab5fSopenharmony_ci    ArenaAllocator *Allocator() const
763af6ab5fSopenharmony_ci    {
773af6ab5fSopenharmony_ci        return allocator_;
783af6ab5fSopenharmony_ci    }
793af6ab5fSopenharmony_ci
803af6ab5fSopenharmony_ci    const varbinder::VarBinder *VarBinder() const
813af6ab5fSopenharmony_ci    {
823af6ab5fSopenharmony_ci        return varbinder_;
833af6ab5fSopenharmony_ci    }
843af6ab5fSopenharmony_ci
853af6ab5fSopenharmony_ci    varbinder::VarBinder *VarBinder()
863af6ab5fSopenharmony_ci    {
873af6ab5fSopenharmony_ci        return varbinder_;
883af6ab5fSopenharmony_ci    }
893af6ab5fSopenharmony_ci
903af6ab5fSopenharmony_ci    ScriptExtension Extension() const
913af6ab5fSopenharmony_ci    {
923af6ab5fSopenharmony_ci        return extension_;
933af6ab5fSopenharmony_ci    }
943af6ab5fSopenharmony_ci
953af6ab5fSopenharmony_ci    ScriptKind Kind() const
963af6ab5fSopenharmony_ci    {
973af6ab5fSopenharmony_ci        return kind_;
983af6ab5fSopenharmony_ci    }
993af6ab5fSopenharmony_ci
1003af6ab5fSopenharmony_ci    util::StringView SourceCode() const
1013af6ab5fSopenharmony_ci    {
1023af6ab5fSopenharmony_ci        return sourceCode_;
1033af6ab5fSopenharmony_ci    }
1043af6ab5fSopenharmony_ci
1053af6ab5fSopenharmony_ci    const util::StringView &SourceFilePath() const
1063af6ab5fSopenharmony_ci    {
1073af6ab5fSopenharmony_ci        return sourceFile_.GetPath();
1083af6ab5fSopenharmony_ci    }
1093af6ab5fSopenharmony_ci
1103af6ab5fSopenharmony_ci    const util::Path &SourceFile() const
1113af6ab5fSopenharmony_ci    {
1123af6ab5fSopenharmony_ci        return sourceFile_;
1133af6ab5fSopenharmony_ci    }
1143af6ab5fSopenharmony_ci
1153af6ab5fSopenharmony_ci    util::StringView SourceFileFolder() const
1163af6ab5fSopenharmony_ci    {
1173af6ab5fSopenharmony_ci        return sourceFileFolder_;
1183af6ab5fSopenharmony_ci    }
1193af6ab5fSopenharmony_ci
1203af6ab5fSopenharmony_ci    util::StringView FileName() const
1213af6ab5fSopenharmony_ci    {
1223af6ab5fSopenharmony_ci        return sourceFile_.GetFileName();
1233af6ab5fSopenharmony_ci    }
1243af6ab5fSopenharmony_ci
1253af6ab5fSopenharmony_ci    util::StringView AbsoluteName() const
1263af6ab5fSopenharmony_ci    {
1273af6ab5fSopenharmony_ci        return sourceFile_.GetAbsolutePath();
1283af6ab5fSopenharmony_ci    }
1293af6ab5fSopenharmony_ci
1303af6ab5fSopenharmony_ci    util::StringView ResolvedFilePath() const
1313af6ab5fSopenharmony_ci    {
1323af6ab5fSopenharmony_ci        return resolvedFilePath_;
1333af6ab5fSopenharmony_ci    }
1343af6ab5fSopenharmony_ci
1353af6ab5fSopenharmony_ci    ir::BlockStatement *Ast()
1363af6ab5fSopenharmony_ci    {
1373af6ab5fSopenharmony_ci        return ast_;
1383af6ab5fSopenharmony_ci    }
1393af6ab5fSopenharmony_ci
1403af6ab5fSopenharmony_ci    const ir::BlockStatement *Ast() const
1413af6ab5fSopenharmony_ci    {
1423af6ab5fSopenharmony_ci        return ast_;
1433af6ab5fSopenharmony_ci    }
1443af6ab5fSopenharmony_ci
1453af6ab5fSopenharmony_ci    void SetAst(ir::BlockStatement *ast)
1463af6ab5fSopenharmony_ci    {
1473af6ab5fSopenharmony_ci        ast_ = ast;
1483af6ab5fSopenharmony_ci    }
1493af6ab5fSopenharmony_ci
1503af6ab5fSopenharmony_ci    ir::ClassDefinition *GlobalClass()
1513af6ab5fSopenharmony_ci    {
1523af6ab5fSopenharmony_ci        return globalClass_;
1533af6ab5fSopenharmony_ci    }
1543af6ab5fSopenharmony_ci
1553af6ab5fSopenharmony_ci    const ir::ClassDefinition *GlobalClass() const
1563af6ab5fSopenharmony_ci    {
1573af6ab5fSopenharmony_ci        return globalClass_;
1583af6ab5fSopenharmony_ci    }
1593af6ab5fSopenharmony_ci
1603af6ab5fSopenharmony_ci    void SetGlobalClass(ir::ClassDefinition *globalClass)
1613af6ab5fSopenharmony_ci    {
1623af6ab5fSopenharmony_ci        globalClass_ = globalClass;
1633af6ab5fSopenharmony_ci    }
1643af6ab5fSopenharmony_ci
1653af6ab5fSopenharmony_ci    ExternalSource &ExternalSources()
1663af6ab5fSopenharmony_ci    {
1673af6ab5fSopenharmony_ci        return externalSources_;
1683af6ab5fSopenharmony_ci    }
1693af6ab5fSopenharmony_ci
1703af6ab5fSopenharmony_ci    const ExternalSource &ExternalSources() const
1713af6ab5fSopenharmony_ci    {
1723af6ab5fSopenharmony_ci        return externalSources_;
1733af6ab5fSopenharmony_ci    }
1743af6ab5fSopenharmony_ci
1753af6ab5fSopenharmony_ci    DirectExternalSource &DirectExternalSources()
1763af6ab5fSopenharmony_ci    {
1773af6ab5fSopenharmony_ci        return directExternalSources_;
1783af6ab5fSopenharmony_ci    }
1793af6ab5fSopenharmony_ci
1803af6ab5fSopenharmony_ci    const DirectExternalSource &DirectExternalSources() const
1813af6ab5fSopenharmony_ci    {
1823af6ab5fSopenharmony_ci        return directExternalSources_;
1833af6ab5fSopenharmony_ci    }
1843af6ab5fSopenharmony_ci
1853af6ab5fSopenharmony_ci    void SetSource(const util::StringView &sourceCode, const util::StringView &sourceFilePath,
1863af6ab5fSopenharmony_ci                   const util::StringView &sourceFileFolder)
1873af6ab5fSopenharmony_ci    {
1883af6ab5fSopenharmony_ci        sourceCode_ = sourceCode;
1893af6ab5fSopenharmony_ci        sourceFile_ = util::Path(sourceFilePath, Allocator());
1903af6ab5fSopenharmony_ci        sourceFileFolder_ = sourceFileFolder;
1913af6ab5fSopenharmony_ci    }
1923af6ab5fSopenharmony_ci
1933af6ab5fSopenharmony_ci    void SetSource(const ark::es2panda::SourceFile &sourceFile)
1943af6ab5fSopenharmony_ci    {
1953af6ab5fSopenharmony_ci        sourceCode_ = util::UString(sourceFile.source, Allocator()).View();
1963af6ab5fSopenharmony_ci        sourceFile_ = util::Path(sourceFile.filePath, Allocator());
1973af6ab5fSopenharmony_ci        sourceFileFolder_ = util::UString(sourceFile.fileFolder, Allocator()).View();
1983af6ab5fSopenharmony_ci        resolvedFilePath_ = util::UString(sourceFile.resolvedPath, Allocator()).View();
1993af6ab5fSopenharmony_ci    }
2003af6ab5fSopenharmony_ci
2013af6ab5fSopenharmony_ci    void SetModuleInfo(const util::StringView &name, bool isPackage, bool omitName = false)
2023af6ab5fSopenharmony_ci    {
2033af6ab5fSopenharmony_ci        moduleInfo_.moduleName = name;
2043af6ab5fSopenharmony_ci        moduleInfo_.isPackageModule = isPackage;
2053af6ab5fSopenharmony_ci        moduleInfo_.omitModuleName = omitName;
2063af6ab5fSopenharmony_ci    }
2073af6ab5fSopenharmony_ci
2083af6ab5fSopenharmony_ci    const util::StringView &ModuleName() const
2093af6ab5fSopenharmony_ci    {
2103af6ab5fSopenharmony_ci        return moduleInfo_.moduleName;
2113af6ab5fSopenharmony_ci    }
2123af6ab5fSopenharmony_ci
2133af6ab5fSopenharmony_ci    bool IsPackageModule() const
2143af6ab5fSopenharmony_ci    {
2153af6ab5fSopenharmony_ci        return moduleInfo_.isPackageModule;
2163af6ab5fSopenharmony_ci    }
2173af6ab5fSopenharmony_ci
2183af6ab5fSopenharmony_ci    bool IsDeclarationModule() const
2193af6ab5fSopenharmony_ci    {
2203af6ab5fSopenharmony_ci        return moduleInfo_.isDeclModule;
2213af6ab5fSopenharmony_ci    }
2223af6ab5fSopenharmony_ci
2233af6ab5fSopenharmony_ci    bool OmitModuleName() const
2243af6ab5fSopenharmony_ci    {
2253af6ab5fSopenharmony_ci        return moduleInfo_.omitModuleName;
2263af6ab5fSopenharmony_ci    }
2273af6ab5fSopenharmony_ci
2283af6ab5fSopenharmony_ci    const bool &IsEntryPoint() const
2293af6ab5fSopenharmony_ci    {
2303af6ab5fSopenharmony_ci        return entryPoint_;
2313af6ab5fSopenharmony_ci    }
2323af6ab5fSopenharmony_ci
2333af6ab5fSopenharmony_ci    void MarkEntry()
2343af6ab5fSopenharmony_ci    {
2353af6ab5fSopenharmony_ci        entryPoint_ = true;
2363af6ab5fSopenharmony_ci    }
2373af6ab5fSopenharmony_ci
2383af6ab5fSopenharmony_ci    void MarkASTAsChecked()
2393af6ab5fSopenharmony_ci    {
2403af6ab5fSopenharmony_ci        isASTchecked_ = true;
2413af6ab5fSopenharmony_ci    }
2423af6ab5fSopenharmony_ci
2433af6ab5fSopenharmony_ci    bool IsASTChecked() const
2443af6ab5fSopenharmony_ci    {
2453af6ab5fSopenharmony_ci        return isASTchecked_;
2463af6ab5fSopenharmony_ci    }
2473af6ab5fSopenharmony_ci
2483af6ab5fSopenharmony_ci    bool IsStdLib() const
2493af6ab5fSopenharmony_ci    {
2503af6ab5fSopenharmony_ci        // NOTE (hurton): temporary solution, needs rework when std sources are renamed
2513af6ab5fSopenharmony_ci        return (ModuleName().Mutf8().rfind("std.", 0) == 0) || (ModuleName().Mutf8().rfind("escompat", 0) == 0) ||
2523af6ab5fSopenharmony_ci               (FileName().Is("etsstdlib"));
2533af6ab5fSopenharmony_ci    }
2543af6ab5fSopenharmony_ci
2553af6ab5fSopenharmony_ci    void SetDeclarationModuleInfo();
2563af6ab5fSopenharmony_ci
2573af6ab5fSopenharmony_ci    varbinder::ClassScope *GlobalClassScope();
2583af6ab5fSopenharmony_ci    const varbinder::ClassScope *GlobalClassScope() const;
2593af6ab5fSopenharmony_ci
2603af6ab5fSopenharmony_ci    varbinder::GlobalScope *GlobalScope();
2613af6ab5fSopenharmony_ci    const varbinder::GlobalScope *GlobalScope() const;
2623af6ab5fSopenharmony_ci
2633af6ab5fSopenharmony_ci    std::string Dump() const;
2643af6ab5fSopenharmony_ci
2653af6ab5fSopenharmony_ci    void DumpSilent() const;
2663af6ab5fSopenharmony_ci
2673af6ab5fSopenharmony_ci    void AddNodeToETSNolintCollection(const ir::AstNode *node, const std::set<ETSWarnings> &warningsCollection);
2683af6ab5fSopenharmony_ci    bool NodeContainsETSNolint(const ir::AstNode *node, ETSWarnings warning);
2693af6ab5fSopenharmony_ci
2703af6ab5fSopenharmony_ciprivate:
2713af6ab5fSopenharmony_ci    struct ModuleInfo {
2723af6ab5fSopenharmony_ci        explicit ModuleInfo(util::StringView name = util::StringView(), bool isPackage = false, bool omitName = false)
2733af6ab5fSopenharmony_ci            : moduleName(name), isPackageModule(isPackage), omitModuleName(omitName)
2743af6ab5fSopenharmony_ci        {
2753af6ab5fSopenharmony_ci        }
2763af6ab5fSopenharmony_ci
2773af6ab5fSopenharmony_ci        // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
2783af6ab5fSopenharmony_ci        util::StringView moduleName;
2793af6ab5fSopenharmony_ci        bool isPackageModule;
2803af6ab5fSopenharmony_ci        bool omitModuleName;  // unclear naming, used to determine the entry point without --ets-module option
2813af6ab5fSopenharmony_ci        bool isDeclModule = false;
2823af6ab5fSopenharmony_ci        // NOLINTEND(misc-non-private-member-variables-in-classes)
2833af6ab5fSopenharmony_ci    };
2843af6ab5fSopenharmony_ci
2853af6ab5fSopenharmony_ci    ArenaAllocator *allocator_ {};
2863af6ab5fSopenharmony_ci    varbinder::VarBinder *varbinder_ {};
2873af6ab5fSopenharmony_ci    ir::BlockStatement *ast_ {};
2883af6ab5fSopenharmony_ci    ir::ClassDefinition *globalClass_ {};
2893af6ab5fSopenharmony_ci    util::StringView sourceCode_ {};
2903af6ab5fSopenharmony_ci    util::Path sourceFile_ {};
2913af6ab5fSopenharmony_ci    util::StringView sourceFileFolder_ {};
2923af6ab5fSopenharmony_ci    util::StringView resolvedFilePath_ {};
2933af6ab5fSopenharmony_ci    ExternalSource externalSources_;
2943af6ab5fSopenharmony_ci    DirectExternalSource directExternalSources_;
2953af6ab5fSopenharmony_ci    ScriptKind kind_ {};
2963af6ab5fSopenharmony_ci    ScriptExtension extension_ {};
2973af6ab5fSopenharmony_ci    bool entryPoint_ {};
2983af6ab5fSopenharmony_ci    ETSNolintsCollectionMap etsnolintCollection_;
2993af6ab5fSopenharmony_ci    ModuleInfo moduleInfo_ {};
3003af6ab5fSopenharmony_ci    bool isASTchecked_ {};
3013af6ab5fSopenharmony_ci};
3023af6ab5fSopenharmony_ci}  // namespace ark::es2panda::parser
3033af6ab5fSopenharmony_ci
3043af6ab5fSopenharmony_ci#endif
305