From bf65b916ef5461ad108c21ae36c7ce92a1bb4bf4 Mon Sep 17 00:00:00 2001 From: liuyongkai2 Date: Mon, 8 Sep 2025 10:42:12 +0800 Subject: [PATCH] fileInteroppp Signed-off-by: liuyongkai2 --- arkui-plugins/common/arkts-utils.ts | 2 +- arkui-plugins/common/file-manager.ts | 4 +- arkui-plugins/common/plugin-context.ts | 2 +- arkui-plugins/common/program-visitor.ts | 71 +++--------- .../ui-plugins/checked-transformer.ts | 2 +- .../ui-plugins/component-transformer.ts | 70 ----------- arkui-plugins/ui-plugins/interop/interop.ts | 109 ++++++------------ .../ui-plugins/interop/legacy-transformer.ts | 82 +++++-------- arkui-plugins/ui-plugins/interop/utils.ts | 46 +++++++- .../ui-plugins/struct-translators/factory.ts | 10 +- 10 files changed, 138 insertions(+), 260 deletions(-) diff --git a/arkui-plugins/common/arkts-utils.ts b/arkui-plugins/common/arkts-utils.ts index 9e8cd8481..69327e976 100644 --- a/arkui-plugins/common/arkts-utils.ts +++ b/arkui-plugins/common/arkts-utils.ts @@ -194,4 +194,4 @@ export function readFirstLineSync(filePath: string): string | null { const firstLine = content.split(/\r?\n/, 1)[0].trim(); return firstLine; -} \ No newline at end of file +} diff --git a/arkui-plugins/common/file-manager.ts b/arkui-plugins/common/file-manager.ts index 11158be41..3e3781173 100644 --- a/arkui-plugins/common/file-manager.ts +++ b/arkui-plugins/common/file-manager.ts @@ -29,7 +29,7 @@ export class FileManager { static setInstance(instance: FileManager | undefined): void { if (instance === undefined) { - throw Error('fileManager is undefined!'); + FileManager.instance = new FileManager(); } FileManager.instance = instance; } @@ -78,4 +78,4 @@ export class FileManager { } return LANGUAGE_VERSION.ARKTS_1_1; } -} \ No newline at end of file +} diff --git a/arkui-plugins/common/plugin-context.ts b/arkui-plugins/common/plugin-context.ts index ffe81012d..0349fc4f5 100644 --- a/arkui-plugins/common/plugin-context.ts +++ b/arkui-plugins/common/plugin-context.ts @@ -161,4 +161,4 @@ export type PluginExecutor = { export interface BuildConfig { compileFiles: string[]; -} \ No newline at end of file +} diff --git a/arkui-plugins/common/program-visitor.ts b/arkui-plugins/common/program-visitor.ts index 9327b9075..999431f10 100644 --- a/arkui-plugins/common/program-visitor.ts +++ b/arkui-plugins/common/program-visitor.ts @@ -22,6 +22,8 @@ import { PluginContext } from './plugin-context'; import { LegacyTransformer } from '../ui-plugins/interop/legacy-transformer'; import { ComponentTransformer } from '../ui-plugins/component-transformer'; import { ProgramSkipper } from './program-skipper'; +import { FileManager } from './file-manager'; +import { LANGUAGE_VERSION } from './predefines'; export interface ProgramVisitorOptions extends VisitorOptions { pluginName: string; @@ -61,10 +63,6 @@ function flattenVisitorsInHooks( ]; } -export interface StructMap { - [key: string]: string; -} - export class ProgramVisitor extends AbstractVisitor { private readonly pluginName: string; private readonly state: arkts.Es2pandaContextState; @@ -73,8 +71,6 @@ export class ProgramVisitor extends AbstractVisitor { private readonly hooks?: ProgramHooks; private filenames: Map; private pluginContext?: PluginContext; - private legacyModuleList: string[] = []; - private legacyStructMap: Map; private isFrameworkMode: boolean = false; constructor(options: ProgramVisitorOptions) { @@ -86,8 +82,7 @@ export class ProgramVisitor extends AbstractVisitor { this.hooks = options.hooks; this.filenames = new Map(); this.pluginContext = options.pluginContext; - this.legacyModuleList = []; - this.legacyStructMap = new Map(); + FileManager.setInstance((this.pluginContext as PluginContext)?.getFileManager()); if (options.isFrameworkMode !== undefined) { this.isFrameworkMode = options.isFrameworkMode; @@ -97,26 +92,6 @@ export class ProgramVisitor extends AbstractVisitor { reset(): void { super.reset(); this.filenames = new Map(); - this.legacyStructMap = new Map(); - this.legacyModuleList = []; - } - - private getLegacyModule(): void { - const moduleList = this.pluginContext?.getProjectConfig()?.dependentModuleList; - if (moduleList === undefined) { - return; - } - for (const module of moduleList) { - const language = module.language; - const moduleName = module.moduleName; - if (language !== InteroperAbilityNames.ARKTS_1_1) { - continue; - } - if (!this.legacyStructMap.has(moduleName)) { - this.legacyStructMap.set(moduleName, {}); - this.legacyModuleList.push(moduleName); - } - } } private dumpExternalSource( @@ -134,15 +109,12 @@ export class ProgramVisitor extends AbstractVisitor { ); } - private visitLegacyInExternalSource(currProgram: arkts.Program, name: string): void { - if (this.state === arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED) { - const structList = this.visitorLegacy(currProgram.astNode, currProgram, name); - const moduleName = name.split('/')[0]; - const structMap = this.legacyStructMap.get(moduleName)!; - for (const struct of structList) { - structMap[struct] = name; - } - } + private visitLegacyInExternalSource(program: arkts.Program, externalSourceName: string): void { + const transformer = new LegacyTransformer(); + transformer.isExternal = !!externalSourceName; + transformer.externalSourceName = externalSourceName; + transformer.program = program; + transformer.visitor(program.astNode); } private visitNonLegacyInExternalSource( @@ -173,13 +145,20 @@ export class ProgramVisitor extends AbstractVisitor { } } + private isLegacyFile(path: string): boolean { + const fileManager = FileManager.getInstance(); + if (fileManager.getLanguageVersionByFilePath(path) === LANGUAGE_VERSION.ARKTS_1_1) { + return true; + } + return false; + } + private visitExternalSources( program: arkts.Program, programQueue: arkts.Program[] ): void { const visited = new Set(); const queue: arkts.Program[] = programQueue; - this.getLegacyModule(); while (queue.length > 0) { const currProgram = queue.shift()!; if (visited.has(currProgram.peer) || currProgram.isASTLowered()) { @@ -188,7 +167,8 @@ export class ProgramVisitor extends AbstractVisitor { if (currProgram.peer !== program.peer) { const name: string = this.filenames.get(currProgram.peer)!; const cachePath: string | undefined = this.pluginContext?.getProjectConfig()?.cachePath; - if (this.legacyModuleList && matchPrefix(this.legacyModuleList, name)) { + if (this.state === arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED && this.pluginName === 'uiTransform' && + this.isLegacyFile(currProgram.absName)) { this.visitLegacyInExternalSource(currProgram, name); } else { this.visitNonLegacyInExternalSource(program, currProgram, name, cachePath); @@ -266,9 +246,6 @@ export class ProgramVisitor extends AbstractVisitor { this.preVisitor(hook, node, program, externalSourceName); for (const transformer of this.visitors) { - if (this.legacyStructMap.size > 0 && transformer instanceof ComponentTransformer) { - transformer.registerMap(this.legacyStructMap); - } this.visitTransformer(transformer, script, externalSourceName, program); arkts.setAllParents(script); if (!transformer.isExternal) { @@ -288,16 +265,6 @@ export class ProgramVisitor extends AbstractVisitor { return script; } - private visitorLegacy(node: arkts.AstNode, program?: arkts.Program, externalSourceName?: string): string[] { - const transformer = new LegacyTransformer(); - transformer.isExternal = !!externalSourceName; - transformer.externalSourceName = externalSourceName; - transformer.program = program; - transformer.visitor(node); - const structList = transformer.getList(); - return structList; - } - private visitTransformer( transformer: AbstractVisitor, script: arkts.EtsScript, diff --git a/arkui-plugins/ui-plugins/checked-transformer.ts b/arkui-plugins/ui-plugins/checked-transformer.ts index 6ad631797..068d3b381 100644 --- a/arkui-plugins/ui-plugins/checked-transformer.ts +++ b/arkui-plugins/ui-plugins/checked-transformer.ts @@ -201,7 +201,7 @@ export class CheckedTransformer extends AbstractVisitor { } else if (arkts.isClassDeclaration(node)) { return structFactory.transformNormalClass(node, this.externalSourceName); } else if (arkts.isCallExpression(node)) { - return structFactory.transformCallExpression(node, this.projectConfig, this.resourceInfo); + return structFactory.transformCallExpression(node, this.projectConfig, this.resourceInfo, this.scope.customComponents.length === 0); } else if (arkts.isTSInterfaceDeclaration(node)) { return structFactory.tranformInterfaceMembers(node, this.externalSourceName); } else if ( diff --git a/arkui-plugins/ui-plugins/component-transformer.ts b/arkui-plugins/ui-plugins/component-transformer.ts index ae383cc16..3fc5fce9d 100644 --- a/arkui-plugins/ui-plugins/component-transformer.ts +++ b/arkui-plugins/ui-plugins/component-transformer.ts @@ -44,7 +44,6 @@ import { factory as entryFactory } from './entry-translators/factory'; import { hasDecoratorName, findDecoratorInfos, DecoratorInfo } from './property-translators/utils'; import { factory } from './ui-factory'; import { factory as propertyFactory } from './property-translators/factory'; -import { StructMap } from '../common/program-visitor'; import { CUSTOM_COMPONENT_IMPORT_SOURCE_NAME, DecoratorIntrinsicNames, @@ -54,7 +53,6 @@ import { NavigationNames, EntryWrapperNames, } from '../common/predefines'; -import { generateInstantiateInterop } from './interop/interop'; export interface ComponentTransformerOptions extends VisitorOptions { arkui?: string; @@ -84,9 +82,6 @@ export class ComponentTransformer extends AbstractVisitor { private isPageLifeCycleImported: boolean = false; private isLayoutCallbackImported: boolean = false; private shouldAddLinkIntrinsic: boolean = false; - private hasLegacy: boolean = false; - private legacyStructMap: Map = new Map(); - private legacyCallMap: Map = new Map(); private projectConfig: ProjectConfig | undefined; private entryRouteName: string | undefined; private componentType: ComponentType = { @@ -115,9 +110,6 @@ export class ComponentTransformer extends AbstractVisitor { this.isPageLifeCycleImported = false; this.isLayoutCallbackImported = false; this.shouldAddLinkIntrinsic = false; - this.hasLegacy = false; - this.legacyStructMap = new Map(); - this.legacyCallMap = new Map(); this.componentType = { hasComponent: false, hasComponentV2: false, @@ -482,58 +474,6 @@ export class ComponentTransformer extends AbstractVisitor { return [originMember, optionsHasMember]; } - registerMap(map: Map): void { - this.legacyStructMap = map; - this.hasLegacy = true; - } - - processInteropImport(node: arkts.ETSImportDeclaration): void { - const source = node.source?.str!; - const specifiers = node.specifiers as arkts.ImportSpecifier[]; - if (this.legacyStructMap.has(source)) { - const structMap = this.legacyStructMap.get(source); - if (!structMap) { - return; - } - for (const specifier of specifiers) { - const name = (specifier as arkts.ImportSpecifier)!.local!.name; - if (structMap[name]) { - this.legacyCallMap.set(name, structMap[name]); - } - } - } - } - - processInteropCall(node: arkts.CallExpression): arkts.CallExpression { - const ident = node.expression; - if (!(ident instanceof arkts.Identifier)) { - return node; - } - const className = ident.name; - const trailingBlock = node.trailingBlock; - const content = trailingBlock - ? arkts.factory.createArrowFunction( - factory.createScriptFunction({ - body: trailingBlock, - flags: arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW, - modifiers: arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, - }) - ) - : undefined; - if (this.legacyCallMap.has(className)) { - const path = this.legacyCallMap.get(className)!; - const args = node.arguments; - const context: InteropContext = { - className: className, - path: path, - arguments: args && args.length === 1 && args[0] instanceof arkts.ObjectExpression ? args[0] : undefined, - content: content, - }; - return generateInstantiateInterop(context); - } - return node; - } - visitor(node: arkts.AstNode): arkts.AstNode { this.enter(node); const newNode = this.visitEachChild(node); @@ -562,16 +502,6 @@ export class ComponentTransformer extends AbstractVisitor { ) { return factory.updateCustomDialogOptionsInterface(newNode); } - // process interop code - if (!this.hasLegacy) { - return newNode; - } - if (arkts.isETSImportDeclaration(newNode)) { - this.processInteropImport(newNode); - } - if (arkts.isCallExpression(newNode)) { - return this.processInteropCall(newNode); - } return newNode; } } diff --git a/arkui-plugins/ui-plugins/interop/interop.ts b/arkui-plugins/ui-plugins/interop/interop.ts index 554444410..447373933 100644 --- a/arkui-plugins/ui-plugins/interop/interop.ts +++ b/arkui-plugins/ui-plugins/interop/interop.ts @@ -29,8 +29,6 @@ import { createELMTID, createInitReturn } from './utils'; -import { ImportCollector } from '../../common/import-collector'; -import { factory as uiFactory } from '../ui-factory'; import { DecoratorNames } from '../../common/predefines'; import { hasDecorator } from '../property-translators/utils'; @@ -329,12 +327,8 @@ function updateArguments(context: InteropContext, name: string): arkts.ObjectExp ); } -function generateVarMap(context: InteropContext, node: arkts.Identifier): Map { +function generateVarMap(context: InteropContext, decl: arkts.ClassDefinition): Map { let needBuilderParam = !!context.content; - const decl = arkts.getDecl(node); - if (!(decl instanceof arkts.ClassDefinition)) { - throw Error("can't find legacy class declaration"); - } const result = new Map(); const definition = decl; const body = definition.body; @@ -351,89 +345,56 @@ function generateVarMap(context: InteropContext, node: arkts.Identifier): Map.instantiate_Interop. - */ -export function generateInstantiateInterop(context: InteropContext): arkts.CallExpression { - return arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - arkts.factory.createIdentifier(context.className), - arkts.factory.createIdentifier('instantiate_Interop'), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), - undefined, - generateStructInfo(context) - ); -} - -/** - * - * @param node - * @returns {boolean} Checks if a given CallExpression represents a call to .instantiate_Interop. - */ -export function isArkUICompatible(node: arkts.AstNode): boolean { - if (node instanceof arkts.CallExpression && node.expression instanceof arkts.MemberExpression && - node.expression.property instanceof arkts.Identifier && - node.expression.property.name === 'instantiate_Interop') { - ImportCollector.getInstance().collectSource(InteroperAbilityNames.ARKUICOMPATIBLE, InteroperAbilityNames.INTEROP); - ImportCollector.getInstance().collectImport(InteroperAbilityNames.ARKUICOMPATIBLE); - ImportCollector.getInstance().collectSource(InteroperAbilityNames.GETCOMPATIBLESTATE, InteroperAbilityNames.INTEROP); - ImportCollector.getInstance().collectImport(InteroperAbilityNames.GETCOMPATIBLESTATE); - ImportCollector.getInstance().collectSource(BuilderMethodNames.TRANSFERCOMPATIBLEBUILDER, InteroperAbilityNames.INTEROP); - ImportCollector.getInstance().collectImport(BuilderMethodNames.TRANSFERCOMPATIBLEBUILDER); - ImportCollector.getInstance().collectSource(BuilderMethodNames.TRANSFERCOMPATIBLEUPDATABLEBUILDER, InteroperAbilityNames.INTEROP); - ImportCollector.getInstance().collectImport(BuilderMethodNames.TRANSFERCOMPATIBLEUPDATABLEBUILDER); - return true; +export function processArgumens(arg: arkts.Expression): arkts.ObjectExpression { + if (!arkts.isObjectExpression(arg)) { + throw new Error('Cannot find arguments for InteropComponent'); } - return false; + const properties = arg.properties.map((property: arkts.Property) => { + const key = property.key; + if (arkts.isIdentifier(key) && key.name.startsWith('__backing_')) { + return arkts.factory.updateProperty( + property, + arkts.factory.updateIdentifier( + key, + key.name.slice('__backing_'.length) + ), + property.value + ); + } + return property; + }); + return arkts.factory.updateObjectExpression( + arg, + arkts.Es2pandaAstNodeType.AST_NODE_TYPE_OBJECT_EXPRESSION, + properties, + false + ); } - /** * * @param node * @returns After Checked, transform instantiate_Interop -> ArkUICompatible */ -export function generateArkUICompatible(node: arkts.CallExpression): arkts.CallExpression { +export function generateArkUICompatible(node: arkts.CallExpression, builder: boolean): arkts.CallExpression { const classInterop = (node.expression as arkts.MemberExpression).object as arkts.Identifier; const className = classInterop.name; + const decl = arkts.getDecl(classInterop); + if (!(decl instanceof arkts.ClassDefinition)) { + throw Error("can't find legacy class declaration"); + } + const filePath = arkts.getProgramFromAstNode(decl).moduleName; const args = node.arguments; - const path = (args[0] as arkts.StringLiteral).str; - const line = args[1] instanceof arkts.UndefinedLiteral ? undefined : (args[1] as arkts.NumberLiteral).value; - const col = args[2] instanceof arkts.UndefinedLiteral ? undefined : (args[2] as arkts.NumberLiteral).value; - const options = args[3] instanceof arkts.UndefinedLiteral ? undefined : args[3] as arkts.ObjectExpression; - const content = args[4] instanceof arkts.UndefinedLiteral ? undefined : args[4] as arkts.ArrowFunctionExpression; + const options = arkts.isUndefinedLiteral(args[2]) ? undefined : processArgumens(args[2]); + const content = arkts.isUndefinedLiteral(args[4]) ? undefined : args[4]; const context: InteropContext = { className: className, - path: path, - line: line, - col: col, + path: filePath, arguments: options, content: content, }; - const varMap: Map = generateVarMap(context, classInterop); + const varMap: Map = generateVarMap(context, decl); const updateProp: arkts.Property[] = []; const initializer = createInitializer(context, varMap, updateProp); const updater = createUpdater(updateProp); @@ -444,7 +405,7 @@ export function generateArkUICompatible(node: arkts.CallExpression): arkts.CallE [ initializer, updater, - arkts.factory.createThisExpression(), + builder ? arkts.factory.createUndefinedLiteral() : arkts.factory.createThisExpression(), ] ); arkts.NodeCache.getInstance().collect(result); diff --git a/arkui-plugins/ui-plugins/interop/legacy-transformer.ts b/arkui-plugins/ui-plugins/interop/legacy-transformer.ts index 1b831a9b0..55aa4162a 100644 --- a/arkui-plugins/ui-plugins/interop/legacy-transformer.ts +++ b/arkui-plugins/ui-plugins/interop/legacy-transformer.ts @@ -49,15 +49,10 @@ export class LegacyTransformer extends AbstractVisitor { // TODO: check reset reset(): void { super.reset(); - this.structList = []; this.componentInterfaceCollection = []; this.scopeInfos = []; } - getList(): string[] { - return this.structList; - } - createParam(name: string, type: string): arkts.ETSParameterExpression { return arkts.factory.createParameterDeclaration( arkts.factory.createIdentifier( @@ -72,38 +67,6 @@ export class LegacyTransformer extends AbstractVisitor { ); } - createInteropMethod(name: string): arkts.MethodDefinition { - const path = this.createParam('path', 'string'); - const line = this.createParam('line', 'number'); - line.setOptional(true); - const col = this.createParam('col', 'number'); - col.setOptional(true); - const options = this.createParam('options', getCustomComponentOptionsName(name)); - options.setOptional(true); - const trailingBlock = this.createParam('trailingBlock', 'Object'); - trailingBlock.setOptional(true); - - const script = arkts.factory.createScriptFunction( - arkts.factory.createBlock([]), - arkts.FunctionSignature.createFunctionSignature( - undefined, - [path, line, col, options, trailingBlock], - arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID), - false - ), - arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_METHOD, - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC | arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_STATIC - ); - - return arkts.factory.createMethodDefinition( - arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_METHOD, - arkts.factory.createIdentifier('instantiate_Interop'), - script, - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC | arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_STATIC, - false - ); - } - generateMember(map: Map): arkts.ClassProperty[] { const properties: arkts.ClassProperty[] = []; @@ -146,17 +109,15 @@ export class LegacyTransformer extends AbstractVisitor { this.structList.push(ident.name); } - const instantiate_Interop: arkts.MethodDefinition = this.createInteropMethod(ident.name); - const newDefinition = arkts.factory.updateClassDefinition( definition, definition.ident, definition.typeParams, - definition.superTypeParams, + undefined, definition.implements, undefined, - definition.super, - [...definition.body, instantiate_Interop], + undefined, + definition.body, definition.modifiers, arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, arkts.Es2pandaLanguage.JS @@ -245,8 +206,9 @@ export class LegacyTransformer extends AbstractVisitor { } enter(node: arkts.AstNode): void { - if (arkts.isStructDeclaration(node) && !!node.definition.ident) { - const scopeInfo: ScopeInfo = { name: node.definition.ident.name }; + if ((arkts.isStructDeclaration(node) || arkts.isClassDeclaration(node)) && !!node.definition.ident) { + const isComponent = node.definition.annotations.some(annotation => annotation.expr instanceof arkts.Identifier && annotation.expr.name === 'Component'); + const scopeInfo: ScopeInfo = { name: node.definition.ident.name, isComponent: isComponent}; this.scopeInfos.push(scopeInfo); } } @@ -318,25 +280,37 @@ export class LegacyTransformer extends AbstractVisitor { if (arkts.isEtsScript(newNode)) { return this.processEtsScript(newNode); } - if (arkts.isStructDeclaration(newNode)) { + if (arkts.isStructDeclaration(newNode) || arkts.isClassDeclaration(newNode)) { const definition = newNode.definition!; const annotations = definition.annotations; - if (annotations.some(annotation => annotation instanceof arkts.Identifier && annotation.name === 'Component')) { - return newNode; + if (annotations.some(annotation => annotation.expr instanceof arkts.Identifier && annotation.expr.name === 'Component')) { + const updateNode = this.processComponent(newNode); + this.exit(newNode); + return updateNode; } - const className = newNode.definition?.ident?.name!; - const memberMap = this.collectComponentMembers(newNode as arkts.StructDeclaration, className); - this.componentInterfaceCollection.push(this.generateComponentInterface(className, node.modifiers, memberMap)); - const updateNode = this.processComponent(newNode); - this.exit(newNode); - return updateNode; + return newNode; } - if (this.scopeInfos.length > 0 && arkts.isMethodDefinition(newNode)) { + if (this.scopeInfos.length > 0 && this.scopeInfos[this.scopeInfos.length - 1].isComponent === true && + arkts.isMethodDefinition(newNode)) { const kind = newNode.kind; if (kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_CONSTRUCTOR) { const updateNode = this.processConstructor(newNode); return updateNode; } + if (newNode.name.name === 'build') { + return arkts.factory.updateMethodDefinition( + newNode, + newNode.kind, + newNode.name, + factory.createScriptFunction( + { + returnTypeAnnotation: arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID) + } + ), + newNode.modifiers, + false + ); + } } if (arkts.isVariableDeclarator(newNode)) { return this.handleWrappedBuilder(newNode); diff --git a/arkui-plugins/ui-plugins/interop/utils.ts b/arkui-plugins/ui-plugins/interop/utils.ts index 3dff5e7af..a6a199ba6 100644 --- a/arkui-plugins/ui-plugins/interop/utils.ts +++ b/arkui-plugins/ui-plugins/interop/utils.ts @@ -16,7 +16,11 @@ import * as arkts from '@koalaui/libarkts'; -import { ESValueMethodNames, InteroperAbilityNames } from './predefines'; +import { BuilderMethodNames, ESValueMethodNames, InteroperAbilityNames } from './predefines'; +import { LANGUAGE_VERSION } from '../../common/predefines'; +import { FileManager } from '../../common/file-manager'; +import { BuilderLambdaNames } from '../utils'; +import { ImportCollector } from '../../common/import-collector'; /** @@ -221,3 +225,43 @@ export function createGlobal(): arkts.Statement { )] ); } + + +export function isInstantiateImpl(node: arkts.MemberExpression): boolean { + const property = node.property; + if (arkts.isIdentifier(property) && property.name === BuilderLambdaNames.TRANSFORM_METHOD_NAME) { + return true; + } + return false; +} + +export function isArkTS1_1(node: arkts.MemberExpression): boolean { + const struct = node.object; + const decl = arkts.getDecl(struct); + if (!decl) { + return false; + } + const filePath = arkts.getProgramFromAstNode(decl).absName; + const fileManager = FileManager.getInstance(); + if (fileManager.getLanguageVersionByFilePath(filePath) === LANGUAGE_VERSION.ARKTS_1_1) { + return true; + } + return false; +} + +export function isInteropComponent(node: arkts.CallExpression): boolean { + if ( + arkts.isMemberExpression(node.expression) && + isInstantiateImpl(node.expression) && + isArkTS1_1(node.expression) + ) { + ImportCollector.getInstance().collectSource(InteroperAbilityNames.ARKUICOMPATIBLE, InteroperAbilityNames.INTEROP); + ImportCollector.getInstance().collectImport(InteroperAbilityNames.ARKUICOMPATIBLE); + ImportCollector.getInstance().collectSource(InteroperAbilityNames.GETCOMPATIBLESTATE, InteroperAbilityNames.INTEROP); + ImportCollector.getInstance().collectImport(InteroperAbilityNames.GETCOMPATIBLESTATE); + ImportCollector.getInstance().collectSource(BuilderMethodNames.TRANSFERCOMPATIBLEBUILDER, InteroperAbilityNames.INTEROP); + ImportCollector.getInstance().collectImport(BuilderMethodNames.TRANSFERCOMPATIBLEBUILDER); + return true; + } + return false; +} diff --git a/arkui-plugins/ui-plugins/struct-translators/factory.ts b/arkui-plugins/ui-plugins/struct-translators/factory.ts index a7ebee0c7..65b55b334 100644 --- a/arkui-plugins/ui-plugins/struct-translators/factory.ts +++ b/arkui-plugins/ui-plugins/struct-translators/factory.ts @@ -76,9 +76,10 @@ import { } from '../../common/predefines'; import { ObservedTranslator } from '../property-translators/index'; import { addMemoAnnotation } from '../../collectors/memo-collectors/utils'; -import { generateArkUICompatible, isArkUICompatible } from '../interop/interop'; +import { generateArkUICompatible } from '../interop/interop'; import { GenSymGenerator } from '../../common/gensym-generator'; import { MethodTranslator } from '../property-translators/base'; +import { isInteropComponent } from '../interop/utils'; import { MonitorCache } from '../property-translators/cache/monitorCache'; import { PropertyCache } from '../property-translators/cache/propertyCache'; import { ComponentAttributeCache } from '../builder-lambda-translators/cache/componentAttributeCache'; @@ -1085,13 +1086,14 @@ export class factory { static transformCallExpression( node: arkts.CallExpression, projectConfig: ProjectConfig | undefined, - resourceInfo: ResourceInfo + resourceInfo: ResourceInfo, + builder: boolean ): arkts.CallExpression { if (arkts.isCallExpression(node) && isResourceNode(node)) { return this.transformResource(node, projectConfig, resourceInfo); } - if (isArkUICompatible(node)) { - return generateArkUICompatible(node as arkts.CallExpression); + if (arkts.isCallExpression(node) && isInteropComponent(node)) { + return generateArkUICompatible(node, builder); } return node; } -- Gitee