diff --git a/arkui-plugins/test/demo/mock/builder-lambda/condition-scope/block-in-switch-case.ets b/arkui-plugins/test/demo/mock/builder-lambda/condition-scope/block-in-switch-case.ets new file mode 100644 index 0000000000000000000000000000000000000000..77df2cf84f13616a2025eb300d99226cc0764665 --- /dev/null +++ b/arkui-plugins/test/demo/mock/builder-lambda/condition-scope/block-in-switch-case.ets @@ -0,0 +1,66 @@ +/* + * 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. + */ + +import { Text, Column, Component } from "@ohos.arkui.component" + +@Component +struct SwitchCase { + num: int = 2; + + build() { + Column() { + switch (this.num) { + case 0: + break; + case 1: + Text('111'); + case 2: + { + Text('111'); + } + case 3: + { + Text('111'); + } + break; + { + Text('111'); + } + case 4: + { + Text('111'); + break; + } + case 5: + { + Text('111'); + } + break; + case 6: + { + break; + } + case 7: + { + break; + Text('111'); + } + default: + break; + } + Text('hello world') + } + } +} \ No newline at end of file diff --git a/arkui-plugins/test/ut/ui-plugins/builder-lambda/condition-scope/block-in-switch-case.test.ts b/arkui-plugins/test/ut/ui-plugins/builder-lambda/condition-scope/block-in-switch-case.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..0c2b3d7c002207d1768944f0c797e12542ba550c --- /dev/null +++ b/arkui-plugins/test/ut/ui-plugins/builder-lambda/condition-scope/block-in-switch-case.test.ts @@ -0,0 +1,505 @@ +/* + * 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. + */ + + +import * as path from 'path'; +import { PluginTester } from '../../../../utils/plugin-tester'; +import { mockBuildConfig } from '../../../../utils/artkts-config'; +import { getRootPath, MOCK_ENTRY_DIR_PATH } from '../../../../utils/path-config'; +import { parseDumpSrc } from '../../../../utils/parse-string'; +import { memoNoRecheck, recheck, uiNoRecheck } from '../../../../utils/plugins'; +import { BuildConfig, PluginTestContext } from '../../../../utils/shared-types'; +import { uiTransform } from '../../../../../ui-plugins'; +import { Plugins } from '../../../../../common/plugin-context'; + +const BUILDER_LAMBDA_DIR_PATH: string = 'builder-lambda/condition-scope'; + +const buildConfig: BuildConfig = mockBuildConfig(); +buildConfig.compileFiles = [ + path.resolve(getRootPath(), MOCK_ENTRY_DIR_PATH, BUILDER_LAMBDA_DIR_PATH, 'block-in-switch-case.ets'), +]; + +const pluginTester = new PluginTester('test block statement in switch case', buildConfig); + +const parsedTransform: Plugins = { + name: 'parsedTrans', + parsed: uiTransform().parsed, +}; + +const expectedUIScript: string = ` +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; +import { ConditionScope as ConditionScope } from "arkui.component.builder"; +import { ConditionBranch as ConditionBranch } from "arkui.component.builder"; +import { memo as memo } from "arkui.stateManagement.runtime"; +import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; +import { CustomComponent as CustomComponent } from "arkui.component.customComponent"; +import { Text as Text, Column as Column, Component as Component } from "@ohos.arkui.component"; + +function main() {} + +@Component() final struct SwitchCase extends CustomComponent { + public __initializeStruct(initializers: (__Options_SwitchCase | undefined), @memo() content: ((()=> void) | undefined)): void { + this.__backing_num = ((({let gensym___83257243 = initializers; + (((gensym___83257243) == (null)) ? undefined : gensym___83257243.num)})) ?? (2)); + } + + public __updateStruct(initializers: (__Options_SwitchCase | undefined)): void {} + + private __backing_num?: int; + + public get num(): int { + return (this.__backing_num as int); + } + + public set num(value: int) { + this.__backing_num = value; + } + + @memo() public build() { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + ConditionScope(@memo() (() => { + switch (this.num) { + case 0: { + break; + } + case 1: { + ConditionBranch(@memo() (() => { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("111", undefined).applyAttributesFinish(); + return; + }), undefined); + })); + } + case 2: { + ConditionBranch(@memo() (() => { + { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("111", undefined).applyAttributesFinish(); + return; + }), undefined); + } + })); + } + case 3: { + ConditionBranch(@memo() (() => { + { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("111", undefined).applyAttributesFinish(); + return; + }), undefined); + } + })); + break; + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("111", undefined).applyAttributesFinish(); + return; + }), undefined); + } + case 4: { + ConditionBranch(@memo() (() => { + { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("111", undefined).applyAttributesFinish(); + return; + }), undefined); + return; + } + })); + break; + } + case 5: { + ConditionBranch(@memo() (() => { + { + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("111", undefined).applyAttributesFinish(); + return; + }), undefined); + } + })); + break; + } + case 6: { + ConditionBranch(@memo() (() => { + { + return; + } + })); + break; + } + case 7: { + ConditionBranch(@memo() (() => { + { + return; + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("111", undefined).applyAttributesFinish(); + return; + }), undefined); + } + })); + break; + } + default: { + break; + } + } + })); + TextImpl(@memo() ((instance: TextAttribute): void => { + instance.setTextOptions("hello world", undefined).applyAttributesFinish(); + return; + }), undefined); + })); + } + + private constructor() {} + +} + +@Component() export interface __Options_SwitchCase { + set num(num: (int | undefined)) + + get num(): (int | undefined) + +} +`; + +function testUITransformer(this: PluginTestContext): void { + expect(parseDumpSrc(this.scriptSnapshot ?? '')).toBe(parseDumpSrc(expectedUIScript)); +} + +const expectedMemoScript: string = ` +import { __memo_context_type as __memo_context_type, __memo_id_type as __memo_id_type } from "arkui.stateManagement.runtime"; +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; +import { ConditionScope as ConditionScope } from "arkui.component.builder"; +import { ConditionBranch as ConditionBranch } from "arkui.component.builder"; +import { memo as memo } from "arkui.stateManagement.runtime"; +import { TextAttribute as TextAttribute } from "arkui.component.text"; +import { TextImpl as TextImpl } from "arkui.component.text"; +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; +import { CustomComponent as CustomComponent } from "arkui.component.customComponent"; +import { Text as Text, Column as Column, Component as Component } from "@ohos.arkui.component"; + +function main() {} + +@Component() final struct SwitchCase extends CustomComponent { + public __initializeStruct(initializers: (__Options_SwitchCase | undefined), @memo() content: (((__memo_context: __memo_context_type, __memo_id: __memo_id_type)=> void) | undefined)): void { + this.__backing_num = ((({let gensym___83257243 = initializers; + (((gensym___83257243) == (null)) ? undefined : gensym___83257243.num)})) ?? (2)); + } + + public __updateStruct(initializers: (__Options_SwitchCase | undefined)): void {} + + private __backing_num?: int; + + public get num(): int { + return (this.__backing_num as int); + } + + public set num(value: int) { + this.__backing_num = value; + } + + @memo() public build(__memo_context: __memo_context_type, __memo_id: __memo_id_type) { + const __memo_scope = __memo_context.scope(((__memo_id) + (261239291)), 0); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + ColumnImpl(__memo_context, ((__memo_id) + (112404751)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: ColumnAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + (9185155)), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setColumnOptions(undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + const __memo_scope = __memo_context.scope(((__memo_id) + (147868395)), 0); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + ConditionScope(__memo_context, ((__memo_id) + (186113)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + const __memo_scope = __memo_context.scope(((__memo_id) + (186336799)), 0); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + switch (this.num) { + case 0: { + break; + } + case 1: { + ConditionBranch(__memo_context, ((__memo_id) + (27357263)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + const __memo_scope = __memo_context.scope(((__memo_id) + (78642435)), 0); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + TextImpl(__memo_context, ((__memo_id) + (235279187)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + (246501778)), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setTextOptions("111", undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), undefined); + { + __memo_scope.recache(); + return; + } + })); + } + case 2: { + ConditionBranch(__memo_context, ((__memo_id) + (220977109)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + const __memo_scope = __memo_context.scope(((__memo_id) + (91459184)), 0); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + { + TextImpl(__memo_context, ((__memo_id) + (241855776)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + (222088696)), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setTextOptions("111", undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), undefined); + } + { + __memo_scope.recache(); + return; + } + })); + } + case 3: { + ConditionBranch(__memo_context, ((__memo_id) + (143235624)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + const __memo_scope = __memo_context.scope(((__memo_id) + (214575380)), 0); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + { + TextImpl(__memo_context, ((__memo_id) + (225601197)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + (240873793)), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setTextOptions("111", undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), undefined); + } + { + __memo_scope.recache(); + return; + } + })); + break; + TextImpl(__memo_context, ((__memo_id) + (220324446)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + (5873742)), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setTextOptions("111", undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), undefined); + } + case 4: { + ConditionBranch(__memo_context, ((__memo_id) + (7513933)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + const __memo_scope = __memo_context.scope(((__memo_id) + (235688754)), 0); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + { + TextImpl(__memo_context, ((__memo_id) + (72849900)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + (10971338)), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setTextOptions("111", undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), undefined); + return; + } + })); + break; + } + case 5: { + ConditionBranch(__memo_context, ((__memo_id) + (58475451)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + const __memo_scope = __memo_context.scope(((__memo_id) + (257250368)), 0); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + { + TextImpl(__memo_context, ((__memo_id) + (264582197)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + (138238536)), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setTextOptions("111", undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), undefined); + } + { + __memo_scope.recache(); + return; + } + })); + break; + } + case 6: { + ConditionBranch(__memo_context, ((__memo_id) + (60292460)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + const __memo_scope = __memo_context.scope(((__memo_id) + (21099142)), 0); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + { + return; + } + })); + break; + } + case 7: { + ConditionBranch(__memo_context, ((__memo_id) + (34940192)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + const __memo_scope = __memo_context.scope(((__memo_id) + (15961624)), 0); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + { + return; + TextImpl(__memo_context, ((__memo_id) + (123392926)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + (181839521)), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setTextOptions("111", undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), undefined); + } + { + __memo_scope.recache(); + return; + } + })); + break; + } + default: { + break; + } + } + { + __memo_scope.recache(); + return; + } + })); + TextImpl(__memo_context, ((__memo_id) + (262734369)), @memo() ((__memo_context: __memo_context_type, __memo_id: __memo_id_type, instance: TextAttribute): void => { + const __memo_scope = __memo_context.scope(((__memo_id) + (229820618)), 1); + const __memo_parameter_instance = __memo_scope.param(0, instance); + if (__memo_scope.unchanged) { + __memo_scope.cached; + return; + } + __memo_parameter_instance.value.setTextOptions("hello world", undefined).applyAttributesFinish(); + { + __memo_scope.recache(); + return; + } + }), undefined); + { + __memo_scope.recache(); + return; + } + })); + { + __memo_scope.recache(); + return; + } + } + + private constructor() {} + +} + +@Component() export interface __Options_SwitchCase { + set num(num: (int | undefined)) + + get num(): (int | undefined) + +} +`; + +function testMemoTransformer(this: PluginTestContext): void { + expect(parseDumpSrc(this.scriptSnapshot ?? '')).toBe(parseDumpSrc(expectedMemoScript)); +} + +pluginTester.run( + 'test block statement in switch case', + [parsedTransform, uiNoRecheck, memoNoRecheck, recheck], + { + 'checked:ui-no-recheck': [testUITransformer], + 'checked:memo-no-recheck': [testMemoTransformer], + }, + { + stopAfter: 'checked', + } +); diff --git a/arkui-plugins/ui-plugins/builder-lambda-translators/cache/conditionBreakCache.ts b/arkui-plugins/ui-plugins/builder-lambda-translators/cache/conditionBreakCache.ts new file mode 100644 index 0000000000000000000000000000000000000000..693053ba845fb8e44250f622dcf3ddf1d8a9c3a2 --- /dev/null +++ b/arkui-plugins/ui-plugins/builder-lambda-translators/cache/conditionBreakCache.ts @@ -0,0 +1,91 @@ +/* + * 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. + */ + +import * as arkts from '@koalaui/libarkts'; + +export class ConditionBreakCache { + private _shouldBreak: boolean; + private _shouldReturn: boolean; + private _shouldContinue: boolean; + private static instance: ConditionBreakCache | null = null; + + private constructor() { + this._shouldBreak = false; + this._shouldReturn = false; + this._shouldContinue = false; + } + + static getInstance(): ConditionBreakCache { + if (!this.instance) { + this.instance = new ConditionBreakCache(); + } + return this.instance; + } + + get shouldBreak(): boolean { + return this._shouldBreak; + } + + get shouldReturn(): boolean { + return this._shouldReturn; + } + + get shouldContinue(): boolean { + return this._shouldContinue; + } + + collectBreak(): void { + if (this._shouldBreak) { + return; + } + this._shouldBreak = true; + } + + collectReturn(): void { + if (this._shouldReturn) { + return; + } + this._shouldReturn = true; + } + + collectContinue(): void { + if (this._shouldContinue) { + return; + } + this._shouldContinue = true; + } + + collect(st: arkts.AstNode): boolean { + if (arkts.isBreakStatement(st)) { + this.collectBreak(); + return true; + } + if (arkts.isReturnStatement(st)) { + this.collectReturn(); + return true; + } + if (arkts.isContinueStatement(st)) { + this.collectContinue(); + return true; + } + return false; + } + + reset(): void { + this._shouldBreak = false; + this._shouldReturn = false; + this._shouldContinue = false; + } +} diff --git a/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts b/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts index 7ff48d4bb7f4605166b1e5575956470c99dea0fc..9b2e6609c771a638e4066b9e02c0735db6f04ec4 100644 --- a/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts +++ b/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts @@ -42,7 +42,6 @@ import { builderLambdaType, BuilderLambdaSecondLastArgInfo, buildSecondLastArgInfo, - checkShouldBreakFromStatement, checkIsWithInIfConditionScope, BuilderLambdaConditionBranchInfo, BuilderLambdaChainingCallArgInfo, @@ -76,6 +75,7 @@ import { import { TypeRecord } from '../../collectors/utils/collect-types'; import { BuilderFactory } from './builder-factory'; import { StyleInternalsVisitor } from './style-internals-visitor'; +import { ConditionBreakCache } from './cache/conditionBreakCache'; export class factory { /** @@ -616,24 +616,34 @@ export class factory { : this.wrapConditionToBlock([newStatement], ConditionNames.CONDITION_SCOPE)) as arkts.AstNode as T; } if (arkts.isSwitchCaseStatement(statement)) { - let { statements, breakIndex } = this.updateConditionBranchInScope( - statement.consequent, - shouldWrap, - stopAtBuilderLambda - ); - if (shouldWrap) { + let { statements, breakIndex } = this.updateConditionBranchInScope(statement.consequent, shouldWrap); + if (shouldWrap && breakIndex > 0) { + const hasBreak = breakIndex !== statements.length; const beforeBreak = this.wrapConditionToBlock( - breakIndex > 0 ? statements.slice(0, breakIndex) : statements, + statements.slice(0, breakIndex), ConditionNames.CONDITION_BRANCH ); - const afterBreak = breakIndex > 0 ? statements.slice(breakIndex) : []; - statements = [beforeBreak, ...afterBreak]; + const afterBreak = statements.slice(hasBreak ? breakIndex + 1 : breakIndex); + const breakStatement = this.createBreakBetweenConditionStatements(); + statements = [beforeBreak, ...breakStatement, ...afterBreak]; } + ConditionBreakCache.getInstance().reset(); return arkts.factory.updateSwitchCaseStatement(statement, statement.test, statements) as T; } return statement; } + static createBreakBetweenConditionStatements(): arkts.AstNode[] { + const cache = ConditionBreakCache.getInstance(); + if (cache.shouldBreak) { + return [arkts.factory.createBreakStatement()]; + } + if (cache.shouldReturn) { + return [arkts.factory.createReturnStatement()]; + } + return []; + } + /** * update ConditionBranch in an if-else or swith-case body. * @internal @@ -645,7 +655,7 @@ export class factory { ): BuilderLambdaConditionBranchInfo { let breakIndex = statements.length; const newStatements = statements.map((st, index) => { - if (checkShouldBreakFromStatement(st)) { + if (ConditionBreakCache.getInstance().collect(st)) { breakIndex = index; } return this.updateContentBodyInBuilderLambda(st, shouldWrap, stopAtBuilderLambda); @@ -707,6 +717,10 @@ export class factory { ); return arkts.factory.updateBlock(statement, newStatements); } + if (arkts.isBreakStatement(statement) && statement.parent && arkts.isBlockStatement(statement.parent)) { + ConditionBreakCache.getInstance().collectBreak(); + return arkts.factory.createReturnStatement(); + } return statement; } diff --git a/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts b/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts index 04ba680cafe41fc5caff25aa3470230c8827216b..e38cd83d31e6bc6811a67514a77ef5545789dcc0 100644 --- a/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts +++ b/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts @@ -565,12 +565,6 @@ export function checkIsWithInIfConditionScope(statement: arkts.AstNode): boolean return false; } -export function checkShouldBreakFromStatement(statement: arkts.AstNode): boolean { - return ( - arkts.isReturnStatement(statement) || arkts.isBreakStatement(statement) || arkts.isContinueStatement(statement) - ); -} - /** * check whether the last parameter is trailing lambda in components. */ diff --git a/koala-wrapper/src/arkts-api/factory/nodeFactory.ts b/koala-wrapper/src/arkts-api/factory/nodeFactory.ts index 844384d34dbd7efd992a12754a7e1a30aedc1975..e07d61b0ef9c6673a0ba902498c92292d091d4c5 100644 --- a/koala-wrapper/src/arkts-api/factory/nodeFactory.ts +++ b/koala-wrapper/src/arkts-api/factory/nodeFactory.ts @@ -86,6 +86,7 @@ import { ETSNullType, TSThisType, TSQualifiedName, + BreakStatement, } from '../../generated'; import { updateIdentifier } from '../node-utilities/Identifier'; import { updateCallExpression } from '../node-utilities/CallExpression'; @@ -152,6 +153,7 @@ import { updateTSArrayType } from '../node-utilities/TSArrayType'; import { updateETSNullType } from '../node-utilities/ETSNullType'; import { updateTSThisType } from '../node-utilities/TSThisType'; import { updateTSQualifiedName } from '../node-utilities/TSQualifiedName'; +import { updateBreakStatement } from '../node-utilities/BreakStatement'; export const factory = { get createIdentifier(): (...args: Parameters) => Identifier { @@ -657,6 +659,12 @@ export const factory = { get updateTSQualifiedName(): (...args: Parameters) => TSQualifiedName { return updateTSQualifiedName; }, + get createBreakStatement(): (...args: Parameters) => BreakStatement { + return BreakStatement.createBreakStatement; + }, + get updateBreakStatement(): (...args: Parameters) => BreakStatement { + return updateBreakStatement; + }, /** @deprecated */ createTypeParameter1_(name: Identifier, constraint?: TypeNode, defaultType?: TypeNode) { return TSTypeParameter.createTSTypeParameter(Identifier.create1Identifier(name.name), constraint, defaultType); diff --git a/koala-wrapper/src/arkts-api/node-utilities/BreakStatement.ts b/koala-wrapper/src/arkts-api/node-utilities/BreakStatement.ts new file mode 100644 index 0000000000000000000000000000000000000000..03ed1b141f0a897d4d9cf76cff36a490aac3f003 --- /dev/null +++ b/koala-wrapper/src/arkts-api/node-utilities/BreakStatement.ts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024 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. + */ + +import { BreakStatement } from '../../generated'; +import { NodeCache } from '../utilities/nodeCache'; +import { attachModifiers, updateThenAttach } from '../utilities/private'; + +export function updateBreakStatement(original: BreakStatement): BreakStatement { + const update = updateThenAttach(BreakStatement.updateBreakStatement, attachModifiers); + const newNode = update(original); + if (NodeCache.getInstance().has(original)) { + NodeCache.getInstance().refresh(original, newNode); + } + return newNode; +}