From fda00d5f4b92d2ed3a050a43e6b2e9a3eead5acc Mon Sep 17 00:00:00 2001 From: Cuecuexiaoyu Date: Tue, 8 Jul 2025 19:36:31 +0800 Subject: [PATCH 1/2] Encapsulate range api Signed-off-by: Cuecuexiaoyu Change-Id: I52c66120704ab78edbc1f47f5fa12979ebaa6dce --- koala-wrapper/native/src/bridges.cc | 10 ++++++++++ koala-wrapper/src/Es2pandaNativeModule.ts | 4 ++++ koala-wrapper/src/arkts-api/peers/AstNode.ts | 9 +++++++++ 3 files changed, 23 insertions(+) diff --git a/koala-wrapper/native/src/bridges.cc b/koala-wrapper/native/src/bridges.cc index 3cc1282ac..300bdf311 100644 --- a/koala-wrapper/native/src/bridges.cc +++ b/koala-wrapper/native/src/bridges.cc @@ -521,6 +521,16 @@ KNativePointer impl_AstNodeRangeConst(KNativePointer context, KNativePointer nod } KOALA_INTEROP_2(AstNodeRangeConst, KNativePointer, KNativePointer, KNativePointer) +void impl_AstNodeSetRange(KNativePointer context, KNativePointer receiver, KNativePointer range) +{ + const auto _context = reinterpret_cast(context); + const auto _receiver = reinterpret_cast(receiver); + const auto _range = reinterpret_cast(range); + GetImpl()->AstNodeSetRange(_context, _receiver, _range); + return; +} +KOALA_INTEROP_V3(AstNodeSetRange, KNativePointer, KNativePointer, KNativePointer); + KNativePointer impl_SourceRangeStart(KNativePointer context, KNativePointer range) { const auto _context = reinterpret_cast(context); diff --git a/koala-wrapper/src/Es2pandaNativeModule.ts b/koala-wrapper/src/Es2pandaNativeModule.ts index 1fcdcdd4f..e9237bd17 100644 --- a/koala-wrapper/src/Es2pandaNativeModule.ts +++ b/koala-wrapper/src/Es2pandaNativeModule.ts @@ -875,6 +875,10 @@ export class Es2pandaNativeModule { throw new Error('CreateFunctionDecl was not overloaded by native module initialization'); } + _AstNodeSetRange(context: KNativePointer, node: KNativePointer, range: KNativePointer): KNativePointer { + throw new Error('Not implemented'); + } + _SourceRangeStart(context: KNativePointer, range: KNativePointer): KNativePointer { throw new Error('CreateFunctionDecl was not overloaded by native module initialization'); } diff --git a/koala-wrapper/src/arkts-api/peers/AstNode.ts b/koala-wrapper/src/arkts-api/peers/AstNode.ts index 2a8b90fa6..892591783 100644 --- a/koala-wrapper/src/arkts-api/peers/AstNode.ts +++ b/koala-wrapper/src/arkts-api/peers/AstNode.ts @@ -21,6 +21,7 @@ import { Es2pandaModifierFlags } from '../../generated/Es2pandaEnums'; import { ArktsObject } from './ArktsObject'; import { Es2pandaAstNodeType } from '../../Es2pandaEnums'; import { SourcePosition } from './SourcePosition'; +import { SourceRange } from './SourceRange'; export abstract class AstNode extends ArktsObject { protected constructor(peer: KNativePointer) { @@ -153,6 +154,14 @@ export abstract class AstNode extends ArktsObject { public set endPosition(end: SourcePosition) { global.es2panda._AstNodeSetEnd(global.context, this.peer, end.peer); } + + public get range(): SourceRange { + return new SourceRange(global.es2panda._AstNodeRangeConst(global.context, this.peer)); + } + + public set range(range: SourceRange) { + global.es2panda._AstNodeSetRange(global.context, this.peer, range.peer); + } } export class UnsupportedNode extends AstNode { -- Gitee From 793c3100c71fc7ba050647b8b3c7dd2a8ebec4a1 Mon Sep 17 00:00:00 2001 From: Cuecuexiaoyu Date: Tue, 8 Jul 2025 19:37:24 +0800 Subject: [PATCH 2/2] set source range for updated nodes Signed-off-by: Cuecuexiaoyu Change-Id: I453a103d630757c5257b4689633cd09f8ef3510d --- .../builder-lambda-translators/factory.ts | 1 + .../ui-plugins/component-transformer.ts | 26 ++++++++++++++----- .../ui-plugins/entry-translators/factory.ts | 3 ++- .../ui-plugins/property-translators/link.ts | 1 + .../ui-plugins/property-translators/prop.ts | 2 ++ .../ui-plugins/property-translators/state.ts | 1 + .../ui-plugins/struct-translators/factory.ts | 10 +++++-- 7 files changed, 34 insertions(+), 10 deletions(-) diff --git a/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts b/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts index 4aede6309..dbf8f0ce3 100644 --- a/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts +++ b/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts @@ -604,6 +604,7 @@ export class factory { const args: (arkts.AstNode | undefined)[] = this.generateArgsInBuilderLambda(leaf, lambdaBody!, declInfo); const newNode = arkts.factory.updateCallExpression(node, replace, leaf.typeArguments, filterDefined(args)); arkts.NodeCache.getInstance().collect(newNode); + newNode.range = node.range; return newNode; } diff --git a/arkui-plugins/ui-plugins/component-transformer.ts b/arkui-plugins/ui-plugins/component-transformer.ts index 8d9c5aaf4..621f447b9 100644 --- a/arkui-plugins/ui-plugins/component-transformer.ts +++ b/arkui-plugins/ui-plugins/component-transformer.ts @@ -69,10 +69,15 @@ export interface InteropContext { arguments?: arkts.ObjectExpression; } +interface EntryConfig { + entryName: string; + entryRange: arkts.SourceRange; +} + export class ComponentTransformer extends AbstractVisitor { private scopeInfos: ScopeInfo[] = []; private componentInterfaceCollection: arkts.TSInterfaceDeclaration[] = []; - private entryNames: string[] = []; + private entryConfigs: EntryConfig[] = []; private structMembersMap: Map = new Map(); private isCustomComponentImported: boolean = false; private isCustomComponentV2Imported: boolean = false; @@ -97,7 +102,7 @@ export class ComponentTransformer extends AbstractVisitor { super.reset(); this.scopeInfos = []; this.componentInterfaceCollection = []; - this.entryNames = []; + this.entryConfigs = []; this.structMembersMap = new Map(); this.isCustomComponentImported = false; this.isCustomComponentV2Imported = false; @@ -221,7 +226,7 @@ export class ComponentTransformer extends AbstractVisitor { navInterface.modifiers = arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_EXPORT; return arkts.factory.updateEtsScript(node, [...node.statements, navInterface]); } - if (this.isExternal && this.componentInterfaceCollection.length === 0 && this.entryNames.length === 0) { + if (this.isExternal && this.componentInterfaceCollection.length === 0 && this.entryConfigs.length === 0) { return node; } const updateStatements: arkts.AstNode[] = []; @@ -245,13 +250,19 @@ export class ComponentTransformer extends AbstractVisitor { updateStatements.push(...this.componentInterfaceCollection); } - if (this.entryNames.length > 0) { + if (this.entryConfigs.length > 0) { if (!this.isEntryPointImported) entryFactory.createAndInsertEntryPointImport(this.program); // normally, we should only have at most one @Entry component in a single file. // probably need to handle error message here. - if (!this.isPageLifeCycleImported) + if (!this.isPageLifeCycleImported) { this.createImportDeclaration(CUSTOM_COMPONENT_IMPORT_SOURCE_NAME, CustomComponentNames.PAGE_LIFE_CYCLE); - updateStatements.push(...this.entryNames.map(entryFactory.generateEntryWrapper)); + } + updateStatements.push( + ...this.entryConfigs.map(({ entryName, entryRange }) => { + const entryWrapper = entryFactory.generateEntryWrapper(entryName, entryRange); + return entryWrapper; + }) + ); updateStatements.push( entryFactory.callRegisterNamedRouter( this.entryRouteName, @@ -342,7 +353,7 @@ export class ComponentTransformer extends AbstractVisitor { const definition: arkts.ClassDefinition = node.definition!; const newDefinitionBody: arkts.AstNode[] = []; if (!!scopeInfo.annotations?.entry) { - this.entryNames.push(className); + this.entryConfigs.push({ entryName: className, entryRange: scopeInfo.annotations.entry.range }); const { storage, useSharedStorage, routeName } = getEntryParams(definition); entryFactory.transformStorageParams(storage, useSharedStorage, definition); if (routeName && routeName.value && arkts.isStringLiteral(routeName.value)) { @@ -367,6 +378,7 @@ export class ComponentTransformer extends AbstractVisitor { _node.modifiers = node.modifiers; _node.startPosition = node.startPosition; _node.endPosition = node.endPosition; + _node.range = node.range; return _node; } else { return arkts.factory.updateClassDeclaration(node, newDefinition); diff --git a/arkui-plugins/ui-plugins/entry-translators/factory.ts b/arkui-plugins/ui-plugins/entry-translators/factory.ts index e4dd29d22..46091b9e8 100644 --- a/arkui-plugins/ui-plugins/entry-translators/factory.ts +++ b/arkui-plugins/ui-plugins/entry-translators/factory.ts @@ -181,7 +181,7 @@ export class factory { * * @param name class/struct name that has `@Entry` annotation. */ - static generateEntryWrapper(name: string): arkts.ClassDeclaration { + static generateEntryWrapper(name: string, entryAnnotationRange: arkts.SourceRange): arkts.ClassDeclaration { const ctor = factory.generateConstructor(); const definition: arkts.ClassDefinition = arkts.factory .createClassDefinition( @@ -202,6 +202,7 @@ export class factory { arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE ) .setCtor(ctor as any); + definition.range = entryAnnotationRange; const newClass = arkts.factory.createClassDeclaration(definition); newClass.modifiers = arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE; return newClass; diff --git a/arkui-plugins/ui-plugins/property-translators/link.ts b/arkui-plugins/ui-plugins/property-translators/link.ts index 65217d539..8245b54e6 100644 --- a/arkui-plugins/ui-plugins/property-translators/link.ts +++ b/arkui-plugins/ui-plugins/property-translators/link.ts @@ -43,6 +43,7 @@ export class LinkTranslator extends PropertyTranslator implements InitializerCon cacheTranslatedInitializer(newName: string, originalName: string): void { const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); + initializeStruct.range = this.property.range; PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); if (!!this.structInfo.annotations?.reusable) { const toRecord = generateToRecord(newName, originalName); diff --git a/arkui-plugins/ui-plugins/property-translators/prop.ts b/arkui-plugins/ui-plugins/property-translators/prop.ts index df2bce793..aa9bfec7c 100644 --- a/arkui-plugins/ui-plugins/property-translators/prop.ts +++ b/arkui-plugins/ui-plugins/property-translators/prop.ts @@ -44,8 +44,10 @@ export class PropTranslator extends PropertyTranslator implements InitializerCon cacheTranslatedInitializer(newName: string, originalName: string): void { const mutableThis: arkts.Expression = generateThisBacking(newName); const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); + initializeStruct.range = this.property.range; PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); const updateStruct: arkts.AstNode = this.generateUpdateStruct(mutableThis, originalName); + updateStruct.range = this.property.range; PropertyCache.getInstance().collectUpdateStruct(this.structInfo.name, [updateStruct]); if (!!this.structInfo.annotations?.reusable) { const toRecord = generateToRecord(newName, originalName); diff --git a/arkui-plugins/ui-plugins/property-translators/state.ts b/arkui-plugins/ui-plugins/property-translators/state.ts index 704a56f71..adf442942 100644 --- a/arkui-plugins/ui-plugins/property-translators/state.ts +++ b/arkui-plugins/ui-plugins/property-translators/state.ts @@ -42,6 +42,7 @@ export class StateTranslator extends PropertyTranslator implements InitializerCo cacheTranslatedInitializer(newName: string, originalName: string): void { const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); + initializeStruct.range = this.property.range; PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); if (!!this.structInfo.annotations?.reusable) { const toRecord = generateToRecord(newName, originalName); diff --git a/arkui-plugins/ui-plugins/struct-translators/factory.ts b/arkui-plugins/ui-plugins/struct-translators/factory.ts index 5901243d4..29dafba3c 100644 --- a/arkui-plugins/ui-plugins/struct-translators/factory.ts +++ b/arkui-plugins/ui-plugins/struct-translators/factory.ts @@ -375,6 +375,7 @@ export class factory { * transform property members in custom-component class. */ static tranformPropertyMembers( + classIdent: arkts.Identifier, propertyTranslators: PropertyTranslator[], optionsTypeName: string, scope: CustomComponentScopeInfo @@ -382,10 +383,14 @@ export class factory { const propertyMembers = propertyTranslators.map((translator) => translator.translateMember()); const collections = []; if (!scope.hasInitializeStruct) { - collections.push(this.createInitializeStruct(optionsTypeName, scope)); + const initializeStruct: arkts.MethodDefinition = this.createInitializeStruct(optionsTypeName, scope); + initializeStruct.range = classIdent.range; + collections.push(initializeStruct); } if (!scope.hasUpdateStruct) { - collections.push(this.createUpdateStruct(optionsTypeName, scope)); + const updateStruct: arkts.MethodDefinition = this.createUpdateStruct(optionsTypeName, scope); + updateStruct.range = classIdent.range; + collections.push(updateStruct); } if (!!scope.annotations?.reusable) { collections.push(this.createToRecord(optionsTypeName, scope)); @@ -432,6 +437,7 @@ export class factory { definition.body.map((it) => classifyProperty(it, scope)) ); const translatedMembers: arkts.AstNode[] = this.tranformPropertyMembers( + node.definition.ident!, propertyTranslators, classOptionsName ?? getCustomComponentOptionsName(className), scope -- Gitee