diff --git a/arkui-plugins/ui-plugins/interop/initstatevar.ts b/arkui-plugins/ui-plugins/interop/initstatevar.ts index 9a8c143e9c2f38cf35ac9cf8685e465bd74093e0..41a51d0578d91c8b91d1a55a3185b8161a6c2d00 100644 --- a/arkui-plugins/ui-plugins/interop/initstatevar.ts +++ b/arkui-plugins/ui-plugins/interop/initstatevar.ts @@ -18,9 +18,62 @@ import * as arkts from '@koalaui/libarkts'; import { ESValueMethodNames, InteroperAbilityNames } from './predefines'; import { annotation, backingField, isAnnotation } from '../../common/arkts-utils'; -import { stateProxy, getPropertyESValue, getWrapValue, ifStateHasProxy, setPropertyESValue, hasLink, hasState, hasProvide, hasProp } from './utils'; +import { stateProxy, getPropertyESValue, getWrapValue, ifStateHasProxy, setPropertyESValue } from './utils'; +import { hasDecorator } from '../property-translators/utils'; +import { DecoratorNames } from '../../common/predefines'; +export function initialArgs(args: arkts.ObjectExpression, varMap: Map, updateProp: arkts.Property[]): arkts.Statement[] { + const result: arkts.Statement[] = []; + const proxySet = new Set(); + + + for (const property of args.properties) { + if (!(property instanceof arkts.Property)) { + continue; + } + const key = property.key; + const value = property.value!; + if (!(key instanceof arkts.Identifier)) { + throw Error('Error arguments in Legacy Component'); + } + const keyName = key.name; + const keyProperty = varMap.get(keyName); + if (keyProperty === undefined) { + throw Error('Error arguments in Legacy Component'); + } + const keyType = keyProperty.typeAnnotation!; + const decorators = keyProperty.decorators; + if (decorators.length === 0) { + const valueProperty = arkts.getDecl(value); + if (valueProperty instanceof arkts.ClassProperty && (hasDecorator(valueProperty, DecoratorNames.PROVIDE) || + hasDecorator(valueProperty, DecoratorNames.CONSUME))) { + throw Error('Cannot assign @Provide or @Consume decorated data to regular property.'); + } + const initParam = processNormal(keyName, value); + result.push(...initParam); + } + if (hasDecorator(keyProperty, DecoratorNames.LINK)) { + const initParam = processLink(keyName, value, keyType, proxySet); + result.push(...initParam); + } else if (hasDecorator(keyProperty, DecoratorNames.CONSUME)) { + throw Error ('The @Consume property cannot be assigned.'); + } else if (hasDecorator(keyProperty, DecoratorNames.PROP)) { + updateProp.push(property); + const initParam = processNormal(keyName, value); + result.push(...initParam); + } else if (hasDecorator(keyProperty, DecoratorNames.STATE) || hasDecorator(keyProperty, DecoratorNames.PROVIDE)) { + const initParam = processNormal(keyName, value); + result.push(...initParam); + } else if (hasDecorator(keyProperty, DecoratorNames.CONSUME)) { + throw Error ('The @Consume property cannot be assigned.'); + } else { + throw Error ('Unsupported decorators.'); + } + } + return result; +} + export function createVariableLet(varName: string, expression: arkts.AstNode): arkts.VariableDeclaration { return arkts.factory.createVariableDeclaration( arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, @@ -291,18 +344,14 @@ export function processLink(keyName: string, value: arkts.Expression, type: arkt const valueDecl = arkts.getDecl(value); const result: arkts.Statement[] = []; if (valueDecl instanceof arkts.ClassProperty) { - const annotations = valueDecl.annotations; - const decorators: string[] = annotations.map(annotation => { - return (annotation.expr as arkts.Identifier).name; - }); - let varName: string; let stateVar: () => arkts.Expression; - if (hasState(decorators) || hasProvide(decorators) || hasProp(decorators)) { + if (hasDecorator(valueDecl, DecoratorNames.STATE) || hasDecorator(valueDecl, DecoratorNames.PROP) || + hasDecorator(valueDecl, DecoratorNames.PROVIDE)) { varName = ((value as arkts.MemberExpression).property as arkts.Identifier).name; stateVar = (): arkts.TSNonNullExpression => createBackingFieldExpression(varName); - } else if (hasLink(decorators)) { + } else if (hasDecorator(valueDecl, DecoratorNames.LINK) || hasDecorator(valueDecl, DecoratorNames.CONSUME)) { varName = ((value as arkts.MemberExpression).property as arkts.Identifier).name; const stateName = `${varName}_State`; const getSource = linkGetSource(varName, proxySet); @@ -324,7 +373,7 @@ export function processLink(keyName: string, value: arkts.Expression, type: arkt ); result.push(setParam); } else { - throw Error('unsupported value for Link'); + throw Error('unsupported data for Link'); } return result; } diff --git a/arkui-plugins/ui-plugins/interop/interop.ts b/arkui-plugins/ui-plugins/interop/interop.ts index 946dc441a5c2bd89333423a0b33a86da65e828ba..460c5fc667f914b4079b1de6006cd81fe0b2463f 100644 --- a/arkui-plugins/ui-plugins/interop/interop.ts +++ b/arkui-plugins/ui-plugins/interop/interop.ts @@ -19,50 +19,9 @@ import * as arkts from '@koalaui/libarkts'; import { ESValueMethodNames, InteroperAbilityNames } from './predefines'; import { getCustomComponentOptionsName } from '../utils'; import { InteropContext } from '../component-transformer'; -import { annotation, backingField, isAnnotation } from '../../common/arkts-utils'; -import { processLink, processNormal } from './initstatevar'; +import { initialArgs} from './initstatevar'; import { createProvideInterop, setAndResetFindProvide } from './provide'; -import { getPropertyESValue, getWrapValue, setPropertyESValue, hasLink, createEmptyESValue, hasProp } from './utils'; - -interface propertyInfo { - decorators: string[], - type: arkts.TypeNode, -} - -function initialArgs(args: arkts.ObjectExpression, varMap: Map, updateProp: arkts.Property[]): arkts.Statement[] { - const result: arkts.Statement[] = []; - const proxySet = new Set(); - - for (const property of args.properties) { - if (!(property instanceof arkts.Property)) { - continue; - } - const key = property.key; - const value = property.value; - if (!(key instanceof arkts.Identifier)) { - throw Error('Error arguments in Legacy Component'); - } - const keyName = key.name; - const keyDecorators = varMap.get(keyName)?.decorators; - const keyType = varMap.get(keyName)?.type!; - if (value instanceof arkts.MemberExpression && value.object instanceof arkts.ThisExpression) { - const declResult = arkts.getDecl(value); - } - - if (keyDecorators === undefined) { - const initParam = processNormal(keyName, value!); - result.push(...initParam); - } else if (hasLink(keyDecorators)) { - const initParam = processLink(keyName, value!, keyType, proxySet); - result.push(...initParam); - } else if (hasProp(keyDecorators)) { - updateProp.push(property); - const initParam = processNormal(keyName, value!); - result.push(...initParam); - } - } - return result; -} +import { getPropertyESValue, getWrapValue, setPropertyESValue, createEmptyESValue } from './utils'; function instantiateComponent(params: arkts.AstNode[]): arkts.VariableDeclaration { return arkts.factory.createVariableDeclaration( @@ -206,7 +165,7 @@ function createESBlank(): arkts.Statement[] { arkts.factory.createIdentifier('blank'), arkts.factory.createTypeReference( arkts.factory.createTypeReferencePart( - arkts.factory.createIdentifier('object') + arkts.factory.createIdentifier('Object') ) ), false @@ -340,7 +299,7 @@ function invokeViewPUCreate(): arkts.Statement[] { return body; } -function createWrapperBlock(context: InteropContext, varMap: Map, +function createWrapperBlock(context: InteropContext, varMap: Map, updateProp: arkts.Property[]): arkts.BlockStatement { const className: string = context.className; const path: string = context.path; @@ -379,7 +338,7 @@ function createWrapperBlock(context: InteropContext, varMap: Map, +function createInitializer(context: InteropContext, varMap: Map, updateProp: arkts.Property[]): arkts.ArrowFunctionExpression { const block = createWrapperBlock(context, varMap, updateProp); return arkts.factory.createArrowFunction( @@ -397,13 +356,13 @@ function createInitializer(context: InteropContext, varMap: Map { +function generateVarMap(node: arkts.Identifier): Map { const decl = arkts.getDecl(node); if (!(decl instanceof arkts.ClassDefinition)) { throw Error("can't find legacy class declaration"); } - const result = new Map(); + const result = new Map(); const definition = decl; const body = definition.body; body.forEach(node => { if (node instanceof arkts.ClassProperty && node.key instanceof arkts.Identifier) { const key = node.key.name; - const annotations = node.annotations; - const decorators: string[] = annotations.map(annotation => { - return (annotation.expr as arkts.Identifier).name; - }); - const type: arkts.TypeNode = node.typeAnnotation!; - result.set(key, {decorators: decorators, type: type}); + result.set(key, node); } }); return result; @@ -544,7 +498,7 @@ export function generateArkUICompatible(node: arkts.CallExpression): arkts.CallE arguments: options }; - const varMap: Map = generateVarMap(classInterop); + const varMap: Map = generateVarMap(classInterop); const updateProp:arkts.Property[] = []; const initializer = createInitializer(context, varMap, updateProp); const updater = createUpdater(updateProp); diff --git a/arkui-plugins/ui-plugins/interop/predefines.ts b/arkui-plugins/ui-plugins/interop/predefines.ts index c70c8e0177ae2e668e2254ad1a9a735971071e55..af53a5278e9346065061bbff94e6fa6147fb9688 100644 --- a/arkui-plugins/ui-plugins/interop/predefines.ts +++ b/arkui-plugins/ui-plugins/interop/predefines.ts @@ -17,7 +17,7 @@ export enum InteroperAbilityNames { ARKTS_1_1 = '1.1', ARKTS_1_2 = '1.2', - ARKUICOMPATIBLE = 'ArkUICompatible', + ARKUICOMPATIBLE = 'compatibleComponent', ELMTID = 'elmtId', NUMBER = 'number', PARENT = 'parent', diff --git a/arkui-plugins/ui-plugins/interop/provide.ts b/arkui-plugins/ui-plugins/interop/provide.ts index 19732e624bb2257139483669cce356da77b294f1..ce9e0bb799433e30db470ea144147dbfebbde9b5 100644 --- a/arkui-plugins/ui-plugins/interop/provide.ts +++ b/arkui-plugins/ui-plugins/interop/provide.ts @@ -71,26 +71,34 @@ function getProvideProxy(): arkts.Statement { function returnProvide(): arkts.Statement { return arkts.factory.createReturnStatement( - arkts.factory.createTSNonNullExpression( - arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - arkts.factory.createTSAsExpression( - arkts.factory.createIdentifier('proxy'), - arkts.factory.createTypeReference( - arkts.factory.createTypeReferencePart( - arkts.factory.createIdentifier(ESValueMethodNames.ESVALUE) - ) + arkts.factory.createTSAsExpression( + arkts.factory.createTSNonNullExpression( + arkts.factory.createCallExpression( + arkts.factory.createMemberExpression( + arkts.factory.createTSAsExpression( + arkts.factory.createIdentifier('proxy'), + arkts.factory.createTypeReference( + arkts.factory.createTypeReferencePart( + arkts.factory.createIdentifier(ESValueMethodNames.ESVALUE) + ) + ), + false ), + arkts.factory.createIdentifier(ESValueMethodNames.UNWRAP), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, + false, false ), - arkts.factory.createIdentifier(ESValueMethodNames.UNWRAP), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), - undefined, - undefined - ) + undefined, + undefined + ) + ), + arkts.factory.createTypeReference( + arkts.factory.createTypeReferencePart( + arkts.factory.createIdentifier('Object') + ) + ), + false ) ); } diff --git a/arkui-plugins/ui-plugins/interop/utils.ts b/arkui-plugins/ui-plugins/interop/utils.ts index c26e4051be20f232a056136a455d4e3fa4240bc0..44448d66774c8f868d50329c3e8ad96218f3f862 100644 --- a/arkui-plugins/ui-plugins/interop/utils.ts +++ b/arkui-plugins/ui-plugins/interop/utils.ts @@ -147,27 +147,6 @@ export function ifStateHasProxy(stateVar: () => arkts.Expression, block: arkts.B ); } -/** - * Checks if an array of decorator names contains the 'Link' decorator. - * @param {string[]} decorators - Array of decorator names applied to a property. - * @returns {boolean} True if the 'Link' decorator is present, otherwise false. - */ -export function hasLink(decorators: string[]): boolean { - return decorators.some(decorator => decorator === 'Link'); -} - -export function hasState(decorators: string[]): boolean { - return decorators.some(decorator => decorator === 'State'); -} - -export function hasProp(decorators: string[]): boolean { - return decorators.some(decorator => decorator === 'Prop'); -} - -export function hasProvide(decorators: string[]): boolean { - return decorators.some(decorator => decorator === 'Provide'); -} - /** * Generates a state proxy variable name by appending "_State_Proxy" suffix. * @param {string} stateVarName - Original state variable name to be proxied.