diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index a9d88755ddc9d50fbfc2334208ac774cfad0e4af..1235ff55932f5cbc9f9cc3f4c221a6373e017991 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -3191,7 +3191,7 @@ checker::Type *ETSAnalyzer::Check(ir::ForOfStatement *const st) const checker::Type *elemType = checker->GlobalTypeError(); if (exprType->IsETSStringType()) { - elemType = checker->GlobalCharBuiltinType(); + 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 cad55b124fb6a929919767772a59153dd6004d04..021f906c1a022736ccdeeb8eacc88c1cdd89a774 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -594,7 +594,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 c3136f256e52160a0174d63b0f35d44e74cd005e..bb0638d99b3c265544896b6498825b9f69de21d3 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/parser/ets/FixedArray/for_of_02.ets b/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets index 25779dcb628b55d54e6189d4bd28539d82c193cd..8e6155210fa7272fb23c82e699bd9168ac942d4f 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/parser/ets/for_of-expected.txt b/ets2panda/test/parser/ets/for_of-expected.txt index f968adacc62c20719e6bf1de571caed9aa86b361..4b94ee693eeb05f672ae40d54e21b725b9a46111 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 66d3ee60ebd420929e842cb6c85fe02b6ea31655..ddbb5b4e82b111b51457205d9bf8a15b11adff30 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 b7aea231ae277e71689994a4c2f6ab42cb3efe72..fe282a93e6279c03a8040165972975966147fb97 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 319908fd9dfea129bc79fba806ed976e80ce73cf..81898d9274fa3b0957845cce8c6a3d9731266b12 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 0000000000000000000000000000000000000000..98c44370108e6d1b266189281d94e0102b80945f --- /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