diff --git a/arkui-plugins/ui-plugins/interop/initstatevar.ts b/arkui-plugins/ui-plugins/interop/initstatevar.ts index 9a8c143e9c2f38cf35ac9cf8685e465bd74093e0..8ac0d576bdea91864434c737c86d267b3a6822f1 100644 --- a/arkui-plugins/ui-plugins/interop/initstatevar.ts +++ b/arkui-plugins/ui-plugins/interop/initstatevar.ts @@ -16,11 +16,63 @@ import * as arkts from '@koalaui/libarkts'; -import { ESValueMethodNames, InteroperAbilityNames } from './predefines'; +import { 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, getWrapValue, 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 annotations = keyProperty.annotations; + if (annotations.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); + } else 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, @@ -32,198 +84,6 @@ export function createVariableLet(varName: string, expression: arkts.AstNode): a )] ); } -function setValueCallback(name: string, block: arkts.BlockStatement, type?: arkts.TypeNode): arkts.AstNode { - return createVariableLet(name, - arkts.factory.createArrowFunction( - arkts.factory.createScriptFunction( - block, - arkts.factory.createFunctionSignature( - undefined, - [ - arkts.factory.createParameterDeclaration( - arkts.factory.createIdentifier( - 'value', - type ?? arkts.factory.createTypeReference( - arkts.factory.createTypeReferencePart( - arkts.factory.createIdentifier('Object') - ) - ) - ), - undefined - ) - ], - undefined, - false - ), - arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW, - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, - ) - ) - ); -} - -function createProxyBlock(stateVar: () => arkts.Expression): arkts.BlockStatement { - return arkts.factory.createBlock( - [ - arkts.factory.createExpressionStatement( - arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - stateVar(), - arkts.factory.createIdentifier('set'), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), - undefined, - [ - arkts.factory.createIdentifier('value') - ] - ) - ) - ] - ); -} - -function setCallbackForProxy(stateVar: () => arkts.Expression, type?: arkts.TypeNode): arkts.Statement[] { - const createCallback = setValueCallback('setSource', createProxyBlock(stateVar), type); - const createProxyState = createVariableLet('proxyState', - arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - arkts.factory.createIdentifier('createState'), - arkts.factory.createIdentifier(ESValueMethodNames.INVOKE), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), - undefined, - [ - getWrapValue( - arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - stateVar(), - arkts.factory.createIdentifier('get'), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), - undefined, - [] - ) - ), - getWrapValue(arkts.factory.createIdentifier('setSource')) - ] - ) - ); - return [createCallback, createProxyState]; -} - -function createSourceBlock(): arkts.BlockStatement { - return arkts.factory.createBlock( - [ - arkts.factory.createExpressionStatement( - arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - arkts.factory.createIdentifier('proxyState'), - arkts.factory.createIdentifier(ESValueMethodNames.INVOKEMETHOD), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), - undefined, - [ - arkts.factory.createStringLiteral('set'), - getWrapValue( - arkts.factory.createIdentifier('value') - ) - ] - ) - ) - ] - ); -} - -function createNotifyBlock(): arkts.BlockStatement { - return arkts.factory.createBlock( - [ - arkts.factory.createExpressionStatement( - arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - arkts.factory.createIdentifier('proxyState'), - arkts.factory.createIdentifier(ESValueMethodNames.INVOKEMETHOD), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), - undefined, - [ - arkts.factory.createStringLiteral('notifyPropertyHasChangedPU') - ] - ) - ) - ] - ); -} - -function setCallbackForSource(type?: arkts.TypeNode): arkts.Statement[] { - const createValueCallback = setValueCallback('setProxy', createSourceBlock(), type); - const block = createNotifyBlock(); - const createNotifyCallback = createVariableLet('notifyCallback', - arkts.factory.createArrowFunction( - arkts.factory.createScriptFunction( - block, - arkts.factory.createFunctionSignature( - undefined, - [ - arkts.factory.createParameterDeclaration( - arkts.factory.createIdentifier('propertyName', - arkts.factory.createTypeReference( - arkts.factory.createTypeReferencePart( - arkts.factory.createIdentifier('string') - ) - ) - ), - undefined, - ), - ], - undefined, - false - ), - arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW, - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, - ) - ) - ); - return [createValueCallback, createNotifyCallback]; -} - -function bindCompatibleState(stateVar: () => arkts.Expression): arkts.Statement { - return arkts.factory.createExpressionStatement( - arkts.factory.createCallExpression( - arkts.factory.createIdentifier(InteroperAbilityNames.CONFIGURESTATE), - undefined, - [ - stateVar(), - arkts.factory.createIdentifier('proxyState'), - arkts.factory.createIdentifier('setProxy'), - arkts.factory.createIdentifier('notifyCallback'), - ], - ) - ); -} - -function createProxyForState(stateVar: () => arkts.Expression, type?: arkts.TypeNode): arkts.Statement[] { - const setProxy = setCallbackForProxy(stateVar, type); - const setSource = setCallbackForSource(type); - const cfgState = bindCompatibleState(stateVar); - return [...setProxy, ...setSource, cfgState]; -} - - -export function setStateProxy(stateVar: () => arkts.Expression, type?: arkts.TypeNode): arkts.Statement[] { - const statements = createProxyForState(stateVar, type); - const ifProxy = ifStateHasProxy(stateVar, arkts.factory.createBlock(statements)); - return [ifProxy]; -} function createBackingFieldExpression(varName: string): arkts.TSNonNullExpression { return arkts.factory.createTSNonNullExpression( @@ -237,46 +97,19 @@ function createBackingFieldExpression(varName: string): arkts.TSNonNullExpressio ); } -function setAndGetProxy(varName: string, type: arkts.TypeNode, stateVar: () => arkts.Expression, - proxySet: Set): arkts.Statement[] { - const result: arkts.Statement[] = []; - if (!proxySet.has(stateProxy(varName))) { - proxySet.add(stateProxy(varName)); - const setProxy = setStateProxy(stateVar, type); - const getProxy = createVariableLet( - stateProxy(varName), - arkts.factory.createCallExpression( - arkts.factory.createIdentifier(InteroperAbilityNames.GETPROXY), - undefined, - [ - stateVar() - ] - ) - ); - result.push(...setProxy, getProxy); - } - return result; -} -function linkGetSource(varName: string, proxySet: Set): arkts.Statement[] { - const result: arkts.Statement[] = []; - const backingLink = createBackingFieldExpression(varName); - const stateName = `${varName}_State`; - if (!proxySet.has(stateName)) { - proxySet.add(stateName); - const getState = createVariableLet( - stateName, - arkts.factory.createCallExpression( - arkts.factory.createIdentifier(InteroperAbilityNames.GETSOURCE), - undefined, - [ - backingLink - ] - ) - ); - result.push(getState); - } - return result; +function getStateProxy(proxyName: string, stateVar: () => arkts.Expression): arkts.Statement { + return createVariableLet( + proxyName, + arkts.factory.createCallExpression( + arkts.factory.createIdentifier(InteroperAbilityNames.GETCOMPATIBLESTATE), + undefined, + [ + stateVar(), + arkts.factory.createIdentifier(InteroperAbilityNames.CREATESTATE) + ] + ) + ); } /** @@ -291,40 +124,28 @@ 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)) { - varName = ((value as arkts.MemberExpression).property as arkts.Identifier).name; - stateVar = (): arkts.TSNonNullExpression => createBackingFieldExpression(varName); - } else if (hasLink(decorators)) { - varName = ((value as arkts.MemberExpression).property as arkts.Identifier).name; - const stateName = `${varName}_State`; - const getSource = linkGetSource(varName, proxySet); - result.push(...getSource); - stateVar = (): arkts.TSNonNullExpression => arkts.factory.createTSNonNullExpression( - arkts.factory.createIdentifier(stateName) - ); + let varName = ((value as arkts.MemberExpression).property as arkts.Identifier).name; + let proxyName = stateProxy(varName); + let stateVar = (): arkts.TSNonNullExpression => createBackingFieldExpression(varName); + if (hasDecorator(valueDecl, DecoratorNames.STATE) || hasDecorator(valueDecl, DecoratorNames.PROP) || + hasDecorator(valueDecl, DecoratorNames.PROVIDE) || hasDecorator(valueDecl, DecoratorNames.LINK) || + hasDecorator(valueDecl, DecoratorNames.CONSUME)) { + if (!proxySet.has(varName)) { + proxySet.add(varName); + const getProxy = getStateProxy(proxyName, stateVar); + result.push(getProxy); + } } else { throw Error('unsupported decorator for Link'); } - - const proxyGet = setAndGetProxy(varName, type, stateVar, proxySet); - result.push(...proxyGet); - const setParam = setPropertyESValue( 'param', keyName, - arkts.factory.createIdentifier(stateProxy(varName)) + arkts.factory.createIdentifier(proxyName) ); 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..13687085fda7c6f215b66b231b529698f9fd9f42 100644 --- a/arkui-plugins/ui-plugins/interop/interop.ts +++ b/arkui-plugins/ui-plugins/interop/interop.ts @@ -19,74 +19,10 @@ 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 { createVariableLet, initialArgs} from './initstatevar'; import { createProvideInterop, setAndResetFindProvide } from './provide'; -import { getPropertyESValue, getWrapValue, setPropertyESValue, hasLink, createEmptyESValue, hasProp } from './utils'; +import { getPropertyESValue, getWrapValue, setPropertyESValue, createEmptyESValue } 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; -} - -function instantiateComponent(params: arkts.AstNode[]): arkts.VariableDeclaration { - return arkts.factory.createVariableDeclaration( - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, - arkts.Es2pandaVariableDeclarationKind.VARIABLE_DECLARATION_KIND_LET, - [ - arkts.factory.createVariableDeclarator( - arkts.Es2pandaVariableDeclaratorFlag.VARIABLE_DECLARATOR_FLAG_LET, - arkts.factory.createIdentifier(InteroperAbilityNames.COMPONENT), - arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - arkts.factory.createIdentifier(InteroperAbilityNames.STRUCTOBJECT), - arkts.factory.createIdentifier(ESValueMethodNames.INSTANTIATE), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), - undefined, - params - ) - ) - ] - ); -} function paramsLambdaDeclaration(name: string, args?: arkts.ObjectExpression): arkts.Statement[] { const result: arkts.Statement[] = []; @@ -162,69 +98,6 @@ function createExtraInfo(properties: string[], value: string[]): arkts.Statement return body; } -function createESUndefined(): arkts.Statement { - return arkts.factory.createVariableDeclaration( - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, - arkts.Es2pandaVariableDeclarationKind.VARIABLE_DECLARATION_KIND_LET, - [ - arkts.factory.createVariableDeclarator( - arkts.Es2pandaVariableDeclaratorFlag.VARIABLE_DECLARATOR_FLAG_LET, - arkts.factory.createIdentifier('esundefined'), - getWrapValue(arkts.factory.createUndefinedLiteral()) - ) - ] - ); -} - -function createESBlank(): arkts.Statement[] { - const body: arkts.Statement[] = []; - const blank = arkts.factory.createVariableDeclaration( - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, - arkts.Es2pandaVariableDeclarationKind.VARIABLE_DECLARATION_KIND_LET, - [ - arkts.factory.createVariableDeclarator( - arkts.Es2pandaVariableDeclaratorFlag.VARIABLE_DECLARATOR_FLAG_LET, - arkts.factory.createIdentifier('blank'), - arkts.factory.createArrowFunction( - arkts.factory.createScriptFunction( - arkts.factory.createBlock([]), - arkts.factory.createFunctionSignature( - undefined, - [], - undefined, - false - ), - arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW, - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, - ) - ) - ) - ] - ); - body.push(blank); - const asExpression = arkts.factory.createTSAsExpression( - arkts.factory.createIdentifier('blank'), - arkts.factory.createTypeReference( - arkts.factory.createTypeReferencePart( - arkts.factory.createIdentifier('object') - ) - ), - false - ); - const esblank = arkts.factory.createVariableDeclaration( - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, - arkts.Es2pandaVariableDeclarationKind.VARIABLE_DECLARATION_KIND_LET, - [ - arkts.factory.createVariableDeclarator( - arkts.Es2pandaVariableDeclaratorFlag.VARIABLE_DECLARATOR_FLAG_LET, - arkts.factory.createIdentifier('esblank'), - getWrapValue(asExpression) - ) - ] - ); - body.push(esblank); - return body; -} function createGlobal(): arkts.Statement { return arkts.factory.createVariableDeclaration( @@ -277,55 +150,76 @@ function createELMTID(): arkts.Statement[] { return body; } -function createComponent(moduleName: string, className: string): arkts.Statement[] { - const body: arkts.Statement[] = []; - const module = arkts.factory.createVariableDeclaration( - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, - arkts.Es2pandaVariableDeclarationKind.VARIABLE_DECLARATION_KIND_LET, - [ - arkts.factory.createVariableDeclarator( - arkts.Es2pandaVariableDeclaratorFlag.VARIABLE_DECLARATOR_FLAG_LET, - arkts.factory.createIdentifier(moduleName), - arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - arkts.factory.createIdentifier(ESValueMethodNames.ESVALUE), - arkts.factory.createIdentifier(ESValueMethodNames.LOAD), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, + +function generateTSASExpression(expression: arkts.AstNode): arkts.Expression { + return arkts.factory.createTSAsExpression( + arkts.factory.createCallExpression( + arkts.factory.createMemberExpression( + expression, + arkts.factory.createIdentifier('unwrap'), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, + false, + false + ), + undefined, + undefined + ), + arkts.factory.createTypeReference( + arkts.factory.createTypeReferencePart( + arkts.factory.createIdentifier('Object') + ) + ), + false + ); +} + +function newComponent(className: string): arkts.Statement { + return createVariableLet( + InteroperAbilityNames.COMPONENT, + getWrapValue( + arkts.factory.createETSNewClassInstanceExpression( + arkts.factory.createIdentifier(className), + [ + generateTSASExpression(getWrapValue(arkts.factory.createUndefinedLiteral())), + generateTSASExpression(arkts.factory.createIdentifier(InteroperAbilityNames.PARAM)), + generateTSASExpression(getWrapValue(arkts.factory.createUndefinedLiteral())), + generateTSASExpression(arkts.factory.createIdentifier(InteroperAbilityNames.ELMTID)), + arkts.factory.createTSAsExpression( + arkts.factory.createArrowFunction( + arkts.factory.createScriptFunction( + arkts.factory.createBlock([]), + arkts.factory.createFunctionSignature( + undefined, + [], + undefined, + false + ), + arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW, + arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, + ) + ), + arkts.factory.createTypeReference( + arkts.factory.createTypeReferencePart( + arkts.factory.createIdentifier('Object') + ) + ), false ), - undefined, - [arkts.factory.create1StringLiteral(InteroperAbilityNames.OHMURL)] - ) + generateTSASExpression(arkts.factory.createIdentifier(InteroperAbilityNames.EXTRAINFO)) + ] ) - ] - ); - body.push(module); - const structObject = getPropertyESValue(InteroperAbilityNames.STRUCTOBJECT, moduleName, className); - body.push(structObject); - const component = instantiateComponent( - [ - arkts.factory.createIdentifier('esundefined'), - arkts.factory.createIdentifier(InteroperAbilityNames.PARAM), - arkts.factory.createIdentifier('esundefined'), - arkts.factory.createIdentifier(InteroperAbilityNames.ELMTID), - arkts.factory.createIdentifier('esblank'), - arkts.factory.createIdentifier(InteroperAbilityNames.EXTRAINFO) - ] + ) ); - body.push(component); - return body; } -function invokeViewPUCreate(): arkts.Statement[] { - const body: arkts.Statement[] = []; - const createMethod = getPropertyESValue('create', InteroperAbilityNames.STRUCTOBJECT, 'create'); - body.push(createMethod); - const viewPUCreate = arkts.factory.createExpressionStatement( +function createComponent(className: string): arkts.Statement[] { + const component = newComponent(className); + const ViewPU = getPropertyESValue('viewPUCreate', InteroperAbilityNames.GLOBAL, 'viewPUCreate'); + const create = arkts.factory.createExpressionStatement( arkts.factory.createCallExpression( arkts.factory.createMemberExpression( - arkts.factory.createIdentifier('create'), - arkts.factory.createIdentifier(ESValueMethodNames.INVOKE), + arkts.factory.createIdentifier('viewPUCreate'), + arkts.factory.createIdentifier('invoke'), arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, false, false @@ -336,12 +230,13 @@ function invokeViewPUCreate(): arkts.Statement[] { ] ) ); - body.push(viewPUCreate); - return body; + return [component, ViewPU, create]; } -function createWrapperBlock(context: InteropContext, varMap: Map, + +function createWrapperBlock(context: InteropContext, varMap: Map, updateProp: arkts.Property[]): arkts.BlockStatement { + const enableStateManagementInterop = false; const className: string = context.className; const path: string = context.path; const args: arkts.ObjectExpression | undefined = context.arguments; @@ -349,12 +244,10 @@ 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,35 +281,47 @@ function createInitializer(context: InteropContext, varMap: Map { + const key = prop.key as arkts.Identifier; + const value = prop.value; + const insertProperty = setPropertyESValue('updateParam', key.name, value!); + result.push(insertProperty); + }); + return result; +} + +function updateStateVars(updateProp: arkts.Property[]): arkts.Statement[] { + const insertProp = createUpdateProp(updateProp); + return [ + ...insertProp, + arkts.factory.createCallExpression( + arkts.factory.createMemberExpression( + arkts.factory.createIdentifier(InteroperAbilityNames.INSTANCE), + arkts.factory.createIdentifier(ESValueMethodNames.INVOKEMETHOD), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, + false, + false + ), + undefined, + [ + arkts.factory.createStringLiteral('updateStateVars'), + arkts.factory.createIdentifier('updateParam') + ] + ) + ]; } function createUpdater(updateProp: arkts.Property[]): arkts.ArrowFunctionExpression { - const updateState = updateStateVars(updateProp); + const updateState = (updateProp.length !== 0) ? updateStateVars(updateProp) : []; return arkts.factory.createArrowFunction( arkts.factory.createScriptFunction( arkts.factory.createBlock( [ - updateState + ...updateState ] ), arkts.factory.createFunctionSignature( @@ -451,23 +347,18 @@ function createUpdater(updateProp: arkts.Property[]): arkts.ArrowFunctionExpress ); } -function generateVarMap(node: arkts.Identifier): 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 +435,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/legacy-transformer.ts b/arkui-plugins/ui-plugins/interop/legacy-transformer.ts index 3d78ff48ec14da2cd300973b9c7d95a33d146881..14a7a4b95546750144f8b9cb8d0e5f2aa8bc40d8 100644 --- a/arkui-plugins/ui-plugins/interop/legacy-transformer.ts +++ b/arkui-plugins/ui-plugins/interop/legacy-transformer.ts @@ -20,9 +20,9 @@ import { getInteropPath } from '../../path'; const interop = require(getInteropPath()); const nullptr = interop.nullptr; import { AbstractVisitor, VisitorOptions } from '../../common/abstract-visitor'; -import { ESValueMethodNames, InteroperAbilityNames } from './predefines'; +import { InteroperAbilityNames } from './predefines'; import { getCustomComponentOptionsName } from '../utils'; -import { annotation } from 'common/arkts-utils'; +import { factory } from '../ui-factory'; interface LegacyTransformerOptions extends VisitorOptions { structList?: string[] @@ -169,44 +169,45 @@ export class LegacyTransformer extends AbstractVisitor { } processConstructor(node: arkts.MethodDefinition): arkts.MethodDefinition { - const esvalue = arkts.factory.createTypeReference( - arkts.factory.createTypeReferencePart( - arkts.factory.createIdentifier(ESValueMethodNames.ESVALUE) - ) - ); - const script = arkts.factory.createScriptFunction( - arkts.factory.createBlock([]), - arkts.factory.createFunctionSignature( - undefined, - [ - arkts.factory.createParameterDeclaration( - arkts.factory.createIdentifier(InteroperAbilityNames.PARENT, esvalue), - undefined, - ), - arkts.factory.createParameterDeclaration( - arkts.factory.createIdentifier(InteroperAbilityNames.PARAM, esvalue), - undefined, - ), - arkts.factory.createParameterDeclaration( - arkts.factory.createIdentifier('localStorage', esvalue), - undefined, - ), - arkts.factory.createParameterDeclaration( - arkts.factory.createIdentifier(InteroperAbilityNames.ELMTID, esvalue), - undefined, - ), - arkts.factory.createParameterDeclaration( - arkts.factory.createIdentifier(InteroperAbilityNames.PARAMSLAMBDA, esvalue), - undefined, - ), - arkts.factory.createParameterDeclaration( - arkts.factory.createIdentifier(InteroperAbilityNames.EXTRAINFO, esvalue), - undefined, - ) - ], undefined, false), - arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_CONSTRUCTOR, - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC, - ); + const valueType = arkts.factory.createUnionType([ + arkts.factory.createTypeReference( + arkts.factory.createTypeReferencePart( + arkts.factory.createIdentifier('Object') + ) + ), + arkts.factory.createETSUndefinedType() + ]); + const script = factory.createScriptFunction({ + body: arkts.factory.createBlock([]), + params: [ + arkts.factory.createParameterDeclaration( + arkts.factory.createIdentifier(InteroperAbilityNames.PARENT, valueType), + undefined, + ), + arkts.factory.createParameterDeclaration( + arkts.factory.createIdentifier(InteroperAbilityNames.PARAM, valueType), + undefined, + ), + arkts.factory.createParameterDeclaration( + arkts.factory.createIdentifier('localStorage', valueType), + undefined, + ), + arkts.factory.createParameterDeclaration( + arkts.factory.createIdentifier(InteroperAbilityNames.ELMTID, valueType), + undefined, + ), + arkts.factory.createParameterDeclaration( + arkts.factory.createIdentifier(InteroperAbilityNames.PARAMSLAMBDA, valueType), + undefined, + ), + arkts.factory.createParameterDeclaration( + arkts.factory.createIdentifier(InteroperAbilityNames.EXTRAINFO, valueType), + undefined, + ) + ], + flags: arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_CONSTRUCTOR, + modifiers: arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC, + }) return arkts.factory.updateMethodDefinition( node, node.kind, diff --git a/arkui-plugins/ui-plugins/interop/predefines.ts b/arkui-plugins/ui-plugins/interop/predefines.ts index c70c8e0177ae2e668e2254ad1a9a735971071e55..731dd1aac31cc6149e79831e77c476a193c3152e 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', @@ -32,9 +32,9 @@ export enum InteroperAbilityNames { PARAMSLAMBDA = 'paramsLambda', INTEROPCOMPONENT = 'interopComponent', OHMURL = '@normalized:N&entry&com.example.Interop2use1&har1/src/main/ets/components/MainPage&1.0.0', - CONFIGURESTATE = 'bindCompatibleState', - GETSOURCE = 'findBindingSourceState', - GETPROXY = 'getCompatibleState' + GETCOMPATIBLESTATE = 'getCompatibleState', + BINDPROVIDEINTEROP = 'bindCompatibleProvideCallback', + CREATESTATE = 'createStateVariable', } diff --git a/arkui-plugins/ui-plugins/interop/provide.ts b/arkui-plugins/ui-plugins/interop/provide.ts index 19732e624bb2257139483669cce356da77b294f1..cf06995fa6187bde6055bb8fc0bd743efce5c8f0 100644 --- a/arkui-plugins/ui-plugins/interop/provide.ts +++ b/arkui-plugins/ui-plugins/interop/provide.ts @@ -16,190 +16,61 @@ import * as arkts from '@koalaui/libarkts'; -import { getPropertyESValue } from './utils'; -import { createVariableLet, setStateProxy } from './initstatevar'; +import { getPropertyESValue, getWrapValue } from './utils'; import { ESValueMethodNames, InteroperAbilityNames, InteropProvideNames } from './predefines'; - -function findProvide(): arkts.Statement { - return createVariableLet( - InteropProvideNames.STATICPROVIDE, - arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - arkts.factory.createThisExpression(), - arkts.factory.createIdentifier(InteropProvideNames.FINDPROVIDE), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), - [ - arkts.factory.createTypeReference( - arkts.factory.createTypeReferencePart( - arkts.factory.createIdentifier('Object') - ) - ) - ], - [ - arkts.factory.createIdentifier(InteropProvideNames.PROVIDEDPROPNAME) - ] - ) - ); -} - -function setProvideProxy(): arkts.Statement[] { - return setStateProxy( - () => arkts.factory.createTSNonNullExpression( - arkts.factory.createIdentifier(InteropProvideNames.STATICPROVIDE) - ) - ); -} - -function getProvideProxy(): arkts.Statement { - return createVariableLet( - 'proxy', - arkts.factory.createCallExpression( - arkts.factory.createIdentifier(InteroperAbilityNames.GETPROXY), - undefined, - [ - arkts.factory.createTSNonNullExpression( - arkts.factory.createIdentifier(InteropProvideNames.STATICPROVIDE) - ) - ] - ) - ); -} - -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) - ) - ), - false - ), - arkts.factory.createIdentifier(ESValueMethodNames.UNWRAP), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), - undefined, - undefined - ) - ) - ); -} - -function createProvideBlock(): arkts.BlockStatement { - const provide = findProvide(); - const setProxy = setProvideProxy(); - const getProxy = getProvideProxy(); - const returnStatement = returnProvide(); - return arkts.factory.createBlock([provide, ...setProxy, getProxy, returnStatement]); -} - -function findProvideCallback(): arkts.Statement { - const block = createProvideBlock(); - const callback = createVariableLet( - InteropProvideNames.FINDPROVIDECALLBACK, - arkts.factory.createArrowFunction( - arkts.factory.createScriptFunction( - block, - arkts.factory.createFunctionSignature( - undefined, - [ - arkts.factory.createParameterDeclaration( - arkts.factory.createIdentifier(InteropProvideNames.PROVIDEDPROPNAME, - arkts.factory.createTypeReference( - arkts.factory.createTypeReferencePart( - arkts.factory.createIdentifier('string') - ) - ) - ), - undefined, - ), - ], - arkts.factory.createTypeReference( - arkts.factory.createTypeReferencePart( - arkts.factory.createIdentifier('Object') - ) - ), - false - ), - arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW, - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE, - ) - ) - ); - return callback; -} - export function createProvideInterop(): arkts.Statement[] { - const viewPUFunc = getPropertyESValue( - InteropProvideNames.SETVIEWPUFINDPROVIDE, - InteroperAbilityNames.GLOBAL, - InteropProvideNames.SETVIEWPUFINDPROVIDE - ); - const componentFunc = getPropertyESValue( + const createState = getPropertyESValue(InteroperAbilityNames.CREATESTATE, InteroperAbilityNames.GLOBAL, InteroperAbilityNames.CREATESTATE); + const setCallbackFunc = getPropertyESValue( InteropProvideNames.SETFINDPROVIDE, InteroperAbilityNames.GLOBAL, InteropProvideNames.SETFINDPROVIDE ); - const callback = findProvideCallback(); + const viewPUResetFunc = getPropertyESValue( + 'resetViewPUFindProvideInterop', + InteroperAbilityNames.GLOBAL, + 'resetViewPUFindProvideInterop' + ); const invokeFunc = arkts.factory.createExpressionStatement( arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - arkts.factory.createIdentifier(InteropProvideNames.SETVIEWPUFINDPROVIDE), - arkts.factory.createIdentifier(ESValueMethodNames.INVOKE), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), + arkts.factory.createIdentifier(InteroperAbilityNames.BINDPROVIDEINTEROP), undefined, [ - arkts.factory.createIdentifier(InteropProvideNames.FINDPROVIDECALLBACK) + arkts.factory.createThisExpression(), + arkts.factory.createIdentifier(InteroperAbilityNames.CREATESTATE), + getWrapValue(arkts.factory.createIdentifier(InteropProvideNames.SETFINDPROVIDE)) ] ) ); - return [viewPUFunc, componentFunc, callback, invokeFunc]; + return [createState, setCallbackFunc, viewPUResetFunc, invokeFunc]; } export function setAndResetFindProvide(): arkts.Statement[] { const setComponent = arkts.factory.createExpressionStatement( arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - arkts.factory.createIdentifier(InteropProvideNames.SETFINDPROVIDE), - arkts.factory.createIdentifier(ESValueMethodNames.INVOKE), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), + arkts.factory.createIdentifier(InteroperAbilityNames.BINDPROVIDEINTEROP), undefined, [ + arkts.factory.createThisExpression(), + arkts.factory.createIdentifier(InteroperAbilityNames.CREATESTATE), + arkts.factory.createIdentifier(InteropProvideNames.SETFINDPROVIDE), arkts.factory.createIdentifier(InteroperAbilityNames.COMPONENT), - arkts.factory.createIdentifier(InteropProvideNames.FINDPROVIDECALLBACK) ] ) ); + const resetViewPU = arkts.factory.createExpressionStatement( arkts.factory.createCallExpression( arkts.factory.createMemberExpression( - arkts.factory.createIdentifier(InteroperAbilityNames.STRUCTOBJECT), - arkts.factory.createIdentifier(ESValueMethodNames.INVOKEMETHOD), + arkts.factory.createIdentifier('resetViewPUFindProvideInterop'), + arkts.factory.createIdentifier(ESValueMethodNames.INVOKE), arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, false, false ), undefined, - [ - arkts.factory.createStringLiteral('resetFindInterop') - ] + undefined ) ); return [setComponent, resetViewPU]; diff --git a/arkui-plugins/ui-plugins/interop/utils.ts b/arkui-plugins/ui-plugins/interop/utils.ts index c26e4051be20f232a056136a455d4e3fa4240bc0..14574a264b19bbab41047aca2fc6ff5b3ff3daec 100644 --- a/arkui-plugins/ui-plugins/interop/utils.ts +++ b/arkui-plugins/ui-plugins/interop/utils.ts @@ -16,7 +16,7 @@ import * as arkts from '@koalaui/libarkts'; -import { ESValueMethodNames, InteroperAbilityNames } from './predefines'; +import { ESValueMethodNames } from './predefines'; /** @@ -126,54 +126,10 @@ export function getPropertyESValue(result: string, obj: string, key: string): ar /** * - * @param stateVar - * @param block - * @returns if (getCompatibleState(stateVar) === undefined) { block } - */ -export function ifStateHasProxy(stateVar: () => arkts.Expression, block: arkts.BlockStatement): arkts.Statement { - return arkts.factory.createIfStatement( - arkts.factory.createBinaryExpression( - arkts.factory.createCallExpression( - arkts.factory.createIdentifier(InteroperAbilityNames.GETPROXY), - undefined, - [ - stateVar() - ] - ), - arkts.factory.createUndefinedLiteral(), - arkts.Es2pandaTokenType.TOKEN_TYPE_PUNCTUATOR_STRICT_EQUAL - ), - block - ); -} - -/** - * 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. - * @returns {string} Proxied variable name in the format: "{stateVarName}_State_Proxy". + * @returns {string} Proxied variable name in the format: "__Proxy_{stateVarName}". */ export function stateProxy(stateVarName: string): string { - return `${stateVarName}_State_Proxy`; + return `__Proxy_${stateVarName}`; }