diff --git a/arkoala-arkts/arkui/src/handwritten/index.ts b/arkoala-arkts/arkui/src/handwritten/index.ts index bbf766e8fe7f7611134a9b56eeb19f10e08ece87..9b1107584ceccea8cbd033e5e918c6d37eac69b9 100644 --- a/arkoala-arkts/arkui/src/handwritten/index.ts +++ b/arkoala-arkts/arkui/src/handwritten/index.ts @@ -2,6 +2,7 @@ export * from "./ArkPageTransition" export * from "./ArkPageTransitionData" export * from "./Router" export * from "./ForeignFunctions" +export * from "./resources" // TODO: implement this diff --git a/arkoala-arkts/arkui/src/handwritten/resources.ts b/arkoala-arkts/arkui/src/handwritten/resources.ts new file mode 100644 index 0000000000000000000000000000000000000000..44c16b051866f69debd04f7263dbadbf8624ad72 --- /dev/null +++ b/arkoala-arkts/arkui/src/handwritten/resources.ts @@ -0,0 +1,40 @@ +import { Resource } from "../generated"; + +export function _r(bundleName: string, moduleName: string, name: string): Resource { + const param: string = name.split(".")[1]; + let res_type = 20000; + + switch (param) { + case 'media': + res_type = 20000; + break; + case 'color': + res_type = 10001; + break; + case 'string': + res_type = 10003; + break; + case 'float': + res_type = 10002; + break; + } + + + return { + "id": -1, + "type": res_type, + "params": new Array(name), + "bundleName": bundleName, + "moduleName": moduleName + } as Resource +} + +export function _rawfile(bundleName: string, moduleName: string, name: string): Resource { + return { + "id": 0, + "type": 30000, + "params": new Array(name), + "bundleName": bundleName, + "moduleName": moduleName + } as Resource +} \ No newline at end of file diff --git a/arkoala-arkts/shopping/application/entry/src/main/resources/base/element/color.json b/arkoala-arkts/shopping/application/entry/src/main/resources/base/element/color.json index 3c712962da3c2751c2b9ddb53559afcbd2b54a02..6a20c650b149de9ea82d6ff44adc2cdf496056d0 100644 --- a/arkoala-arkts/shopping/application/entry/src/main/resources/base/element/color.json +++ b/arkoala-arkts/shopping/application/entry/src/main/resources/base/element/color.json @@ -3,6 +3,10 @@ { "name": "start_window_background", "value": "#FFFFFF" + }, + { + "name": "my_color", + "value": "#2e2e33" } ] } \ No newline at end of file diff --git a/arkoala-arkts/shopping/application/entry/src/main/resources/base/element/string.json b/arkoala-arkts/shopping/application/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..d1c869602797ec927e55d7c7ca6e4633d8430acb 100644 --- a/arkoala-arkts/shopping/application/entry/src/main/resources/base/element/string.json +++ b/arkoala-arkts/shopping/application/entry/src/main/resources/base/element/string.json @@ -11,6 +11,10 @@ { "name": "EntryAbility_label", "value": "label" + }, + { + "name": "my_text", + "value": "some_text" } ] } \ No newline at end of file diff --git a/arkoala-arkts/trivial/trivial/entry/src/main/resources/rawfile/phone.png b/arkoala-arkts/trivial/trivial/entry/src/main/resources/rawfile/phone.png new file mode 100644 index 0000000000000000000000000000000000000000..75f9a36d17ae87c9fbb5cc6673a7420488016d11 Binary files /dev/null and b/arkoala-arkts/trivial/trivial/entry/src/main/resources/rawfile/phone.png differ diff --git a/arkoala-arkts/trivial/user/src/ets/etsconfig.json b/arkoala-arkts/trivial/user/src/ets/etsconfig.json index 8c8b162b4fe9b32f34daace4a8dabeb90c280fba..d8b2ae0458473c3a64ddbe4adf2d715cb26d8846 100644 --- a/arkoala-arkts/trivial/user/src/ets/etsconfig.json +++ b/arkoala-arkts/trivial/user/src/ets/etsconfig.json @@ -14,7 +14,11 @@ { "transform": "@koalaui/ets-plugin/build/lib/src/ArkExpander.js", "destination": "../../build/generated", - "arkui": "@koalaui/arkts-arkui" + "arkui": "@koalaui/arkts-arkui", + "applicationInfo": { + "bundleName": "com.example.trivial.application", + "moduleName": "entry" + } } ] } diff --git a/arkoala-arkts/trivial/user/src/ets/page1.ets b/arkoala-arkts/trivial/user/src/ets/page1.ets index c85a9eb52578e6232c9f13636112699742e4993a..7d28ff27e9c15233acdcbf6ef9b52f28f24ffd12 100644 --- a/arkoala-arkts/trivial/user/src/ets/page1.ets +++ b/arkoala-arkts/trivial/user/src/ets/page1.ets @@ -107,13 +107,16 @@ struct Page1 { .backgroundColor(this.color2) .width(200).height(100) .onClick((e?: ClickEvent) => { this.swap() }) + Text($r('app.string.my_text')).height(50) Button("Click! " + this.state) .width(200).height(100) + .backgroundColor($r('app.color.my_color')) .onClick((e?: ClickEvent) => { this.state++ console.log("#### Set Button onClick! #" + this.state) }) - Image("/resources/glass.png").width(400) + Image($r('app.media.startIcon')).width(60).height(60) + Image($rawfile('phone.png')).width(400) Text("Set Button onClick! #" + this.state) .width(200).height(100) TestProvide() diff --git a/arkoala/ets-plugin/src/ArkExpander.ts b/arkoala/ets-plugin/src/ArkExpander.ts index d45369d721e31f2b954534309098dbbfb1d4f92e..c5cdf8d6e8a975e3730a119321170ae3b4f4ecb2 100644 --- a/arkoala/ets-plugin/src/ArkExpander.ts +++ b/arkoala/ets-plugin/src/ArkExpander.ts @@ -25,7 +25,7 @@ import { CallTable, IssueTable, NameTable } from './utils' import { LazyTransformer } from './LazyTransformer' import { EntryTracker } from './EntryTracker' import { filterOutDiagnostics } from './DiagnosticFilter' -import { DollarTransformer } from './DollarTransformer' +import { DollarTransformer, ApplicationInfo } from './DollarTransformer' import { ExtensionStylesTransformer } from './ExtensionStylesTransformer' import { NewTransformer } from './NewTransformer' import { CustomBuilderTransformer } from './CustomBuilderTransformer' @@ -40,7 +40,8 @@ interface ArkToKoOptions { source?: string destination?: string arkui?: string - moduleInfo?: (moduleName: string) => any + moduleInfo?: (moduleName: string) => any, + applicationInfo?: ApplicationInfo } function printSourceFile(sourceFile: ts.Node, source?: string, destination?: string, extension?: string) { @@ -106,7 +107,8 @@ export function arkExpandFile( ctx: ts.TransformationContext, extras: ts.TransformerExtras | undefined, entryTracker: EntryTracker, - moduleInfo?: (moduleName: string) => any + moduleInfo?: (moduleName: string) => any, + applicationInfo?: ApplicationInfo ): ts.SourceFile { const importer = new Importer(arkuiPackage, moduleInfo) const nameTable = new NameTable() @@ -132,7 +134,7 @@ export function arkExpandFile( const styleTransformer = new StyleTransformer(sourceFile, ctx, typeChecker, importer, extensionStylesTransformer, callTable) const structTransformer = new StructTransformer(sourceFile, ctx, typeChecker, importer, nameTable, entryTracker, callTable, extras) const nameCollector = new NameCollector(sourceFile, ctx, nameTable, issueTable) - const dollarTransformer = new DollarTransformer(sourceFile, ctx, nameTable) + const dollarTransformer = new DollarTransformer(sourceFile, ctx, nameTable, importer, applicationInfo) const abilityTransformer = new AbilityTransformer(sourceFile, ctx, importer) const observedResolver = new ObservedResolver(sourceFile, ctx, importer) @@ -177,7 +179,8 @@ export default function arkExpander(program: ts.Program, userPluginOptions: ArkT source: userPluginOptions.source ?? ".", destination: userPluginOptions.destination ?? "../generated", arkui: userPluginOptions.arkui ?? "@koalaui/koala-arkui", - moduleInfo: userPluginOptions.moduleInfo + moduleInfo: userPluginOptions.moduleInfo, + applicationInfo: userPluginOptions.applicationInfo } const typeChecker = program.getTypeChecker() prepareDestination(pluginOptions.destination) @@ -194,7 +197,7 @@ export default function arkExpander(program: ts.Program, userPluginOptions: ArkT console.log("ETS->TS: " + path.normalize(sourceFile.fileName)) } - let final = arkExpandFile(sourceFile, pluginOptions.arkui, typeChecker, ctx, extras, entryTracker, pluginOptions.moduleInfo) + let final = arkExpandFile(sourceFile, pluginOptions.arkui, typeChecker, ctx, extras, entryTracker, pluginOptions.moduleInfo, pluginOptions.applicationInfo) printSourceFile(final, pluginOptions.source, pluginOptions.destination) if (pluginOptions.arkui != "@koalaui/arkts-arkui") { diff --git a/arkoala/ets-plugin/src/DollarTransformer.ts b/arkoala/ets-plugin/src/DollarTransformer.ts index caac6830f671108fa7611fdd0c3ac129ea539d6b..12a3dfe998a43deec035f78008c520a102133f9c 100644 --- a/arkoala/ets-plugin/src/DollarTransformer.ts +++ b/arkoala/ets-plugin/src/DollarTransformer.ts @@ -16,13 +16,21 @@ import * as ts from "@koalaui/ets-tsc" import { AbstractVisitor } from "./AbstractVisitor"; import { NameTable } from "./utils"; +import { Importer } from "./Importer"; +export interface ApplicationInfo { + bundleName: string, + moduleName: string +} + export class DollarTransformer extends AbstractVisitor { constructor( sourceFile: ts.SourceFile, ctx: ts.TransformationContext, - private nameTable: NameTable + private nameTable: NameTable, + private importer: Importer, + private applicationInfo?: ApplicationInfo ) { super(sourceFile, ctx) } @@ -58,7 +66,37 @@ export class DollarTransformer extends AbstractVisitor { ) } + isDollarCallExpression(node: ts.CallExpression): boolean { + return !this.whiteList.includes(ts.idText(node.expression as ts.Identifier)) ? false : true + } + + transformDollarCallExpression(node: ts.CallExpression): ts.CallExpression { + const name = ts.idText(node.expression as ts.Identifier).replace('$', '_') + + const args = node.arguments.slice() + + args.unshift( + ts.factory.createStringLiteral(this.applicationInfo?.bundleName ?? ""), + ts.factory.createStringLiteral(this.applicationInfo?.moduleName ?? "entry") + ) + + return ts.factory.updateCallExpression( + node, + ts.factory.createIdentifier(this.importer.withAdaptorImport(name)), + node.typeArguments, + args + ) + + } + visitor(node: ts.Node): ts.Node { + + if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) { + if (this.isDollarCallExpression(node)) { + return this.transformDollarCallExpression(node) + } + } + if (ts.isStruct(node)) { this.currentStruct = node const transformed = this.visitEachChild(node) diff --git a/arkoala/ets-plugin/test/ets/dollar-functions/dollar-functions.ets b/arkoala/ets-plugin/test/ets/dollar-functions/dollar-functions.ets new file mode 100644 index 0000000000000000000000000000000000000000..6a0f053fd238975d82ac482912b981e3623901bf --- /dev/null +++ b/arkoala/ets-plugin/test/ets/dollar-functions/dollar-functions.ets @@ -0,0 +1,15 @@ +@Entry +@Component +struct Index { + @State myState2: string = "Hello" + + build() { + Column() { + Image($rawfile('startIcon.png')) + Image($r('app.media.icon')) + Text($myState2) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/arkoala/ets-plugin/test/ets/tsconfig.arkoala.json b/arkoala/ets-plugin/test/ets/tsconfig.arkoala.json index fc43e265829b54013c53c17ccb61ce85017bf1e1..1df10a8750239500399ced2e577759e3298263df 100644 --- a/arkoala/ets-plugin/test/ets/tsconfig.arkoala.json +++ b/arkoala/ets-plugin/test/ets/tsconfig.arkoala.json @@ -19,6 +19,10 @@ "transform": "@koalaui/ets-plugin/build/lib/src/ArkExpander.js", "arkui": "@koalaui/arkoala-arkui", "destination": "../../build/ts/arkoala/ets", + "applicationInfo": { + "bundleName": "com.application.example", + "moduleName": "entry" + } } ] } diff --git a/arkoala/ets-plugin/test/ets/tsconfig.arkts.json b/arkoala/ets-plugin/test/ets/tsconfig.arkts.json index 5d6536e20dac33c1a58cb634a06c7092158788b1..7bc3115321cad6ddc364b4536367329f152edbd7 100644 --- a/arkoala/ets-plugin/test/ets/tsconfig.arkts.json +++ b/arkoala/ets-plugin/test/ets/tsconfig.arkts.json @@ -19,6 +19,10 @@ "transform": "@koalaui/ets-plugin/build/lib/src/ArkExpander.js", "arkui": "@koalaui/arkts-arkui", "destination": "../../build/ts/arkts/ets", + "applicationInfo": { + "bundleName": "com.application.example", + "moduleName": "entry" + } } ] } diff --git a/arkoala/ets-plugin/test/golden/arkoala/ets/__router_initialization.ts b/arkoala/ets-plugin/test/golden/arkoala/ets/__router_initialization.ts index 2d336d76962f25e975a3ebef06beb71ad10a3c8b..acedfbdd34f252a618f4e43a5939809cc4d476e1 100644 --- a/arkoala/ets-plugin/test/golden/arkoala/ets/__router_initialization.ts +++ b/arkoala/ets-plugin/test/golden/arkoala/ets/__router_initialization.ts @@ -2,9 +2,11 @@ import { EntryExample as Entry0 } from "./Rewrite" import { LocalStorageLinkExample as Entry1 } from "./Rewrite2" import { LocalStoragePropExample as Entry2 } from "./Rewrite3" +import { Index as Entry3 } from "./dollar-functions/dollar-functions" export function registerRoutes() { const __forceEntry0Use = Entry0 const __forceEntry1Use = Entry1 const __forceEntry2Use = Entry2 + const __forceEntry3Use = Entry3 } diff --git a/arkoala/ets-plugin/test/golden/arkoala/ets/dollar-functions/dollar-functions.ts b/arkoala/ets-plugin/test/golden/arkoala/ets/dollar-functions/dollar-functions.ts new file mode 100644 index 0000000000000000000000000000000000000000..efc95491b1f03ac8d17d1a3a955ab714440cf757 --- /dev/null +++ b/arkoala/ets-plugin/test/golden/arkoala/ets/dollar-functions/dollar-functions.ts @@ -0,0 +1,52 @@ +import { ArkColumn, ArkColumnComponent, ArkCommonMethodComponent, ArkImage, ArkPageTransitionEnterComponent, ArkPageTransitionExitComponent, ArkStructBase, ArkText, LocalStorage, MutableState, _r, _rawfile, observableProxy, stateOf } from "@koalaui/arkoala-arkui"; +import { registerArkuiEntry } from "@koalaui/arkoala-arkui/ohos.router"; +class ArkIndexComponent extends ArkStructBase { + private _entry_local_storage_ = new LocalStorage(); + __initializeStruct(/**/ + /** @memo */ + content?: () => void, initializers?: IndexOptions): void { + this.__backing_myState2 = stateOf(initializers?.myState2 ?? ("Hello"), this); + } + private __backing_myState2?: MutableState; + private get myState2(): string { + return this.__backing_myState2!.value; + } + private set myState2(value: string) { + this.__backing_myState2!.value = observableProxy(value); + } + /** @memo */ + __build(/**/ + /** @memo */ + __builder: ((__instance: ArkCommonMethodComponent) => void) | undefined, /**/ + /** @memo */ + content?: () => void, initializers?: IndexOptions) { + ArkColumn(__instance => { + { + __instance.height('100%') + .width('100%'); + } + __builder?.(__instance); + }, () => { + ArkImage(undefined, undefined, _rawfile("com.application.example", "entry", 'startIcon.png')); + ArkImage(undefined, undefined, _r("com.application.example", "entry", 'app.media.icon')); + ArkText(undefined, undefined, this.$myState2); + }); + } +} +/** @memo */ +export function Index(/**/ +/** @memo */ +style?: (__instance: ArkCommonMethodComponent) => void, /**/ +/** @memo */ +content?: () => void, initializers?: IndexOptions): void { + const updatedInitializers: IndexOptions = { + __backing_myState2: initializers?.__backing_myState2 + }; + ArkIndexComponent._instantiate(style, () => new ArkIndexComponent, content, updatedInitializers); +} +export interface IndexOptions { + __backing_myState2?: MutableState; + myState2?: string; +} +registerArkuiEntry(Index, "dollar-functions/dollar-functions"); +export const __Entry = Index; diff --git a/arkoala/ets-plugin/test/golden/arkts/ets/dollar-functions/dollar-functions.ts b/arkoala/ets-plugin/test/golden/arkts/ets/dollar-functions/dollar-functions.ts new file mode 100644 index 0000000000000000000000000000000000000000..0d250826a8d0cabd245679f764b6f4655f93b7f8 --- /dev/null +++ b/arkoala/ets-plugin/test/golden/arkts/ets/dollar-functions/dollar-functions.ts @@ -0,0 +1,52 @@ +import { ArkColumn, ArkColumnComponent, ArkCommonMethodComponent, ArkImage, ArkPageTransitionEnterComponent, ArkPageTransitionExitComponent, ArkStructBase, ArkText, _r, _rawfile, stateOf } from "@koalaui/arkts-arkui"; +import { MutableState } from "@koalaui/runtime"; +import { LocalStorage } from "@koalaui/arkui-common"; +import { observableProxy } from "@koalaui/common"; +class ArkIndexComponent extends ArkStructBase { + private _entry_local_storage_ = new LocalStorage(); + __initializeStruct(/**/ + /** @memo */ + content?: () => void, initializers?: IndexOptions): void { + this.__backing_myState2 = stateOf(initializers?.myState2 ?? ("Hello"), this); + } + private __backing_myState2?: MutableState; + private get myState2(): string { + return this.__backing_myState2!.value; + } + private set myState2(value: string) { + this.__backing_myState2!.value = observableProxy(value); + } + /** @memo */ + __build(/**/ + /** @memo */ + __builder: ((__instance: ArkCommonMethodComponent) => void) | undefined, /**/ + /** @memo */ + content?: () => void, initializers?: IndexOptions) { + ArkColumn(__instance => { + { + __instance.height('100%') + .width('100%'); + } + __builder?.(__instance); + }, () => { + ArkImage(undefined, undefined, _rawfile("com.application.example", "entry", 'startIcon.png')); + ArkImage(undefined, undefined, _r("com.application.example", "entry", 'app.media.icon')); + ArkText(undefined, undefined, this.$myState2); + }); + } +} +/** @memo */ +export function Index(/**/ +/** @memo */ +style?: (__instance: ArkCommonMethodComponent) => void, /**/ +/** @memo */ +content?: () => void, initializers?: IndexOptions): void { + const updatedInitializers: IndexOptions = { + __backing_myState2: initializers?.__backing_myState2 + }; + ArkIndexComponent._instantiate(style, () => new ArkIndexComponent, content, updatedInitializers); +} +export interface IndexOptions { + __backing_myState2?: MutableState; + myState2?: string; +} diff --git a/arkoala/ets-plugin/test/golden/koala/ets/__router_initialization.ts b/arkoala/ets-plugin/test/golden/koala/ets/__router_initialization.ts index 2d336d76962f25e975a3ebef06beb71ad10a3c8b..acedfbdd34f252a618f4e43a5939809cc4d476e1 100644 --- a/arkoala/ets-plugin/test/golden/koala/ets/__router_initialization.ts +++ b/arkoala/ets-plugin/test/golden/koala/ets/__router_initialization.ts @@ -2,9 +2,11 @@ import { EntryExample as Entry0 } from "./Rewrite" import { LocalStorageLinkExample as Entry1 } from "./Rewrite2" import { LocalStoragePropExample as Entry2 } from "./Rewrite3" +import { Index as Entry3 } from "./dollar-functions/dollar-functions" export function registerRoutes() { const __forceEntry0Use = Entry0 const __forceEntry1Use = Entry1 const __forceEntry2Use = Entry2 + const __forceEntry3Use = Entry3 } diff --git a/arkoala/ets-plugin/test/golden/koala/ets/dollar-functions/dollar-functions.ts b/arkoala/ets-plugin/test/golden/koala/ets/dollar-functions/dollar-functions.ts new file mode 100644 index 0000000000000000000000000000000000000000..a526694989ac785348e3b79104bce810fa485244 --- /dev/null +++ b/arkoala/ets-plugin/test/golden/koala/ets/dollar-functions/dollar-functions.ts @@ -0,0 +1,54 @@ +import { $r, $rawfile, AppStorage, ArkColumn, ArkColumnComponent, ArkCommonMethodComponent, ArkImage, ArkPageTransitionEnterComponent, ArkPageTransitionExitComponent, ArkStructBase, ArkText, CanvasRenderingContext2D, CustomDialogController, DataChangeListener, Environment, ForEach, GestureGroup, IDataSource, LocalStorage, LongPressGesture, PanGesture, PanGestureOptions, PersistentStorage, PinchGesture, RenderingContextSettings, RotationGesture, Scroller, SubscribedAbstractProperty, SwipeGesture, SwiperController, TabsController, TapGesture, TextAreaController, VideoController, _r, _rawfile, animateTo, fp2px, getContext, getInspectorByKey, lpx2px, px2fp, px2lpx, px2vp, stateOf, vp2px } from "@koalaui/arkui"; +import { MutableState } from "@koalaui/runtime"; +import { registerArkuiEntry } from "@koalaui/arkui/ohos.router"; +import { observableProxy } from "@koalaui/common"; +class ArkIndexComponent extends ArkStructBase { + private _entry_local_storage_ = new LocalStorage(); + __initializeStruct(/**/ + /** @memo */ + content?: () => void, initializers?: IndexOptions): void { + this.__backing_myState2 = stateOf(initializers?.myState2 ?? ("Hello"), this); + } + private __backing_myState2?: MutableState; + private get myState2(): string { + return this.__backing_myState2!.value; + } + private set myState2(value: string) { + this.__backing_myState2!.value = observableProxy(value); + } + /** @memo */ + __build(/**/ + /** @memo */ + __builder: ((__instance: ArkCommonMethodComponent) => void) | undefined, /**/ + /** @memo */ + content?: () => void, initializers?: IndexOptions) { + ArkColumn(__instance => { + { + __instance.height('100%') + .width('100%'); + } + __builder?.(__instance); + }, () => { + ArkImage(undefined, undefined, _rawfile("", "entry", 'startIcon.png')); + ArkImage(undefined, undefined, _r("", "entry", 'app.media.icon')); + ArkText(undefined, undefined, this.$myState2); + }); + } +} +/** @memo */ +export function Index(/**/ +/** @memo */ +style?: (__instance: ArkCommonMethodComponent) => void, /**/ +/** @memo */ +content?: () => void, initializers?: IndexOptions): void { + const updatedInitializers: IndexOptions = { + __backing_myState2: initializers?.__backing_myState2 + }; + ArkIndexComponent._instantiate(style, () => new ArkIndexComponent, content, updatedInitializers); +} +export interface IndexOptions { + __backing_myState2?: MutableState; + myState2?: string; +} +registerArkuiEntry(Index, "dollar-functions/dollar-functions"); +export const __Entry = Index; diff --git a/arkoala/ets-plugin/test/utils.ts b/arkoala/ets-plugin/test/utils.ts index b22af78f93f613580f56380e6ba336e31718734b..a4da1e0c137414064bbd61dcab5e93e7fff2a4e4 100644 --- a/arkoala/ets-plugin/test/utils.ts +++ b/arkoala/ets-plugin/test/utils.ts @@ -22,7 +22,7 @@ export function testFolder(folder: string) { suite(folder, () => { const golden = "./test/golden/" + folder const current = "./build/ts/" + folder - const files = collectFiles(path.resolve(golden)) + const files = collectFiles(path.resolve(current)) console.log(files) files.forEach(file => { test(file, () => {