diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index ca365e2a61a38520779e0572b1f9310578e60b12..7fb55ea9e9969329a1dfeca860bf43ae10d753d6 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -82,6 +82,13 @@ checker::Type *ETSAnalyzer::Check(ir::CatchClause *st) const checker::Type *ETSAnalyzer::Check(ir::ClassDefinition *node) const { + for (auto p = node->Parent(); p != nullptr; p = p->Parent()) { + if (p->IsWhileStatement() || p->IsForInStatement() || p->IsForOfStatement()) { + checker->LogError(diagnostic::CLASS_SHOULD_NOT_IN_LOOP, {}, node->Start()); + node->SetTsType(checker->GlobalTypeError()); + return node->TsType(); + } + } ETSChecker *checker = GetETSChecker(); if (node->TsType() == nullptr) { diff --git a/ets2panda/test/ast/compiler/ets/class_should_not_in_loop.ets b/ets2panda/test/ast/compiler/ets/class_should_not_in_loop.ets new file mode 100644 index 0000000000000000000000000000000000000000..15649d758431a983a6daeed691553efc410dea53 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/class_should_not_in_loop.ets @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2024-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 foo(v: int) { + label: while (v) { + class C { + static { + if (v === 1) { + // Simulate break label + flagStore.flagBreakLabel = true; + return; + } + if (v === 2) { + // Simulate continue label + flagStore.flagContinueLabel = true; + return; + } + if (v === 3) { + // Simulate break + flagStore.flagBreak = true; + return; + } + if (v === 4) { + // Simulate continue + flagStore.flagContinue = true; + return; + } + } + } + + // Check flags set inside static block + if (flagStore.flagBreakLabel) { + flagStore.flagBreakLabel = false; + break label; + } + if (flagStore.flagContinueLabel) { + flagStore.flagContinueLabel = false; + continue label; + } + if (flagStore.flagBreak) { + flagStore.flagBreak = false; + break; + } + if (flagStore.flagContinue) { + flagStore.flagContinue = false; + continue; + } + + if (v === 5) { + break label; + } + if (v === 6) { + continue label; + } + if (v === 7) { + break; + } + if (v === 8) { + continue; + } + } + + class C { + static { + // Simulate labeled block with a self-breaking loop + inner: while (true) { + break inner; + } + + loop: while (v) { + if (v === 1) break loop; + if (v === 2) continue loop; + if (v === 3) break; + if (v === 4) continue; + break loop; + } + + switch (v) { + default: break; + } + } + } +} + +// Define a local object to store flags with explicit typing +interface FlagStore { + flagBreakLabel: boolean; + flagContinueLabel: boolean; + flagBreak: boolean; + flagContinue: boolean; +} + +const flagStore: FlagStore = { + flagBreakLabel: false, + flagContinueLabel: false, + flagBreak: false, + flagContinue: false +}; + + + +/* @@? 3:21 Error TypeError: Local class declaration is not allowed. */ diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index 4c4ae2e28ecd4f21ea96d41b0697c01a66857615..a516e52063ba559a4cf25c8349b35ce97e47880d 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -1514,3 +1514,7 @@ semantic: - name: DYMANIC_INIT_WITH_OBJEXPR id: 382 message: "Dymanic Type {} cannot be initialize with an object expression" + +- name: CLASS_SHOULD_NOT_IN_LOOP + id: 383 + message: "Local class declaration is not allowed."