From 6ea79e99297b095b5dec33d82e02f0093e6b4f12 Mon Sep 17 00:00:00 2001 From: fcc Date: Sat, 28 Jun 2025 10:11:56 +0800 Subject: [PATCH] Fix for-of string type For-of string type should call string type's iterator. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICIF8H Signed-off-by: fcc --- ets2panda/checker/ETSAnalyzer.cpp | 2 +- ets2panda/checker/ETSAnalyzerHelpers.cpp | 2 +- .../compiler/lowering/ets/objectIterator.cpp | 6 +-- .../test/ast/compiler/ets/func_as_param.ets | 2 +- .../ast/parser/ets/FixedArray/for_of_02.ets | 6 +-- ets2panda/test/ast/parser/ets/for_of_02.ets | 6 +-- ets2panda/test/parser/ets/for_of-expected.txt | 44 ++++++++++++++++--- ets2panda/test/parser/ets/for_of.ets | 4 +- ets2panda/test/runtime/ets/ForOfBoxing.ets | 2 +- ets2panda/test/runtime/ets/ForOfUnion.ets | 4 +- ets2panda/test/runtime/ets/forOfString.ets | 25 +++++++++++ 11 files changed, 80 insertions(+), 23 deletions(-) create mode 100644 ets2panda/test/runtime/ets/forOfString.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index f8f1ec7e37..2fe276487a 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -3005,7 +3005,7 @@ checker::Type *ETSAnalyzer::Check(ir::ForOfStatement *const st) const checker::Type *elemType = checker->GlobalTypeError(); if (exprType->IsETSStringType()) { - elemType = checker->GetGlobalTypesHolder()->GlobalCharType(); + elemType = checker->GlobalBuiltinETSStringType(); } else if (exprType->IsETSArrayType() || exprType->IsETSResizableArrayType()) { elemType = checker->GetElementTypeOfArray(exprType); } else if (exprType->IsETSObjectType() || exprType->IsETSUnionType() || exprType->IsETSTypeParameter()) { diff --git a/ets2panda/checker/ETSAnalyzerHelpers.cpp b/ets2panda/checker/ETSAnalyzerHelpers.cpp index f652f68e78..6b4208e562 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -611,7 +611,7 @@ checker::Type *GetIteratorType(ETSChecker *checker, checker::Type *elemType, ir: checker->LogError(diagnostic::ITERATOR_TYPE_ABSENT, {}, left->Start()); return checker->GlobalTypeError(); } - return iterType; + return checker->GetNonConstantType(iterType); } bool CheckArgumentVoidType(checker::Type *&funcReturnType, ETSChecker *checker, const std::string &name, diff --git a/ets2panda/compiler/lowering/ets/objectIterator.cpp b/ets2panda/compiler/lowering/ets/objectIterator.cpp index cf43ac31d1..ebaf767866 100644 --- a/ets2panda/compiler/lowering/ets/objectIterator.cpp +++ b/ets2panda/compiler/lowering/ets/objectIterator.cpp @@ -157,7 +157,8 @@ ir::Statement *ObjectIteratorLowering::ProcessObjectIterator(public_lib::Context declaration->Kind() != ir::VariableDeclaration::VariableDeclarationKind::CONST ? "let " : "const "; loopVariableIdent = declaration->Declarators().at(0U)->Id()->AsIdentifier()->Clone(allocator, nullptr); } else if (left->IsIdentifier()) { - loopVariableIdent = left->AsIdentifier()->Clone(allocator, nullptr); + loopVariableIdent = Gensym(allocator); + loopVariableIdent->SetName(left->AsIdentifier()->Name()); } else { ES2PANDA_UNREACHABLE(); } @@ -189,8 +190,7 @@ ir::Statement *ObjectIteratorLowering::ProcessObjectIterator(public_lib::Context bool ObjectIteratorLowering::PerformForModule(public_lib::Context *ctx, parser::Program *program) { auto hasIterator = [](checker::Type const *const exprType) -> bool { - return exprType != nullptr && - ((exprType->IsETSObjectType() && !exprType->IsETSStringType()) || exprType->IsETSTypeParameter()); + return exprType != nullptr && (exprType->IsETSObjectType() || exprType->IsETSTypeParameter()); }; program->Ast()->TransformChildrenRecursively( diff --git a/ets2panda/test/ast/compiler/ets/func_as_param.ets b/ets2panda/test/ast/compiler/ets/func_as_param.ets index 43f1c47d80..cccaa0f81b 100644 --- a/ets2panda/test/ast/compiler/ets/func_as_param.ets +++ b/ets2panda/test/ast/compiler/ets/func_as_param.ets @@ -27,7 +27,7 @@ function getFunctionArgumentsCount(funcStr: string): number { const regex = new RegExp("^[0123456789]$", "g") let count = "" for(let ch of funcStr) { - let str = new Char(ch).toString(); + let str = ch; if(regex.test(str)) { count = str } diff --git a/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets b/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets index fd74b049d9..36cb1a26db 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets @@ -15,11 +15,11 @@ let a: FixedArray = [1, 2, 3]; -function forins(): int { - for (let i: int of "abcdef") { +function forins(): string { + for (let i: string of "abcdef") { return i; } - return c'*'; + return '*'; } function main(): void { diff --git a/ets2panda/test/ast/parser/ets/for_of_02.ets b/ets2panda/test/ast/parser/ets/for_of_02.ets index 535270a596..2a4fd2ce83 100644 --- a/ets2panda/test/ast/parser/ets/for_of_02.ets +++ b/ets2panda/test/ast/parser/ets/for_of_02.ets @@ -15,11 +15,11 @@ let a: int[] = [1, 2, 3]; -function forins(): int { - for (let i: int of "abcdef") { +function forins(): string { + for (let i: string of "abcdef") { return i; } - return c'*'; + return '*'; } function main(): void { diff --git a/ets2panda/test/parser/ets/for_of-expected.txt b/ets2panda/test/parser/ets/for_of-expected.txt index 2a62e69595..149a169895 100644 --- a/ets2panda/test/parser/ets/for_of-expected.txt +++ b/ets2panda/test/parser/ets/for_of-expected.txt @@ -981,7 +981,39 @@ "expression": false, "params": [], "returnType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 20, + "program": "for_of.ets" + }, + "end": { + "line": 28, + "column": 26, + "program": "for_of.ets" + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 20, + "program": "for_of.ets" + }, + "end": { + "line": 28, + "column": 28, + "program": "for_of.ets" + } + } + }, "loc": { "start": { "line": 28, @@ -990,7 +1022,7 @@ }, "end": { "line": 28, - "column": 24, + "column": 28, "program": "for_of.ets" } } @@ -1133,7 +1165,7 @@ { "type": "ReturnStatement", "argument": { - "type": "CharLiteral", + "type": "StringLiteral", "value": "*", "loc": { "start": { @@ -1143,7 +1175,7 @@ }, "end": { "line": 32, - "column": 14, + "column": 13, "program": "for_of.ets" } } @@ -1156,7 +1188,7 @@ }, "end": { "line": 32, - "column": 15, + "column": 14, "program": "for_of.ets" } } @@ -1165,7 +1197,7 @@ "loc": { "start": { "line": 28, - "column": 25, + "column": 27, "program": "for_of.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/for_of.ets b/ets2panda/test/parser/ets/for_of.ets index 66d3ee60eb..ddbb5b4e82 100644 --- a/ets2panda/test/parser/ets/for_of.ets +++ b/ets2panda/test/parser/ets/for_of.ets @@ -25,9 +25,9 @@ function main(): void { } } -function forins(): char { +function forins(): string { for (let i of "abcdef") { return i; } - return c'*'; + return '*'; } diff --git a/ets2panda/test/runtime/ets/ForOfBoxing.ets b/ets2panda/test/runtime/ets/ForOfBoxing.ets index 4a7d4d02cd..45c0e3a150 100644 --- a/ets2panda/test/runtime/ets/ForOfBoxing.ets +++ b/ets2panda/test/runtime/ets/ForOfBoxing.ets @@ -97,7 +97,7 @@ function check6() { function check7() { let str = ""; let a7 : string = "ffff" - for (let idx7 : char of a7) { + for (let idx7 : string of a7) { let b7 = idx7 str += b7; } diff --git a/ets2panda/test/runtime/ets/ForOfUnion.ets b/ets2panda/test/runtime/ets/ForOfUnion.ets index 3e6929ee0e..08f2c4958d 100644 --- a/ets2panda/test/runtime/ets/ForOfUnion.ets +++ b/ets2panda/test/runtime/ets/ForOfUnion.ets @@ -16,8 +16,8 @@ function check1() { let a8 : string|Int[] = "abc" let str = ""; - for (let character : Char|Int of a8) { - if (character instanceof Char) { + for (let character : string|Int of a8) { + if (character instanceof string) { str += character; } } diff --git a/ets2panda/test/runtime/ets/forOfString.ets b/ets2panda/test/runtime/ets/forOfString.ets new file mode 100644 index 0000000000..98c4437010 --- /dev/null +++ b/ets2panda/test/runtime/ets/forOfString.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 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. + */ + +function main() { + let str = '\ud801\udc28\ud801\udc28'; + let expected = '𐐨'; + + // for-of string type should call string's iterator in std library + for(const s of str) { + arktest.assertTrue(s instanceof string); + arktest.assertEQ(s, expected); + } +} \ No newline at end of file -- Gitee