diff --git a/arkui-plugins/common/predefines.ts b/arkui-plugins/common/predefines.ts index 8825a0df1ef28dab3f6114eb001eb82f7a23dda7..8013dec0dbf9540ad6e4bb21780e5a7ceda8087e 100644 --- a/arkui-plugins/common/predefines.ts +++ b/arkui-plugins/common/predefines.ts @@ -79,6 +79,8 @@ export enum DecoratorIntrinsicNames { export enum StateManagementTypes { STATE_MANAGEMENT_FACTORY = 'STATE_MGMT_FACTORY', + UI_UTILS = 'UIUtils', + MAKE_OBSERVED = 'makeObserved', STATE_DECORATED = 'IStateDecoratedVariable', LINK_DECORATED = 'ILinkDecoratedVariable', LINK_SOURCE_TYPE = 'LinkSourceType', @@ -130,14 +132,63 @@ export const INTERMEDIATE_IMPORT_SOURCE: Map = new Map = new Map = new Map = new Map export enum GetSetTypes { GET = 'get', SET = 'set', -} \ No newline at end of file +} diff --git a/arkui-plugins/ui-plugins/property-translators/consume.ts b/arkui-plugins/ui-plugins/property-translators/consume.ts index 8bd40ec2e46c89602fc559259a56fe61a7ea69ef..2091a6fdb6e67868c4d003a96b0ff8ad7da2f03f 100644 --- a/arkui-plugins/ui-plugins/property-translators/consume.ts +++ b/arkui-plugins/ui-plugins/property-translators/consume.ts @@ -22,7 +22,6 @@ import { createGetter, createSetter2, generateThisBacking, - generateGetOrSetCall, getValueInAnnotation, hasDecorator, PropertyCache, @@ -56,9 +55,9 @@ export class ConsumeTranslator extends PropertyTranslator implements Initializer arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PRIVATE ); const thisValue: arkts.Expression = generateThisBacking(newName, false, true); - const thisGet: arkts.CallExpression = generateGetOrSetCall(thisValue, GetSetTypes.GET); + const thisGet: arkts.CallExpression = factory.generateGetOrSetCall(thisValue, GetSetTypes.GET); const thisSet: arkts.ExpressionStatement = arkts.factory.createExpressionStatement( - generateGetOrSetCall(thisValue, GetSetTypes.SET) + factory.generateGetOrSetCall(thisValue, GetSetTypes.SET) ); const getter: arkts.MethodDefinition = this.translateGetter( originalName, diff --git a/arkui-plugins/ui-plugins/property-translators/factory.ts b/arkui-plugins/ui-plugins/property-translators/factory.ts index f7704736399995e23dbd5acf19d7247e5d2c753d..b06a3940df22283e2c986cf27ba337a3a79c6ad8 100644 --- a/arkui-plugins/ui-plugins/property-translators/factory.ts +++ b/arkui-plugins/ui-plugins/property-translators/factory.ts @@ -15,7 +15,7 @@ import * as arkts from '@koalaui/libarkts'; import { GenSymGenerator } from '../../common/gensym-generator'; -import { DecoratorNames, DECORATOR_TYPE_MAP, StateManagementTypes } from '../../common/predefines'; +import { DecoratorNames, DECORATOR_TYPE_MAP, StateManagementTypes, GetSetTypes } from '../../common/predefines'; import { factory as UIFactory } from '../ui-factory'; import { collectStateManagementTypeImport, getValueInAnnotation, hasDecorator, removeDecorator } from './utils'; import { addMemoAnnotation, findCanAddMemoFromTypeAnnotation, CustomComponentNames } from '../utils'; @@ -121,8 +121,8 @@ export class factory { static createNonNullOrOptionalMemberExpression( object: string, property: string, - optional: boolean, - nonNull: boolean + optional: boolean = false, + nonNull: boolean = false ): arkts.Expression { const objectNode: arkts.Identifier = arkts.factory.createIdentifier(object); return arkts.factory.createMemberExpression( @@ -777,4 +777,50 @@ export class factory { } return property; } + + /** + * Wrap the UIUtils.makeObserved call for ``; + * + * @param initValue expecting property with decorator annotation. + * @param typeAnnotation type for initValue. + */ + static wrapMakeObservedCall( + initValue: arkts.AstNode, + typeAnnotation: arkts.TypeNode | undefined + ): arkts.CallExpression { + collectStateManagementTypeImport(StateManagementTypes.UI_UTILS); + return arkts.factory.createCallExpression( + this.createNonNullOrOptionalMemberExpression( + StateManagementTypes.UI_UTILS, + StateManagementTypes.MAKE_OBSERVED + ), + typeAnnotation ? [typeAnnotation] : undefined, + [initValue], + false, + false + ); + } + + static generateGetOrSetCall( + beforCall: arkts.AstNode, + type: GetSetTypes, + isMakeObserved: boolean = false, + typeAnnotation: arkts.TypeNode | undefined = undefined + ): arkts.CallExpression { + const valueIdent: arkts.Identifier = arkts.factory.createIdentifier('value'); + return arkts.factory.createCallExpression( + arkts.factory.createMemberExpression( + beforCall, + arkts.factory.createIdentifier(type), + arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, + false, + false + ), + undefined, + type === GetSetTypes.SET + ? [isMakeObserved ? this.wrapMakeObservedCall(valueIdent, typeAnnotation) : valueIdent] + : undefined, + undefined + ); + } } diff --git a/arkui-plugins/ui-plugins/property-translators/link.ts b/arkui-plugins/ui-plugins/property-translators/link.ts index 65217d539ea207a9cd60a0503eeea15a59d8a442..cbdf663b897638f748f7ac3d527dd9248e5cea24 100644 --- a/arkui-plugins/ui-plugins/property-translators/link.ts +++ b/arkui-plugins/ui-plugins/property-translators/link.ts @@ -23,7 +23,6 @@ import { createGetter, createSetter2, generateThisBacking, - generateGetOrSetCall, collectStateManagementTypeImport, hasDecorator, PropertyCache, @@ -96,9 +95,9 @@ export class LinkTranslator extends PropertyTranslator implements InitializerCon arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PRIVATE ); const thisValue: arkts.Expression = generateThisBacking(newName, false, true); - const thisGet: arkts.CallExpression = generateGetOrSetCall(thisValue, GetSetTypes.GET); + const thisGet: arkts.CallExpression = factory.generateGetOrSetCall(thisValue, GetSetTypes.GET); const thisSet: arkts.ExpressionStatement = arkts.factory.createExpressionStatement( - generateGetOrSetCall(thisValue, GetSetTypes.SET) + factory.generateGetOrSetCall(thisValue, GetSetTypes.SET) ); const getter: arkts.MethodDefinition = this.translateGetter( originalName, diff --git a/arkui-plugins/ui-plugins/property-translators/objectlink.ts b/arkui-plugins/ui-plugins/property-translators/objectlink.ts index 2c20897942a8e8ca46dac257d574c1bb5c438f45..80b7778d4dd8d014ae70d8bfa34a1ae1b201fcc5 100644 --- a/arkui-plugins/ui-plugins/property-translators/objectlink.ts +++ b/arkui-plugins/ui-plugins/property-translators/objectlink.ts @@ -18,14 +18,7 @@ import * as arkts from '@koalaui/libarkts'; import { backingField, expectName } from '../../common/arkts-utils'; import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { CustomComponentNames } from '../utils'; -import { - createGetter, - generateGetOrSetCall, - generateThisBacking, - generateToRecord, - hasDecorator, - PropertyCache, -} from './utils'; +import { createGetter, generateThisBacking, generateToRecord, hasDecorator, PropertyCache } from './utils'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; @@ -60,7 +53,10 @@ export class ObjectLinkTranslator extends PropertyTranslator implements Initiali originalName ) ); - const args: arkts.Expression[] = [arkts.factory.create1StringLiteral(originalName), initializers]; + const args: arkts.Expression[] = [ + arkts.factory.create1StringLiteral(originalName), + factory.wrapMakeObservedCall(initializers, this.property.typeAnnotation), + ]; factory.judgeIfAddWatchFunc(args, this.property); return arkts.factory.createAssignmentExpression( @@ -102,7 +98,7 @@ export class ObjectLinkTranslator extends PropertyTranslator implements Initiali arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PRIVATE ); const thisValue: arkts.Expression = generateThisBacking(newName, false, true); - const thisGet: arkts.CallExpression = generateGetOrSetCall(thisValue, GetSetTypes.GET); + const thisGet: arkts.CallExpression = factory.generateGetOrSetCall(thisValue, GetSetTypes.GET); const getter: arkts.MethodDefinition = this.translateGetter( originalName, this.property.typeAnnotation, diff --git a/arkui-plugins/ui-plugins/property-translators/prop.ts b/arkui-plugins/ui-plugins/property-translators/prop.ts index df2bce7938f7871c223864bbb2700b93a031e9aa..5f2c1dc407a7671c9b760916f73b4f6be80ebce1 100644 --- a/arkui-plugins/ui-plugins/property-translators/prop.ts +++ b/arkui-plugins/ui-plugins/property-translators/prop.ts @@ -22,7 +22,6 @@ import { generateToRecord, createGetter, createSetter2, - generateGetOrSetCall, generateThisBacking, collectStateManagementTypeImport, hasDecorator, @@ -61,9 +60,9 @@ export class PropTranslator extends PropertyTranslator implements InitializerCon arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PRIVATE ); const thisValue: arkts.Expression = generateThisBacking(newName, false, true); - const thisGet: arkts.CallExpression = generateGetOrSetCall(thisValue, GetSetTypes.GET); + const thisGet: arkts.CallExpression = factory.generateGetOrSetCall(thisValue, GetSetTypes.GET); const thisSet: arkts.ExpressionStatement = arkts.factory.createExpressionStatement( - generateGetOrSetCall(thisValue, GetSetTypes.SET) + factory.generateGetOrSetCall(thisValue, GetSetTypes.SET, true, this.property.typeAnnotation) ); const getter: arkts.MethodDefinition = this.translateGetter( originalName, @@ -106,18 +105,21 @@ export class PropTranslator extends PropertyTranslator implements InitializerCon ); const args: arkts.Expression[] = [ arkts.factory.create1StringLiteral(originalName), - this.property.value - ? binaryItem - : arkts.factory.createTSAsExpression( - factory.createNonNullOrOptionalMemberExpression( - CustomComponentNames.COMPONENT_INITIALIZERS_NAME, - originalName, - false, - true + factory.wrapMakeObservedCall( + this.property.value + ? binaryItem + : arkts.factory.createTSAsExpression( + factory.createNonNullOrOptionalMemberExpression( + CustomComponentNames.COMPONENT_INITIALIZERS_NAME, + originalName, + false, + true + ), + this.property.typeAnnotation ? this.property.typeAnnotation.clone() : undefined, + false ), - this.property.typeAnnotation ? this.property.typeAnnotation.clone() : undefined, - false - ), + this.property.typeAnnotation + ), ]; factory.judgeIfAddWatchFunc(args, this.property); collectStateManagementTypeImport(StateManagementTypes.PROP_DECORATED); diff --git a/arkui-plugins/ui-plugins/property-translators/provide.ts b/arkui-plugins/ui-plugins/property-translators/provide.ts index c1141a5ac63d1e5bf00c2f0c417c50da74482cfd..1b1a3e61f96b3b805b1a32794e49cc15d273bd0b 100644 --- a/arkui-plugins/ui-plugins/property-translators/provide.ts +++ b/arkui-plugins/ui-plugins/property-translators/provide.ts @@ -23,7 +23,6 @@ import { generateToRecord, createSetter2, generateThisBacking, - generateGetOrSetCall, getValueInProvideAnnotation, ProvideOptions, hasDecorator, @@ -58,9 +57,9 @@ export class ProvideTranslator extends PropertyTranslator implements Initializer arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PRIVATE ); const thisValue: arkts.Expression = generateThisBacking(newName, false, true); - const thisGet: arkts.CallExpression = generateGetOrSetCall(thisValue, GetSetTypes.GET); + const thisGet: arkts.CallExpression = factory.generateGetOrSetCall(thisValue, GetSetTypes.GET); const thisSet: arkts.ExpressionStatement = arkts.factory.createExpressionStatement( - generateGetOrSetCall(thisValue, GetSetTypes.SET) + factory.generateGetOrSetCall(thisValue, GetSetTypes.SET, true, this.property.typeAnnotation) ); const getter: arkts.MethodDefinition = this.translateGetter( originalName, @@ -99,13 +98,16 @@ export class ProvideTranslator extends PropertyTranslator implements Initializer const args: arkts.Expression[] = [ arkts.factory.create1StringLiteral(originalName), arkts.factory.create1StringLiteral(alias), - arkts.factory.createBinaryExpression( - factory.createBlockStatementForOptionalExpression( - arkts.factory.createIdentifier(CustomComponentNames.COMPONENT_INITIALIZERS_NAME), - originalName + factory.wrapMakeObservedCall( + arkts.factory.createBinaryExpression( + factory.createBlockStatementForOptionalExpression( + arkts.factory.createIdentifier(CustomComponentNames.COMPONENT_INITIALIZERS_NAME), + originalName + ), + this.property.value ?? arkts.factory.createUndefinedLiteral(), + arkts.Es2pandaTokenType.TOKEN_TYPE_PUNCTUATOR_NULLISH_COALESCING ), - this.property.value ?? arkts.factory.createUndefinedLiteral(), - arkts.Es2pandaTokenType.TOKEN_TYPE_PUNCTUATOR_NULLISH_COALESCING + this.property.typeAnnotation ), arkts.factory.createBooleanLiteral(allowOverride), ]; diff --git a/arkui-plugins/ui-plugins/property-translators/state.ts b/arkui-plugins/ui-plugins/property-translators/state.ts index 704a56f711b3614520ceaa4cf517a9d069d44290..a774ee62af527512a930b99b0b6b1ab5583e52fd 100644 --- a/arkui-plugins/ui-plugins/property-translators/state.ts +++ b/arkui-plugins/ui-plugins/property-translators/state.ts @@ -23,7 +23,6 @@ import { createGetter, createSetter2, generateThisBacking, - generateGetOrSetCall, hasDecorator, collectStateManagementTypeImport, PropertyCache, @@ -57,9 +56,9 @@ export class StateTranslator extends PropertyTranslator implements InitializerCo arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PRIVATE ); const thisValue: arkts.Expression = generateThisBacking(newName, false, true); - const thisGet: arkts.CallExpression = generateGetOrSetCall(thisValue, GetSetTypes.GET); + const thisGet: arkts.CallExpression = factory.generateGetOrSetCall(thisValue, GetSetTypes.GET); const thisSet: arkts.ExpressionStatement = arkts.factory.createExpressionStatement( - generateGetOrSetCall(thisValue, GetSetTypes.SET) + factory.generateGetOrSetCall(thisValue, GetSetTypes.SET, true, this.property.typeAnnotation) ); const getter: arkts.MethodDefinition = this.translateGetter( originalName, @@ -100,7 +99,10 @@ export class StateTranslator extends PropertyTranslator implements InitializerCo this.property.value ?? arkts.factory.createUndefinedLiteral(), arkts.Es2pandaTokenType.TOKEN_TYPE_PUNCTUATOR_NULLISH_COALESCING ); - const args: arkts.Expression[] = [arkts.factory.create1StringLiteral(originalName), binaryItem]; + const args: arkts.Expression[] = [ + arkts.factory.create1StringLiteral(originalName), + factory.wrapMakeObservedCall(binaryItem, this.property.typeAnnotation), + ]; factory.judgeIfAddWatchFunc(args, this.property); collectStateManagementTypeImport(StateManagementTypes.STATE_DECORATED); const assign: arkts.AssignmentExpression = arkts.factory.createAssignmentExpression( diff --git a/arkui-plugins/ui-plugins/property-translators/storageProp.ts b/arkui-plugins/ui-plugins/property-translators/storageProp.ts index ecec9362b047ad0e779b5010d1612fbd12fcf165..6513dc2aeeaf7f988c51f7c1cf9408bd56e0cfd6 100644 --- a/arkui-plugins/ui-plugins/property-translators/storageProp.ts +++ b/arkui-plugins/ui-plugins/property-translators/storageProp.ts @@ -24,7 +24,6 @@ import { createGetter, createSetter2, generateThisBacking, - generateGetOrSetCall, collectStateManagementTypeImport, hasDecorator, PropertyCache, @@ -87,7 +86,10 @@ export class StoragePropTranslator extends PropertyTranslator implements Initial const args: arkts.Expression[] = [ arkts.factory.createStringLiteral(storagePropValueStr), arkts.factory.create1StringLiteral(originalName), - this.property.value ?? arkts.factory.createUndefinedLiteral(), + factory.wrapMakeObservedCall( + this.property.value ?? arkts.factory.createUndefinedLiteral(), + this.property.typeAnnotation + ), ]; factory.judgeIfAddWatchFunc(args, this.property); collectStateManagementTypeImport(StateManagementTypes.STORAGE_PROP_DECORATED); @@ -112,9 +114,9 @@ export class StoragePropTranslator extends PropertyTranslator implements Initial arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PRIVATE ); const thisValue: arkts.Expression = generateThisBacking(newName, false, true); - const thisGet: arkts.CallExpression = generateGetOrSetCall(thisValue, GetSetTypes.GET); + const thisGet: arkts.CallExpression = factory.generateGetOrSetCall(thisValue, GetSetTypes.GET); const thisSet: arkts.ExpressionStatement = arkts.factory.createExpressionStatement( - generateGetOrSetCall(thisValue, GetSetTypes.SET) + factory.generateGetOrSetCall(thisValue, GetSetTypes.SET, true, this.property.typeAnnotation) ); const getter: arkts.MethodDefinition = this.translateGetter( originalName, diff --git a/arkui-plugins/ui-plugins/property-translators/storagelink.ts b/arkui-plugins/ui-plugins/property-translators/storagelink.ts index 8e3256a90b80d8550fcaef2e114aefdd2d730146..ea238b6235fe286a355d53503ee7fcdee2ebdd6e 100644 --- a/arkui-plugins/ui-plugins/property-translators/storagelink.ts +++ b/arkui-plugins/ui-plugins/property-translators/storagelink.ts @@ -24,7 +24,6 @@ import { createGetter, createSetter2, generateThisBacking, - generateGetOrSetCall, collectStateManagementTypeImport, hasDecorator, PropertyCache, @@ -87,7 +86,10 @@ export class StorageLinkTranslator extends PropertyTranslator implements Initial const args: arkts.Expression[] = [ arkts.factory.createStringLiteral(storageLinkValueStr), arkts.factory.create1StringLiteral(originalName), - this.property.value ?? arkts.factory.createUndefinedLiteral(), + factory.wrapMakeObservedCall( + this.property.value ?? arkts.factory.createUndefinedLiteral(), + this.property.typeAnnotation + ), ]; factory.judgeIfAddWatchFunc(args, this.property); collectStateManagementTypeImport(StateManagementTypes.STORAGE_LINK_DECORATED); @@ -111,9 +113,9 @@ export class StorageLinkTranslator extends PropertyTranslator implements Initial arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PRIVATE ); const thisValue: arkts.Expression = generateThisBacking(newName, false, true); - const thisGet: arkts.CallExpression = generateGetOrSetCall(thisValue, GetSetTypes.GET); + const thisGet: arkts.CallExpression = factory.generateGetOrSetCall(thisValue, GetSetTypes.GET); const thisSet: arkts.ExpressionStatement = arkts.factory.createExpressionStatement( - generateGetOrSetCall(thisValue, GetSetTypes.SET) + factory.generateGetOrSetCall(thisValue, GetSetTypes.SET, true, this.property.typeAnnotation) ); const getter: arkts.MethodDefinition = this.translateGetter( originalName, diff --git a/arkui-plugins/ui-plugins/property-translators/utils.ts b/arkui-plugins/ui-plugins/property-translators/utils.ts index 2a750395a60900508b7a02a32890b5bf923031f5..652b9a2249d8d26026631058ceefd4c5798914a4 100644 --- a/arkui-plugins/ui-plugins/property-translators/utils.ts +++ b/arkui-plugins/ui-plugins/property-translators/utils.ts @@ -23,7 +23,7 @@ import { DecoratorNames, DECORATOR_TYPE_MAP, StateManagementTypes, - GetSetTypes + GetSetTypes, } from '../../common/predefines'; import { addMemoAnnotation, findCanAddMemoFromParamExpression, findCanAddMemoFromTypeAnnotation } from '../utils'; @@ -360,21 +360,6 @@ function getDifferentAnnoTypeValue(value: arkts.Expression): string | boolean { return value.dumpSrc(); } -export function generateGetOrSetCall(beforCall: arkts.AstNode, type: GetSetTypes) { - return arkts.factory.createCallExpression( - arkts.factory.createMemberExpression( - beforCall, - arkts.factory.createIdentifier(type), - arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, - false, - false - ), - undefined, - type === 'set' ? [arkts.factory.createIdentifier('value')] : undefined, - undefined - ); -} - export function generateToRecord(newName: string, originalName: string): arkts.Property { return arkts.Property.createProperty( arkts.factory.createStringLiteral(originalName),