From 4bc426f453197de85083a6c7b6e883ef77bedc09 Mon Sep 17 00:00:00 2001 From: jiangkaiwen Date: Fri, 28 Apr 2023 18:18:49 +0800 Subject: [PATCH] Es2abc supports 2e3 as the key for the Object Issue:I6Y55G Signed-off-by: jiangkaiwen Change-Id: Iedc8418da3e199f27c4086158cf2d7ade368f5b3 --- es2panda/binder/binder.cpp | 2 +- es2panda/ir/base/classDefinition.cpp | 2 +- es2panda/ir/expressions/objectExpression.cpp | 2 +- ...test-obj-expr-key-bound-value-expected.txt | 8 +++ .../test-obj-expr-key-bound-value.js | 19 +++++++ .../test-obj-expr-key-diff-type-expected.txt | 5 ++ .../test-obj-expr-key-diff-type.js | 13 +++++ .../test-obj-expr-key-float-expected.txt | 1 + .../test-obj-expr-key-float.js | 6 +++ .../test-obj-expr-value-float-expected.txt | 1 + .../test-obj-expr-value-float.js | 6 +++ es2panda/util/helpers.cpp | 52 ++++++++++++++++--- es2panda/util/helpers.h | 7 ++- es2panda/util/ustring.h | 2 +- 14 files changed, 114 insertions(+), 12 deletions(-) create mode 100644 es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-bound-value-expected.txt create mode 100644 es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-bound-value.js create mode 100644 es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-diff-type-expected.txt create mode 100644 es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-diff-type.js create mode 100644 es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-float-expected.txt create mode 100644 es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-float.js create mode 100644 es2panda/test/compiler/js/language/arguments-object/test-obj-expr-value-float-expected.txt create mode 100644 es2panda/test/compiler/js/language/arguments-object/test-obj-expr-value-float.js diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index 03bce9e7ec..300b6dce25 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -396,7 +396,7 @@ void Binder::BuildScriptFunction(Scope *outerScope, const ir::ScriptFunction *sc } ASSERT(scope_->IsFunctionScope() || scope_->IsTSModuleScope() || scope_->IsTSEnumScope()); - BuildFunction(scope_->AsFunctionVariableScope(), util::Helpers::FunctionName(scriptFunc), scriptFunc); + BuildFunction(scope_->AsFunctionVariableScope(), util::Helpers::FunctionName(Allocator(), scriptFunc), scriptFunc); } void Binder::BuildVarDeclaratorId(const ir::AstNode *parent, ir::AstNode *childNode) diff --git a/es2panda/ir/base/classDefinition.cpp b/es2panda/ir/base/classDefinition.cpp index 14896cf5f3..1dcd5c4edd 100644 --- a/es2panda/ir/base/classDefinition.cpp +++ b/es2panda/ir/base/classDefinition.cpp @@ -166,7 +166,7 @@ int32_t ClassDefinition::CreateClassStaticProperties(compiler::PandaGen *pg, uti continue; } - util::StringView name = util::Helpers::LiteralToPropName(prop->Key()); + util::StringView name = util::Helpers::LiteralToPropName(pg->Allocator(), prop->Key()); compiler::LiteralBuffer *literalBuf = prop->IsStatic() ? &staticBuf : buf; auto &nameMap = prop->IsStatic() ? staticPropNameMap : propNameMap; diff --git a/es2panda/ir/expressions/objectExpression.cpp b/es2panda/ir/expressions/objectExpression.cpp index 2e5e0e924d..3c401ebb0b 100644 --- a/es2panda/ir/expressions/objectExpression.cpp +++ b/es2panda/ir/expressions/objectExpression.cpp @@ -295,7 +295,7 @@ void ObjectExpression::CompileStaticProperties(compiler::PandaGen *pg, util::Bit } std::vector propBuf; - util::StringView name = util::Helpers::LiteralToPropName(prop->Key()); + util::StringView name = util::Helpers::LiteralToPropName(pg->Allocator(), prop->Key()); size_t propIndex = i; auto res = propNameMap.insert({name, propIndex}); if (res.second) { // name not found in map diff --git a/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-bound-value-expected.txt b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-bound-value-expected.txt new file mode 100644 index 0000000000..e44681b5c2 --- /dev/null +++ b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-bound-value-expected.txt @@ -0,0 +1,8 @@ +1,000,000 +0.000001 +10,000,000 +1e-7 +1,000,000,000,000,000,000 +10,000,000,000,000,000,000 +100,000,000,000,000,000,000 +1,000,000,000,000,000,000,000 diff --git a/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-bound-value.js b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-bound-value.js new file mode 100644 index 0000000000..0893fa1884 --- /dev/null +++ b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-bound-value.js @@ -0,0 +1,19 @@ +let number = { + 1e6 : '1,000,000', + 1e-6 : '0.000001', + 1e7 : '10,000,000', + 1e-7 : '1e-7', + 1e18 : '1,000,000,000,000,000,000', + 1e19 : '10,000,000,000,000,000,000', + 1e20 : '100,000,000,000,000,000,000', + 1e21 : '1,000,000,000,000,000,000,000', +} + +print(number[1e6]); +print(number[1e-6]); +print(number[1e7]); +print(number[1e-7]); +print(number[1e18]); +print(number[1e19]); +print(number[1e20]); +print(number[1e21]); diff --git a/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-diff-type-expected.txt b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-diff-type-expected.txt new file mode 100644 index 0000000000..8fda00d6d8 --- /dev/null +++ b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-diff-type-expected.txt @@ -0,0 +1,5 @@ +A +B +C +D +E diff --git a/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-diff-type.js b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-diff-type.js new file mode 100644 index 0000000000..4f87734766 --- /dev/null +++ b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-diff-type.js @@ -0,0 +1,13 @@ +let number = { + 1e3 : 'A', + 1E4 : 'B', + 100 : 'C', + 0.11 : 'D', + '1.11' : 'E' +} + +print(number[1e3]); +print(number[1E4]); +print(number[100]); +print(number[0.11]); +print(number[1.11]); diff --git a/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-float-expected.txt b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-float-expected.txt new file mode 100644 index 0000000000..4fc803e127 --- /dev/null +++ b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-float-expected.txt @@ -0,0 +1 @@ +1000,2000 diff --git a/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-float.js b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-float.js new file mode 100644 index 0000000000..b9e662b20e --- /dev/null +++ b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-key-float.js @@ -0,0 +1,6 @@ +let number = { + 1e3 : '1000', + '2000' : 2e3 +} + +print(Object.keys(number)); diff --git a/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-value-float-expected.txt b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-value-float-expected.txt new file mode 100644 index 0000000000..4fc803e127 --- /dev/null +++ b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-value-float-expected.txt @@ -0,0 +1 @@ +1000,2000 diff --git a/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-value-float.js b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-value-float.js new file mode 100644 index 0000000000..438cc79a07 --- /dev/null +++ b/es2panda/test/compiler/js/language/arguments-object/test-obj-expr-value-float.js @@ -0,0 +1,6 @@ +let number = { + 1e3 : '1000', + '2000' : 2e3 +} + +print(Object.values(number)); diff --git a/es2panda/util/helpers.cpp b/es2panda/util/helpers.cpp index cd09d5cf08..721fb0ad5f 100644 --- a/es2panda/util/helpers.cpp +++ b/es2panda/util/helpers.cpp @@ -70,7 +70,7 @@ bool Helpers::ContainSpreadElement(const ArenaVector &args) return std::any_of(args.begin(), args.end(), [](const auto *it) { return it->IsSpreadElement(); }); } -util::StringView Helpers::LiteralToPropName(const ir::Expression *lit) +util::StringView Helpers::LiteralToPropName(ArenaAllocator *allocator, const ir::Expression *lit) { switch (lit->Type()) { case ir::AstNodeType::IDENTIFIER: { @@ -80,7 +80,15 @@ util::StringView Helpers::LiteralToPropName(const ir::Expression *lit) return lit->AsStringLiteral()->Str(); } case ir::AstNodeType::NUMBER_LITERAL: { - return lit->AsNumberLiteral()->Str(); + auto strName = lit->AsNumberLiteral()->Str(); + auto numName = lit->AsNumberLiteral()->Number(); + + if ((strName.Find("e") != std::string::npos || strName.Find("E") != std::string::npos) && + std::fabs(numName) < MAX_LITERAL_FORMAT && std::fabs(numName) >= MIN_LITERAL_FORMAT) { + return util::Helpers::ToStringView(allocator, numName); + } + + return strName; } case ir::AstNodeType::NULL_LITERAL: { return "null"; @@ -149,12 +157,44 @@ bool Helpers::EndsWith(std::string_view str, std::string_view suffix) return str.find(suffix, expectPos) == expectPos; } +std::string Helpers::RemoveLastZero(std::string &str) +{ + uint32_t index = 0; + + if (str.empty() || str.find('.') == std::string::npos) { + return str; + } + + for (int i = str.size() - 1; i > 0; --i) { + if (str[i] == '.') { + index = i; + break; + } + if (str[i] != '0') { + index = i + 1; + break; + } + } + + return str.substr(0, index); +} + std::string Helpers::ToString(double number) { std::string str; - if (Helpers::IsInteger(number)) { - str = std::to_string(static_cast(number)); + if (std::fabs(number) <= static_cast(std::numeric_limits::max()) && + std::fabs(number) >= MIN_LITERAL_FORMAT) { + if (Helpers::IsInteger(number)) { + str = std::to_string(static_cast(number)); + } else { + str = std::to_string(number); + str = RemoveLastZero(str); + } + } else if (std::fabs(number) > static_cast(std::numeric_limits::max()) && + std::fabs(number) < MAX_LITERAL_FORMAT) { + str = std::to_string(number); + str = RemoveLastZero(str); } else { str = std::to_string(number); } @@ -332,7 +372,7 @@ std::vector Helpers::CollectBindingNames(const ir::AstNo return bindings; } -util::StringView Helpers::FunctionName(const ir::ScriptFunction *func) +util::StringView Helpers::FunctionName(ArenaAllocator *allocator, const ir::ScriptFunction *func) { if (func->Id()) { return func->Id()->Name(); @@ -395,7 +435,7 @@ util::StringView Helpers::FunctionName(const ir::ScriptFunction *func) if (prop->Kind() != ir::PropertyKind::PROTO && Helpers::IsConstantPropertyKey(prop->Key(), prop->IsComputed())) { - return Helpers::LiteralToPropName(prop->Key()); + return Helpers::LiteralToPropName(allocator, prop->Key()); } break; diff --git a/es2panda/util/helpers.h b/es2panda/util/helpers.h index cc0e41cd39..609e584744 100644 --- a/es2panda/util/helpers.h +++ b/es2panda/util/helpers.h @@ -59,7 +59,7 @@ public: static bool IsGlobalIdentifier(const util::StringView &str); static bool ContainSpreadElement(const ArenaVector &args); - static util::StringView LiteralToPropName(const ir::Expression *lit); + static util::StringView LiteralToPropName(ArenaAllocator *allocator, const ir::Expression *lit); template static bool IsInteger(double number); @@ -68,6 +68,7 @@ public: static bool FileExtensionIs(std::string_view filePath, std::string_view extension); static bool EndsWith(std::string_view str, std::string_view suffix); + static std::string RemoveLastZero(std::string &str); static std::string ToString(double number); static util::StringView ToStringView(ArenaAllocator *allocator, double number); static util::StringView ToStringView(ArenaAllocator *allocator, int32_t number); @@ -83,7 +84,7 @@ public: static bool IsBindingPattern(const ir::AstNode *node); static bool IsPattern(const ir::AstNode *node); static std::vector CollectBindingNames(const ir::AstNode *node); - static util::StringView FunctionName(const ir::ScriptFunction *func); + static util::StringView FunctionName(ArenaAllocator *allocator, const ir::ScriptFunction *func); static std::tuple ParamName(ArenaAllocator *allocator, const ir::AstNode *param, uint32_t index); static bool IsChild(const ir::AstNode *parent, const ir::AstNode *child); @@ -96,6 +97,8 @@ public: static bool ReadFileToBuffer(const std::string &file, std::stringstream &ss); static void SetFuncFlagsForDirectives(ir::ScriptFunction *func, const lexer::LineIndex &lineIndex); + static constexpr double MAX_LITERAL_FORMAT = 1e21; + static constexpr double MIN_LITERAL_FORMAT = 1e-6; static const uint32_t INVALID_INDEX = 4294967295L; static const uint32_t MAX_INT32 = 2147483647; static const uint32_t MAX_INT16 = std::numeric_limits::max(); diff --git a/es2panda/util/ustring.h b/es2panda/util/ustring.h index dc73aaf4e1..52976ee8ac 100644 --- a/es2panda/util/ustring.h +++ b/es2panda/util/ustring.h @@ -109,7 +109,7 @@ public: return StringView(std::string_view(sv_.data() + begin, end - begin)); } - constexpr size_t Find(const char *str) + constexpr size_t Find(const char *str) const { return sv_.find(str); } -- Gitee