diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index f8f1ec7e37942851ef8706f99b100afe5a047649..2fe276487a97d5158dd8bd7d365fc2ab11b42c4c 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 f652f68e788bf04c99f3cf5025e85efc5da534f2..6b4208e5626e8e575dad1e104323c4d36fa723c5 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 cf43ac31d1e336ef4535651a524e674094e13657..ebaf7678665b5c17635f2970c664cdaa2266e329 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 43f1c47d80e957c7619da2512f1e419be36ac96f..cccaa0f81b1f7df10b848363de5580e11b56dbb3 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 fd74b049d9cf1f7fa1811afceca01c352bfc419e..36cb1a26db16cf275a116c17649805497cf3f5fa 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 535270a5967403b2897ae0740dfcfa0c2a198a0c..2a4fd2ce83bafc3f57ae3ea204b66429c43011eb 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 2a62e695955ccc39054ad9b8c5afd0acdcdb5522..149a169895a8316e97338f6460fafac46a5c2296 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 4a7d4d02cd042acdfce6791013ec0bd6ca87ed82..45c0e3a150d83df2fee91543da63b7731ebf5573 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 3e6929ee0e8e636793154eeafb8b81b7e57ac136..08f2c4958d1b64d9db4ed10bba921e1d9f7e3bb3 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