diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index 4092e21fb4fc637cf51c6d92799ac59896137a43..8ee052ef8288da15ff11d814887b975731006a9d 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -2276,9 +2276,9 @@ ir::Expression *ParserImpl::ParseClassKey(ClassElmentDescriptor *desc, bool isDe if (Extension() == ScriptExtension::TS) { // TODO(songqi): Determine whether MemberExpression is a symbol during type check. - desc->invalidComputedProperty = - !propName->IsNumberLiteral() && !propName->IsStringLiteral() && - !propName->IsMemberExpression() && !propName->IsIdentifier(); + desc->invalidComputedProperty = !propName->IsNumberLiteral() && + util::Helpers::GetSignedNumberLiteral(propName) == util::SignedNumberLiteral::UNRECOGNIZED && + !propName->IsStringLiteral() && !propName->IsMemberExpression() && !propName->IsIdentifier(); } if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { diff --git a/es2panda/test/compiler/ts/cases/conformance/classes/test-ts-class-property-2-expected.txt b/es2panda/test/compiler/ts/cases/conformance/classes/test-ts-class-property-2-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..5862a140a620cf9661f43c10f49cce373cee8972 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/classes/test-ts-class-property-2-expected.txt @@ -0,0 +1,6 @@ +10 +1 +1 +-1 +0 +-2 diff --git a/es2panda/test/compiler/ts/cases/conformance/classes/test-ts-class-property-2.ts b/es2panda/test/compiler/ts/cases/conformance/classes/test-ts-class-property-2.ts new file mode 100644 index 0000000000000000000000000000000000000000..b623f2cde8e3518c2b95aa9f4de3cebe8b52250c --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/classes/test-ts-class-property-2.ts @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 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. + */ + + +class A { + zero : number = 0 + ten : number = 10 + "1" : number = 1 + "-1" : number = -1 + 0 : number = 0 + readonly [-2] : number = -2 +} + +let a : A = new A() +print(a["ten"]) +print(a["1"]) +print(a[+1]) +print(a["-1"]) +print(a[0]) +print(a[-2]) diff --git a/es2panda/util/helpers.cpp b/es2panda/util/helpers.cpp index 5cfa1b35a132c5ce485085aea104176901c1fa43..ee9c5277f7e09f8751bc5be9e0c9dc371ba6d3da 100644 --- a/es2panda/util/helpers.cpp +++ b/es2panda/util/helpers.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -459,6 +460,32 @@ bool Helpers::IsObjectPropertyValue(const ArenaVector &propert return false; } +SignedNumberLiteral Helpers::GetSignedNumberLiteral(const ir::Expression *expr) +{ + if (!expr->IsUnaryExpression()) { + return SignedNumberLiteral::UNRECOGNIZED; + } + + auto unaryExpression = expr->AsUnaryExpression(); + if (!unaryExpression->Argument()->IsNumberLiteral()) { + return SignedNumberLiteral::UNRECOGNIZED; + } + + // TODO(hxw): Here we return different value for positive and nagative number literal in UnaryExpression. + // Because when we access a computed property by MemberExpression, the compiler should emit different instruction. + // Now es2abc always emits the instruction `loadObjByValue` whether the computed property is literal or not. + // It can be optimized. For positive integer literal, the instruction should be `loadObjByIndex`. + // While for negative number literal, the instruction should be `loadObjByName`. + // So I add this util api and return different value for future use. + if (unaryExpression->OperatorType() == lexer::TokenType::PUNCTUATOR_PLUS) { + return SignedNumberLiteral::POSITIVE; + } else if (unaryExpression->OperatorType() == lexer::TokenType::PUNCTUATOR_MINUS) { + return SignedNumberLiteral::NEGATIVE; + } + + return SignedNumberLiteral::UNRECOGNIZED; +} + void Helpers::OptimizeProgram(panda::pandasm::Program *prog, const std::string &inputFile) { std::map stat; diff --git a/es2panda/util/helpers.h b/es2panda/util/helpers.h index 3f1e62041688d78e2c9500f5e69f75a8d182cf34..6ba2b9559da6f8e06d1612fcaad321b6d102c059 100644 --- a/es2panda/util/helpers.h +++ b/es2panda/util/helpers.h @@ -44,6 +44,12 @@ struct Program; namespace panda::es2panda::util { +enum class SignedNumberLiteral { + UNRECOGNIZED = 0, + POSITIVE = 1, + NEGATIVE = 2 +}; + class Helpers { public: Helpers() = delete; @@ -79,6 +85,7 @@ public: uint32_t index); static bool IsChild(const ir::AstNode *parent, const ir::AstNode *child); static bool IsObjectPropertyValue(const ArenaVector &properties, const ir::AstNode *ident); + static SignedNumberLiteral GetSignedNumberLiteral(const ir::Expression *expr); static void OptimizeProgram(panda::pandasm::Program *prog, const std::string &inputFile); template