From d91c45ee19f93a3f2b35ee42247ea6d8d876d344 Mon Sep 17 00:00:00 2001 From: Cuecuexiaoyu Date: Wed, 27 Aug 2025 19:54:14 +0800 Subject: [PATCH] modify repeat arguments Signed-off-by: Cuecuexiaoyu Change-Id: I23d0487735621745208d231c811f89aba4702a70 --- arkui-plugins/common/abstract-visitor.ts | 2 + arkui-plugins/common/metadata-collector.ts | 51 ++++++ arkui-plugins/common/predefines.ts | 2 + arkui-plugins/common/program-visitor.ts | 3 +- .../test/demo/mock/component/repeat.ets | 42 +++++ .../ut/ui-plugins/component/repeat.test.ts | 158 ++++++++++++++++++ .../cache/componentAttributeCache.ts | 132 +++++++++++++++ .../builder-lambda-translators/factory.ts | 66 +++++++- .../builder-lambda-translators/utils.ts | 124 +------------- .../ui-plugins/checked-transformer.ts | 15 +- .../ui-plugins/struct-translators/factory.ts | 5 +- 11 files changed, 472 insertions(+), 128 deletions(-) create mode 100644 arkui-plugins/common/metadata-collector.ts create mode 100644 arkui-plugins/test/demo/mock/component/repeat.ets create mode 100644 arkui-plugins/test/ut/ui-plugins/component/repeat.test.ts create mode 100644 arkui-plugins/ui-plugins/builder-lambda-translators/cache/componentAttributeCache.ts diff --git a/arkui-plugins/common/abstract-visitor.ts b/arkui-plugins/common/abstract-visitor.ts index 2c7a307da..6b70c3573 100644 --- a/arkui-plugins/common/abstract-visitor.ts +++ b/arkui-plugins/common/abstract-visitor.ts @@ -43,6 +43,8 @@ export abstract class AbstractVisitor implements VisitorOptions { abstract visitor(node: arkts.AstNode): arkts.AstNode; + init(): void {} + reset(): void { this.indentation = 0; } diff --git a/arkui-plugins/common/metadata-collector.ts b/arkui-plugins/common/metadata-collector.ts new file mode 100644 index 000000000..9f12ec95b --- /dev/null +++ b/arkui-plugins/common/metadata-collector.ts @@ -0,0 +1,51 @@ +/* + * 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 { ProjectConfig } from './plugin-context'; + +export class MetaDataCollector { + public projectConfig: ProjectConfig | undefined; + public fileAbsName: string | undefined; + public externalSourceName: string | undefined; + private static instance: MetaDataCollector | null = null; + + static getInstance(): MetaDataCollector { + if (!this.instance) { + this.instance = new MetaDataCollector(); + } + return this.instance; + } + + setProjectConfig(config: ProjectConfig | undefined): this { + this.projectConfig = config; + return this; + } + + setAbsName(fileName: string | undefined): this { + this.fileAbsName = fileName; + return this; + } + + setExternalSourceName(externalSourceName: string | undefined): this { + this.externalSourceName = externalSourceName; + return this; + } + + reset(): void { + this.projectConfig = undefined; + this.fileAbsName = undefined; + this.externalSourceName = undefined; + } +} \ No newline at end of file diff --git a/arkui-plugins/common/predefines.ts b/arkui-plugins/common/predefines.ts index f62a60a5d..77117169d 100644 --- a/arkui-plugins/common/predefines.ts +++ b/arkui-plugins/common/predefines.ts @@ -35,6 +35,7 @@ export const ENTRY_POINT_IMPORT_SOURCE_NAME: string = 'arkui.UserView'; export const ARKUI_COMPONENT_COMMON_SOURCE_NAME: string = 'arkui.component.common'; export const ARKUI_FOREACH_SOURCE_NAME: string = 'arkui.component.forEach'; export const ARKUI_BUILDER_SOURCE_NAME: string = 'arkui.component.builder'; +export const ARKUI_REPEAT_SOURCE_NAME: string = 'arkui.component.repeat'; export enum ModuleType { HAR = 'har', @@ -118,6 +119,7 @@ export enum EntryParamNames { export enum InnerComponentNames { FOR_EACH = 'ForEach', + REPEAT = 'Repeat', } export enum InnerComponentAttributes { diff --git a/arkui-plugins/common/program-visitor.ts b/arkui-plugins/common/program-visitor.ts index 1b7d0eac8..368f696a2 100644 --- a/arkui-plugins/common/program-visitor.ts +++ b/arkui-plugins/common/program-visitor.ts @@ -271,7 +271,6 @@ export class ProgramVisitor extends AbstractVisitor { transformer.registerMap(this.legacyStructMap); } this.visitTransformer(transformer, script, externalSourceName, program); - transformer.reset(); arkts.setAllParents(script); if (!transformer.isExternal) { debugDump( @@ -310,7 +309,9 @@ export class ProgramVisitor extends AbstractVisitor { transformer.isExternal = !!externalSourceName; transformer.externalSourceName = externalSourceName; transformer.program = program; + transformer.init(); const newScript = transformer.visitor(script) as arkts.EtsScript; + transformer.reset(); return newScript; } } diff --git a/arkui-plugins/test/demo/mock/component/repeat.ets b/arkui-plugins/test/demo/mock/component/repeat.ets new file mode 100644 index 000000000..1e931686e --- /dev/null +++ b/arkui-plugins/test/demo/mock/component/repeat.ets @@ -0,0 +1,42 @@ +/* + * 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 { Component, Text, WrappedBuilder, Column, Repeat, RepeatItem } from "@kit.ArkUI" + +interface Person { + name: string; + age: number; +} + +class AB { + per: string = 'hello'; + bar: Array = new Array('xx', 'yy', 'zz'); +} + +@Component +struct ImportStruct { + arr: string[] = ['a', 'b', 'c']; + getArray() { + return new Array({ name: 'LiHua', age:25 } as Person, { name: 'Amy', age:18 } as Person); + } + + build() { + Column() { + Repeat(this.arr).key((item: string, index: number): string => item) + Repeat(this.getArray()) + Repeat((new AB()).bar) + } + } +} \ No newline at end of file diff --git a/arkui-plugins/test/ut/ui-plugins/component/repeat.test.ts b/arkui-plugins/test/ut/ui-plugins/component/repeat.test.ts new file mode 100644 index 000000000..ab2af438a --- /dev/null +++ b/arkui-plugins/test/ut/ui-plugins/component/repeat.test.ts @@ -0,0 +1,158 @@ +/* + * 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 { recheck, uiNoRecheck } from '../../../utils/plugins'; +import { BuildConfig, PluginTestContext } from '../../../utils/shared-types'; +import { uiTransform } from '../../../../ui-plugins'; +import { Plugins } from '../../../../common/plugin-context'; + +const COMPONENT_DIR_PATH: string = 'component'; + +const buildConfig: BuildConfig = mockBuildConfig(); +buildConfig.compileFiles = [ + path.resolve(getRootPath(), MOCK_ENTRY_DIR_PATH, COMPONENT_DIR_PATH, 'repeat.ets'), +]; + +const pluginTester = new PluginTester('test Repeat component transformation', buildConfig); + +const parsedTransform: Plugins = { + name: 'repeat', + parsed: uiTransform().parsed +}; + +const expectedScript: string = ` +import { ColumnAttribute as ColumnAttribute } from "arkui.component.column"; + +import { memo as memo } from "arkui.stateManagement.runtime"; + +import { RepeatAttribute as RepeatAttribute } from "arkui.component.repeat"; + +import { RepeatImpl as RepeatImpl } from "arkui.component.repeat"; + +import { ColumnImpl as ColumnImpl } from "arkui.component.column"; + +import { CustomComponent as CustomComponent } from "arkui.component.customComponent"; + +import { Component as Component, Text as Text, WrappedBuilder as WrappedBuilder, Column as Column, Repeat as Repeat, RepeatItem as RepeatItem } from "@kit.ArkUI"; + +function main() {} + + +interface Person { + set name(name: string) + + get name(): string + set age(age: number) + + get age(): number + +} + +class AB { + public per: string = "hello"; + + public bar: Array = new Array("xx", "yy", "zz"); + + public constructor() {} + +} + +@Component() final struct ImportStruct extends CustomComponent { + public __initializeStruct(initializers: (__Options_ImportStruct | undefined), @memo() content: ((()=> void) | undefined)): void { + this.__backing_arr = ((({let gensym___244068973 = initializers; + (((gensym___244068973) == (null)) ? undefined : gensym___244068973.arr)})) ?? (["a", "b", "c"])); + } + + public __updateStruct(initializers: (__Options_ImportStruct | undefined)): void {} + + private __backing_arr?: Array; + + public get arr(): Array { + return (this.__backing_arr as Array); + } + + public set arr(value: Array) { + this.__backing_arr = value; + } + + public getArray() { + return new Array(({ + name: "LiHua", + age: 25, + } as Person), ({ + name: "Amy", + age: 18, + } as Person)); + } + + @memo() public build() { + ColumnImpl(@memo() ((instance: ColumnAttribute): void => { + instance.setColumnOptions(undefined).applyAttributesFinish(); + return; + }), @memo() (() => { + RepeatImpl(@memo() ((instance): void => { + instance.setRepeatOptions((() => { + return this.arr; + })).key(((item: string, index: number): string => { + return item; + })); + return; + })); + RepeatImpl(@memo() ((instance): void => { + instance.setRepeatOptions((() => { + return this.getArray(); + })); + return; + })); + RepeatImpl(@memo() ((instance): void => { + instance.setRepeatOptions((() => { + return new AB().bar; + })); + return; + })); + })); + } + + public constructor() {} + +} + +@Component() export interface __Options_ImportStruct { + set arr(arr: (Array | undefined)) + + get arr(): (Array | undefined) + +} +`; + +function testParsedAndCheckedTransformer(this: PluginTestContext): void { + expect(parseDumpSrc(this.scriptSnapshot ?? '')).toBe(parseDumpSrc(expectedScript)); +} + +pluginTester.run( + 'test Repeat component transformation', + [parsedTransform, uiNoRecheck, recheck], + { + 'checked:ui-no-recheck': [testParsedAndCheckedTransformer], + }, + { + stopAfter: 'checked', + } +); \ No newline at end of file diff --git a/arkui-plugins/ui-plugins/builder-lambda-translators/cache/componentAttributeCache.ts b/arkui-plugins/ui-plugins/builder-lambda-translators/cache/componentAttributeCache.ts new file mode 100644 index 000000000..71d47f2a2 --- /dev/null +++ b/arkui-plugins/ui-plugins/builder-lambda-translators/cache/componentAttributeCache.ts @@ -0,0 +1,132 @@ +/* + * 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'; +import { checkIsTrailingLambdaInLastParam } from '../utils'; +import { + collectTypeRecordFromParameter, + collectTypeRecordFromTypeParameterDeclaration, + collectTypeRecordFromTypeParameterInstatiation, + ParameterRecord, + TypeParameterTypeRecord, + TypeRecord, +} from '../../../collectors/utils/collect-types'; +import { factory as builderLambdaFactory } from '../factory'; + +export interface ComponentRecord { + name: string; + attributeRecords: ParameterRecord[]; + typeParams?: TypeParameterTypeRecord[]; + hasRestParameter?: boolean; + hasReceiver?: boolean; + hasLastTrailingLambda?: boolean; +} + +export class ComponentAttributeCache { + private _cache: Map; + private _attributeName: string | undefined; + private _attributeTypeParams: TypeRecord[] | undefined; + private _isCollected: boolean = false; + private static instance: ComponentAttributeCache; + + private constructor() { + this._cache = new Map(); + } + + static getInstance(): ComponentAttributeCache { + if (!this.instance) { + this.instance = new ComponentAttributeCache(); + } + return this.instance; + } + + private collectAttributeName(type: arkts.TypeNode | undefined): string | undefined { + if ( + !type || + !arkts.isETSTypeReference(type) || + !type.part || + !type.part.name || + !arkts.isIdentifier(type.part.name) + ) { + return; + } + this._attributeName = type.part.name.name; + if (type.part.typeParams) { + this._attributeTypeParams = collectTypeRecordFromTypeParameterInstatiation(type.part.typeParams); + } + } + + get attributeName(): string | undefined { + return this._attributeName; + } + + get attributeTypeParams(): TypeRecord[] | undefined { + return this._attributeTypeParams; + } + + reset(): void { + this._cache.clear(); + this._attributeName = undefined; + this._attributeTypeParams = undefined; + this._isCollected = false; + } + + isCollected(): boolean { + return this._isCollected; + } + + collect(node: arkts.MethodDefinition): void { + this.collectAttributeName(node.scriptFunction.returnTypeAnnotation); + if (!this._attributeName) { + return; + } + const name: string = node.name.name; + const hasRestParameter = node.scriptFunction.hasRestParameter; + const hasReceiver = node.scriptFunction.hasReceiver; + const typeParams = collectTypeRecordFromTypeParameterDeclaration(node.scriptFunction.typeParams); + const params = builderLambdaFactory.preProcessDeclParams( + node, + name, + node.scriptFunction.params as arkts.ETSParameterExpression[] + ); + const attributeRecords: ParameterRecord[] = []; + const hasLastTrailingLambda = checkIsTrailingLambdaInLastParam(params); + params.forEach((p, index) => { + if (index === params.length - 1 && hasLastTrailingLambda) { + return; + } + const record = collectTypeRecordFromParameter(p); + attributeRecords.push(record); + }); + const componentRecord: ComponentRecord = { + name, + attributeRecords, + typeParams, + hasRestParameter, + hasReceiver, + hasLastTrailingLambda, + }; + this._cache.set(name, componentRecord); + this._isCollected = true; + } + + getComponentRecord(name: string): ComponentRecord | undefined { + return this._cache.get(name); + } + + getAllComponentRecords(): ComponentRecord[] { + return Array.from(this._cache.values()); + } +} diff --git a/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts b/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts index 638e446b3..83511fd71 100644 --- a/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts +++ b/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts @@ -49,9 +49,8 @@ import { BuilderLambdaStyleBodyInfo, getDeclaredSetAttribtueMethodName, checkIsTrailingLambdaInLastParam, - ComponentAttributeCache, - ComponentRecord, getTransformedComponentName, + isRepeat, } from './utils'; import { hasDecorator, isDecoratorIntrinsicAnnotation } from '../property-translators/utils'; import { factory as PropertyFactory } from '../property-translators/factory'; @@ -76,6 +75,7 @@ import { TypeRecord } from '../../collectors/utils/collect-types'; import { BuilderFactory } from './builder-factory'; import { StyleInternalsVisitor } from './style-internals-visitor'; import { ConditionBreakCache } from './cache/conditionBreakCache'; +import { ComponentAttributeCache, ComponentRecord } from './cache/componentAttributeCache'; export class factory { /** @@ -88,8 +88,9 @@ export class factory { newName: string | undefined ): arkts.MethodDefinition { const func: arkts.ScriptFunction = node.scriptFunction; - const isFunctionCall: boolean = node.name.name !== BuilderLambdaNames.ORIGIN_METHOD_NAME; - const newParams: arkts.Expression[] = [...prefixArgs, ...func.params]; + const name: string = node.name.name; + const isFunctionCall: boolean = name !== BuilderLambdaNames.ORIGIN_METHOD_NAME; + const newParams: arkts.Expression[] = factory.preProcessDeclParams(node, name, [...prefixArgs, ...func.params]); const updateFunc = arkts.factory .updateScriptFunction( func, @@ -115,6 +116,38 @@ export class factory { ); } + static preProcessDeclParams( + node: arkts.MethodDefinition, + name: string, + params: arkts.Expression[] + ): arkts.Expression[] { + if (isRepeat(name)) { + factory.transformRepeatArguments(node, params); + } + return params; + } + + static transformRepeatArguments(node: arkts.MethodDefinition, newParams: arkts.Expression[]): void { + if (node.scriptFunction.params.length <= 0 || !arkts.isEtsParameterExpression(node.scriptFunction.params[0])) { + return; + } + const specificParam: arkts.ETSParameterExpression = node.scriptFunction.params[0]; + const paramType: arkts.AstNode | undefined = specificParam.type; + if (paramType && arkts.isTypeNode(paramType)) { + newParams.splice( + -1, + 1, + arkts.factory.createParameterDeclaration( + arkts.factory.createIdentifier( + specificParam.identifier.name, + UIFactory.createLambdaFunctionType([], paramType) + ), + undefined + ) + ); + } + } + /* * transform arguments in style node. */ @@ -509,7 +542,7 @@ export class factory { ); const lambdaBody = this.addOptionsArgsToLambdaBodyInStyleArg( lambdaBodyInfo, - modifiedArgs, + factory.processModifiedArgs(modifiedArgs, moduleName, type?.name), typeArguments, isFromCommonMethod ); @@ -519,6 +552,29 @@ export class factory { return args; } + static processModifiedArgs( + modifiedArgs: (arkts.AstNode | undefined)[], + moduleName: string, + name: string | undefined + ): (arkts.AstNode | undefined)[] { + if ( + isRepeat(name, moduleName) && + modifiedArgs.length > 0 && + modifiedArgs[0] && + arkts.isExpression(modifiedArgs[0]) + ) { + const firstArg = modifiedArgs[0]; + modifiedArgs[0] = arkts.factory.createArrowFunction( + UIFactory.createScriptFunction({ + body: arkts.factory.createBlock([arkts.factory.createReturnStatement(firstArg)]), + flags: arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW, + modifiers: arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, + }) + ); + } + return modifiedArgs; + } + /** * add options arguments to set methods in style argument body. */ diff --git a/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts b/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts index ea3aaa077..e0a786193 100644 --- a/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts +++ b/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts @@ -19,22 +19,17 @@ import { BuilderLambdaNames, expectNameInTypeReference, isCustomComponentAnnotat import { DeclarationCollector } from '../../common/declaration-collector'; import { ARKUI_IMPORT_PREFIX_NAMES, - BindableDecl, + ARKUI_REPEAT_SOURCE_NAME, Dollars, InnerComponentAttributes, + InnerComponentNames, StructDecoratorNames, } from '../../common/predefines'; import { ImportCollector } from '../../common/import-collector'; -import { - collectTypeRecordFromParameter, - collectTypeRecordFromTypeParameterDeclaration, - collectTypeRecordFromTypeParameterInstatiation, - ParameterRecord, - TypeParameterTypeRecord, - TypeRecord, -} from '../../collectors/utils/collect-types'; import { hasMemoAnnotation } from '../../collectors/memo-collectors/utils'; -import { AstNodePointer } from 'common/safe-types'; +import { AstNodePointer } from '../../common/safe-types'; +import { ComponentAttributeCache } from './cache/componentAttributeCache'; +import { MetaDataCollector } from '../../common/metadata-collector'; export type BuilderLambdaDeclInfo = { name: string; @@ -423,10 +418,7 @@ export function isBuilderLambdaFunctionCall(nameNode: arkts.Identifier | undefin return false; } const name = nameNode.name; - return ( - name !== BuilderLambdaNames.ORIGIN_METHOD_NAME && - name !== BuilderLambdaNames.TRANSFORM_METHOD_NAME - ); + return name !== BuilderLambdaNames.ORIGIN_METHOD_NAME && name !== BuilderLambdaNames.TRANSFORM_METHOD_NAME; } export function callIsGoodForBuilderLambda(leaf: arkts.CallExpression): boolean { @@ -649,105 +641,7 @@ export function getTransformedComponentName(componentName: string): string { return `${componentName}Impl`; } -// CACHE -export interface ComponentRecord { - name: string; - attributeRecords: ParameterRecord[]; - typeParams?: TypeParameterTypeRecord[]; - hasRestParameter?: boolean; - hasReceiver?: boolean; - hasLastTrailingLambda?: boolean; -} - -export class ComponentAttributeCache { - private _cache: Map; - private _attributeName: string | undefined; - private _attributeTypeParams: TypeRecord[] | undefined; - private _isCollected: boolean = false; - private static instance: ComponentAttributeCache; - - private constructor() { - this._cache = new Map(); - } - - static getInstance(): ComponentAttributeCache { - if (!this.instance) { - this.instance = new ComponentAttributeCache(); - } - return this.instance; - } - - private collectAttributeName(type: arkts.TypeNode | undefined): string | undefined { - if ( - !type || - !arkts.isETSTypeReference(type) || - !type.part || - !type.part.name || - !arkts.isIdentifier(type.part.name) - ) { - return; - } - this._attributeName = type.part.name.name; - if (type.part.typeParams) { - this._attributeTypeParams = collectTypeRecordFromTypeParameterInstatiation(type.part.typeParams); - } - } - - get attributeName(): string | undefined { - return this._attributeName; - } - - get attributeTypeParams(): TypeRecord[] | undefined { - return this._attributeTypeParams; - } - - reset(): void { - this._cache.clear(); - this._attributeName = undefined; - this._attributeTypeParams = undefined; - this._isCollected = false; - } - - isCollected(): boolean { - return this._isCollected; - } - - collect(node: arkts.MethodDefinition): void { - this.collectAttributeName(node.scriptFunction.returnTypeAnnotation); - if (!this._attributeName) { - return; - } - const name: string = node.name.name; - const hasRestParameter = node.scriptFunction.hasRestParameter; - const hasReceiver = node.scriptFunction.hasReceiver; - const typeParams = collectTypeRecordFromTypeParameterDeclaration(node.scriptFunction.typeParams); - const params = node.scriptFunction.params as arkts.ETSParameterExpression[]; - const attributeRecords: ParameterRecord[] = []; - const hasLastTrailingLambda = checkIsTrailingLambdaInLastParam(params); - params.forEach((p, index) => { - if (index === params.length - 1 && hasLastTrailingLambda) { - return; - } - const record = collectTypeRecordFromParameter(p); - attributeRecords.push(record); - }); - const componentRecord: ComponentRecord = { - name, - attributeRecords, - typeParams, - hasRestParameter, - hasReceiver, - hasLastTrailingLambda, - }; - this._cache.set(name, componentRecord); - this._isCollected = true; - } - - getComponentRecord(name: string): ComponentRecord | undefined { - return this._cache.get(name); - } - - getAllComponentRecords(): ComponentRecord[] { - return Array.from(this._cache.values()); - } +export function isRepeat(name: string | undefined, sourceName?: string): boolean { + const externalSourceName = sourceName ?? MetaDataCollector.getInstance().externalSourceName; + return name === InnerComponentNames.REPEAT && externalSourceName === ARKUI_REPEAT_SOURCE_NAME; } diff --git a/arkui-plugins/ui-plugins/checked-transformer.ts b/arkui-plugins/ui-plugins/checked-transformer.ts index aaa177820..258145b96 100644 --- a/arkui-plugins/ui-plugins/checked-transformer.ts +++ b/arkui-plugins/ui-plugins/checked-transformer.ts @@ -19,11 +19,7 @@ import { factory as structFactory } from './struct-translators/factory'; import { factory as builderLambdaFactory } from './builder-lambda-translators/factory'; import { factory as entryFactory } from './entry-translators/factory'; import { AbstractVisitor } from '../common/abstract-visitor'; -import { - ComponentAttributeCache, - isBuilderLambda, - isBuilderLambdaMethodDecl, -} from './builder-lambda-translators/utils'; +import { isBuilderLambda, isBuilderLambdaMethodDecl } from './builder-lambda-translators/utils'; import { isEntryWrapperClass } from './entry-translators/utils'; import { ImportCollector } from '../common/import-collector'; import { DeclarationCollector } from '../common/declaration-collector'; @@ -50,6 +46,8 @@ import { InteroperAbilityNames } from './interop/predefines'; import { generateBuilderCompatible } from './interop/builder-interop'; import { builderRewriteByType } from './builder-lambda-translators/builder-factory'; import { MonitorCache } from './property-translators/cache/monitorCache'; +import { ComponentAttributeCache } from './builder-lambda-translators/cache/componentAttributeCache'; +import { MetaDataCollector } from '../common/metadata-collector'; export class CheckedTransformer extends AbstractVisitor { private scope: ScopeInfoCollection; @@ -85,6 +83,13 @@ export class CheckedTransformer extends AbstractVisitor { } } + init(): void { + MetaDataCollector.getInstance() + .setProjectConfig(this.projectConfig) + .setAbsName(this.program?.absName) + .setExternalSourceName(this.externalSourceName); + } + reset(): void { super.reset(); this.scope = { customComponents: [] }; diff --git a/arkui-plugins/ui-plugins/struct-translators/factory.ts b/arkui-plugins/ui-plugins/struct-translators/factory.ts index 13a120dc4..8066fd88e 100644 --- a/arkui-plugins/ui-plugins/struct-translators/factory.ts +++ b/arkui-plugins/ui-plugins/struct-translators/factory.ts @@ -61,7 +61,7 @@ import { isComputedMethod, } from './utils'; import { collectStateManagementTypeImport, generateThisBacking, hasDecorator } from '../property-translators/utils'; -import { ComponentAttributeCache, isComponentAttributeInterface } from '../builder-lambda-translators/utils'; +import { isComponentAttributeInterface } from '../builder-lambda-translators/utils'; import { ProjectConfig } from '../../common/plugin-context'; import { ImportCollector } from '../../common/import-collector'; import { @@ -83,9 +83,10 @@ import { } from '../../collectors/memo-collectors/utils'; import { generateArkUICompatible, isArkUICompatible } from '../interop/interop'; import { GenSymGenerator } from '../../common/gensym-generator'; -import { MethodTranslator } from 'ui-plugins/property-translators/base'; +import { MethodTranslator } from '../property-translators/base'; import { MonitorCache } from '../property-translators/cache/monitorCache'; import { PropertyCache } from '../property-translators/cache/propertyCache'; +import { ComponentAttributeCache } from '../builder-lambda-translators/cache/componentAttributeCache'; export class factory { /** -- Gitee