diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index d2a8b2ad397c8be9b3a5a17ca306bd6354d2d199..de4a3024472da24118033438e79a0606ac4d7e84 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -80,7 +80,7 @@ void Binder::IdentifierAnalysis() ASSERT(program_->Ast()); ASSERT(scope_ == topScope_); - BuildFunction(topScope_, "main"); + BuildFunction(topScope_, MAIN_FUNC_NAME); ResolveReferences(program_->Ast()); AddMandatoryParams(); } @@ -160,13 +160,22 @@ void Binder::LookupIdentReference(ir::Identifier *ident) void Binder::BuildFunction(FunctionScope *funcScope, util::StringView name) { - uint32_t idx = functionScopes_.size(); functionScopes_.push_back(funcScope); + bool funcNameWithoutDot = (name.Find(".") == std::string::npos); + bool funcNameWithoutBackslash = (name.Find("\\") == std::string::npos); + if (name != ANONYMOUS_FUNC_NAME && funcNameWithoutDot && funcNameWithoutBackslash && !functionNames_.count(name)) { + functionNames_.insert(name); + funcScope->BindName(name, name); + return; + } std::stringstream ss; - ss << "func_" << name << "_" << std::to_string(idx); + uint32_t idx = functionNameIndex_++; + ss << "#" << std::to_string(idx) << "#"; + if (funcNameWithoutDot && funcNameWithoutBackslash) { + ss << name; + } util::UString internalName(ss.str(), Allocator()); - funcScope->BindName(name, internalName.View()); } diff --git a/es2panda/binder/binder.h b/es2panda/binder/binder.h index 28f4b038d2ecfe000b020cd6552496d5d681d9d0..90f06aebf7b561d4a2e79950e73bcbfce5f8c20d 100644 --- a/es2panda/binder/binder.h +++ b/es2panda/binder/binder.h @@ -41,7 +41,12 @@ class VariableScope; class Binder { public: - explicit Binder(parser::Program *program) : program_(program), functionScopes_(Allocator()->Adapter()) {} + explicit Binder(parser::Program *program) + : program_(program), + functionScopes_(Allocator()->Adapter()), + functionNames_(Allocator()->Adapter()) + { + } NO_COPY_SEMANTIC(Binder); DEFAULT_MOVE_SEMANTIC(Binder); ~Binder() = default; @@ -104,6 +109,9 @@ public: static constexpr std::string_view LEXICAL_MANDATORY_PARAM_NEW_TARGET = "!nt"; static constexpr std::string_view LEXICAL_MANDATORY_PARAM_THIS = "!t"; + static constexpr std::string_view MAIN_FUNC_NAME = "func_main_0"; + static constexpr std::string_view ANONYMOUS_FUNC_NAME = ""; + private: using MandatoryParams = std::array; @@ -138,6 +146,8 @@ private: GlobalScope *topScope_ {}; Scope *scope_ {}; ArenaVector functionScopes_; + ArenaSet functionNames_; + size_t functionNameIndex_ {1}; }; template diff --git a/es2panda/util/ustring.h b/es2panda/util/ustring.h index 1801234961d79bdf1a60ad245dffd650e0e2c007..41146010871fa6c5e2b6e95b927e217353af6abd 100644 --- a/es2panda/util/ustring.h +++ b/es2panda/util/ustring.h @@ -109,6 +109,11 @@ public: return StringView(std::string_view(sv_.data() + begin, end - begin)); } + constexpr size_t Find(const char *str) + { + return sv_.find(str); + } + static bool IsHighSurrogate(char32_t cp) { return (cp >= Constants::SURROGATE_HIGH_MIN && cp < Constants::SURROGATE_HIGH_MAX);