diff --git a/arkoala-arkts/libarkts/examples/input/main.sts b/arkoala-arkts/libarkts/examples/input/main.sts index f3610831a3cdfb0374f4d9f72ca7579292bd2818..699f7b36996f2dc34da71d881c9f91f420fca269 100644 --- a/arkoala-arkts/libarkts/examples/input/main.sts +++ b/arkoala-arkts/libarkts/examples/input/main.sts @@ -7,8 +7,8 @@ class StructBase {} @interface Component {} /* User code */ -interface __Options_MyComponent {} -interface __Options_AnotherComponent {} +// @interface __Options_MyComponent {} +// @interface __Options_AnotherComponent {} @Component class MyComponent { @@ -35,8 +35,3 @@ class AnotherComponent { .width(17.0) } } - -function main() {} - -main() - diff --git a/arkoala-arkts/libarkts/examples/src/component-transformer.ts b/arkoala-arkts/libarkts/examples/src/component-transformer.ts index bfcbbb0f1b8c897eb9b96a75fa6a3a9cb7f10d2e..40385f395c2187745831394a9d7d083b0477d695 100644 --- a/arkoala-arkts/libarkts/examples/src/component-transformer.ts +++ b/arkoala-arkts/libarkts/examples/src/component-transformer.ts @@ -16,38 +16,51 @@ import * as arkts from "@koalaui/libarkts" import { AbstractVisitor } from "./AbstractVisitor"; -// function getConstructor(node: arkts.ClassDeclaration): arkts.MethodDefinition | undefined { -// const definition = node.definition -// const members = definition.members -// members.forEach( -// (member) => { -// if (arkts.isMethodDefinition(member)) { -// const func = member.scriptFunction -// const annotations = arkts.getAnnotations(func) -// } -// } -// ) -// return undefined -// } +export class ComponentTransformer extends AbstractVisitor { + private context: { componentNames: string[] } = { componentNames: [] } -function isComponent(node: arkts.ClassDeclaration): boolean { - // const constructor = getConstructor(node) - return node.definition.name.name.endsWith("Component") -} + isComponent(node: arkts.ClassDeclaration): boolean { + // TODO: + // const annotations = arkts.getAnnotations(node.definition) -export class ComponentTransformer extends AbstractVisitor { - visitor(beforeChildren: arkts.Node): arkts.Node { - const node = this.visitEachChild(beforeChildren) + return node.definition.name.name.endsWith("Component") + } - if (!arkts.isClassDeclaration(node)) { - return node - } - if (!isComponent(node)) { - return node - } - const className = node.definition.name.name - const optionsName = `__Options_${node.definition.name.name}` - // return node + processEtsScript(node: arkts.EtsScript): arkts.EtsScript { + // const importDecl = arkts.factory.createImportDeclaration( + // arkts.factory.createStringLiteral('example/arkui/runtime'), + // [ + // arkts.factory.createImportSpecifier( + // arkts.factory.createIdentifier('StructBase'), + // arkts.nullptr + // ) + // ], + // arkts.Es2pandaImportKinds.TYPE, + // false + // ) + const interfaceDeclarations = this.context.componentNames.map( + name => arkts.factory.createInterfaceDeclaration( + [], + arkts.factory.createIdentifier(`__Options_${name}`), + arkts.nullptr, + arkts.factory.createBlock([]), + false, + false + ) + ) + return arkts.factory.updateEtsScript( + node, + [ + // importDecl, + ...interfaceDeclarations, + ...node.statements + ] + ) + } + + processComponent(node: arkts.ClassDeclaration): arkts.ClassDeclaration { + const className = node.definition.name.name + this.context.componentNames.push(className) return arkts.factory.updateClassDeclaration( node, arkts.factory.updateClassDefinition( @@ -68,7 +81,7 @@ export class ComponentTransformer extends AbstractVisitor { arkts.factory.createIdentifier(className) ), arkts.factory.createTypeReference( - arkts.factory.createIdentifier(optionsName) + arkts.factory.createIdentifier(`__Options_${className}`) ), ] ) @@ -77,4 +90,15 @@ export class ComponentTransformer extends AbstractVisitor { ) ) } + + visitor(node: arkts.Node): arkts.Node { + const newNode = this.visitEachChild(node) + if (arkts.isEtsScript(newNode)) { + return this.processEtsScript(newNode) + } + if (arkts.isClassDeclaration(newNode) && this.isComponent(newNode)) { + return this.processComponent(newNode) + } + return newNode + } } diff --git a/arkoala-arkts/libarkts/examples/src/example-checked-transformer.ts b/arkoala-arkts/libarkts/examples/src/example-checked-transformer.ts index 537091d791b4a9aa85a1586dc24ef9561eb187ec..ec0578ffde3afe67fb6a161e67b9d9e6a0123bfb 100644 --- a/arkoala-arkts/libarkts/examples/src/example-checked-transformer.ts +++ b/arkoala-arkts/libarkts/examples/src/example-checked-transformer.ts @@ -1,6 +1,7 @@ import * as ts from "@koalaui/libarkts" import { PrintVisitor } from './print-visitor' import { BuilderLambdaTransformer } from './builder-lambda-transformer' +import { ComponentTransformer } from './component-transformer' export interface TransformerOptions { trace?: boolean, diff --git a/arkoala-arkts/libarkts/native/src/bridges.cc b/arkoala-arkts/libarkts/native/src/bridges.cc index b260d71bd3d93c00e0bf66e216eae784659af4f6..2b994c0d7cfa38f29d4ba4c743cec731865d9a3d 100644 --- a/arkoala-arkts/libarkts/native/src/bridges.cc +++ b/arkoala-arkts/libarkts/native/src/bridges.cc @@ -1,5 +1,35 @@ #include "common.h" +KNativePointer impl_ClassDefinitionSuper(KNativePointer contextPtr, KNativePointer nodePtr) { + auto context = reinterpret_cast(contextPtr); + auto node = reinterpret_cast(nodePtr); + return GetImpl()->ClassDefinitionSuper(context, node); +} +KOALA_INTEROP_2(ClassDefinitionSuper, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_CreateTSInterfaceDeclaration( + KNativePointer _context, + KNativePointerArray _extends, + KInt _extendsLen, + KNativePointer _id, + KNativePointer _typeParams, + KNativePointer _body, + KBoolean _isStatic, + KBoolean _isExternal +) { + auto context = reinterpret_cast(_context); + auto extends = reinterpret_cast(_extends); + auto extendsLen = static_cast(_extendsLen); + auto id = reinterpret_cast(_id); + auto typeParams = reinterpret_cast(_typeParams); + auto body = reinterpret_cast(_body); + auto isStatic = static_cast(_isStatic); + auto isExternal = static_cast(_isExternal); + + return GetImpl()->CreateTSInterfaceDeclaration(context, extends, extendsLen, id, typeParams, body, isStatic, isExternal); +} +KOALA_INTEROP_8(CreateTSInterfaceDeclaration, KNativePointer, KNativePointer, KNativePointerArray, KInt, KNativePointer, KNativePointer, KNativePointer, KBoolean, KBoolean) + KNativePointer impl_CreateTSTypeParameterInstantiation( KNativePointer context, KNativePointerArray params, diff --git a/arkoala-arkts/libarkts/package.json b/arkoala-arkts/libarkts/package.json index 929bc727d47139210f04bc20a1e63391bb806698..76258d7299c6327a9f1e6e52e27e2125144de2ae 100644 --- a/arkoala-arkts/libarkts/package.json +++ b/arkoala-arkts/libarkts/package.json @@ -27,7 +27,6 @@ "test": "npm run compile:native && npm run mocha", "run:abc": "../../incremental/tools/panda/node_modules/@panda/sdk/linux_host_tools/bin/ark --load-runtimes=ets --boot-panda-files=../../incremental/tools/panda/node_modules/@panda/sdk/ets/etsstdlib.abc ./main.abc main.ETSGLOBAL::main", "compile:playground": "cd playground && meson setup build && meson compile -C build", - "run:playground": "npm run compile:playground && ./playground/build/playground.out", - "clean": "rimraf ./build && rimraf ./native/build && rimraf ./playground/build && rimraf ./compatible/build" + "run:playground": "npm run compile:playground && ./playground/build/playground.out" } } diff --git a/arkoala-arkts/libarkts/src/Es2pandaNativeModule.ts b/arkoala-arkts/libarkts/src/Es2pandaNativeModule.ts index 827529d80d236e9fa47728b9a9322ef82e85bab9..f81a62c5493194a7f1af24f37d195dcd860aeedf 100644 --- a/arkoala-arkts/libarkts/src/Es2pandaNativeModule.ts +++ b/arkoala-arkts/libarkts/src/Es2pandaNativeModule.ts @@ -27,6 +27,12 @@ import { export type KPtrArray = BigUint64Array export class Es2pandaNativeModule { + _ClassDefinitionSuper(context: KPtr, node: KPtr): KPtr { + throw new Error("Not implemented") + } + _CreateTSInterfaceDeclaration(_context: KPtr, _extends: KPtrArray, _extendsLen: KInt, _id: KPtr, _typeParams: KPtr, _body: KPtr, _isStatic: KBoolean, _isExternal: KBoolean): KPtr { + throw new Error("Not implemented") + } _CreateTSTypeParameterInstantiation(context: KPtr, params: KPtrArray, paramsLen: KInt): KPtr { throw new Error("Not implemented") } diff --git a/arkoala-arkts/libarkts/src/arkts-api/factory/nodeFactory.ts b/arkoala-arkts/libarkts/src/arkts-api/factory/nodeFactory.ts index 753b7040fd73004533752d71c525df028cdee86d..ecf51582fe3907ff9bb9a79b9449fb9a256fc5e2 100644 --- a/arkoala-arkts/libarkts/src/arkts-api/factory/nodeFactory.ts +++ b/arkoala-arkts/libarkts/src/arkts-api/factory/nodeFactory.ts @@ -136,4 +136,7 @@ export const factory = { createTSTypeParameterInstantiation: arkts.TSTypeParameterInstantiation.create, updateTSTypeParameterInstantiation: compose(arkts.TSTypeParameterInstantiation.create), + + createInterfaceDeclaration: arkts.TSInterfaceDeclaration.create, + updateInterfaceDeclaration: compose(arkts.TSInterfaceDeclaration.create), } diff --git a/arkoala-arkts/libarkts/src/arkts-api/factory/nodeTests.ts b/arkoala-arkts/libarkts/src/arkts-api/factory/nodeTests.ts index 64a29f26a50d0510e9e6db76fa6eb14b40b27703..20ec7c362a57a3c5663f112562299ef38e7866ef 100644 --- a/arkoala-arkts/libarkts/src/arkts-api/factory/nodeTests.ts +++ b/arkoala-arkts/libarkts/src/arkts-api/factory/nodeTests.ts @@ -18,6 +18,7 @@ import { VariableDeclaration, ScriptFunction, StringLiteral, + ClassDefinition, } from "../types" export function isIdentifier(node: Node): node is Identifier { @@ -80,6 +81,10 @@ export function isStringLiteral(node: Node): node is StringLiteral { return node instanceof StringLiteral } +export function isClassDefinition(node: Node): node is ClassDefinition { + return node instanceof ClassDefinition +} + // export function isVariableDeclarationList(node: Node): node is VariableDeclarationList { // return node.kind === SyntaxKind.VariableDeclarationList // } diff --git a/arkoala-arkts/libarkts/src/arkts-api/types.ts b/arkoala-arkts/libarkts/src/arkts-api/types.ts index 1fb50c7a2db3cfa3aeebe8e643843614ed22fd7a..55b816d6ad42716d7c33c9d3e05f120455066618 100644 --- a/arkoala-arkts/libarkts/src/arkts-api/types.ts +++ b/arkoala-arkts/libarkts/src/arkts-api/types.ts @@ -16,7 +16,7 @@ import global from "./static/global" import { throwError } from "../utils" -import { KInt, KNativePointer as KPtr, isNullPtr, nullptr } from "@koalaui/interop" +import { KBoolean, KInt, KNativePointer as KPtr, isNullPtr, nullptr } from "@koalaui/interop" import { Es2pandaPrimitiveType, Es2pandaModifierFlags, @@ -978,6 +978,7 @@ export class ClassDefinition extends Node { this.name = unpackNonNullableNode(global.es2panda._ClassDefinitionIdent(global.context, this.peer)) this.members = unpackNodeArray(global.es2panda._ClassDefinitionBody(global.context, this.peer)) this.typeParamsDecl = unpackNode(global.es2panda._ClassDefinitionTypeParamsConst(global.context, this.peer)) + this.superClass = unpackNode(global.es2panda._ClassDefinitionSuper(global.context, this.peer)) } static create( @@ -1006,6 +1007,7 @@ export class ClassDefinition extends Node { readonly name: Identifier readonly members: readonly Node[] readonly typeParamsDecl?: TSTypeParameterDeclaration + readonly superClass?: Node } export class ClassStaticBlock extends Node { @@ -1280,6 +1282,35 @@ export class TSTypeParameterInstantiation extends Node { } } +export class TSInterfaceDeclaration extends Node { + constructor(peer: KPtr) { + assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_TS_INTERFACE_DECLARATION) + super(peer) + } + + static create( + extendsParams: readonly Node[], + id: Node, + typeParams: Node, + body: Node, + isStatic: KBoolean, + isExternal: KBoolean, + ): TSInterfaceDeclaration { + return new TSInterfaceDeclaration( + global.es2panda._CreateTSInterfaceDeclaration( + global.context, + passNodeArray(extendsParams), + extendsParams.length, + passNode(id), + passNode(typeParams), + passNode(body), + isStatic, + isExternal, + ) + ) + } +} + export class UndefinedLiteral extends Node { constructor(peer: KPtr) { assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_UNDEFINED_LITERAL) diff --git a/arkoala-arkts/libarkts/src/arkts-api/utilities/public.ts b/arkoala-arkts/libarkts/src/arkts-api/utilities/public.ts index d12ab9d6294b98b790e6ffed90f6aaa391628210..9a0ae473155d090e832297aed3bd829c6e0f8f52 100644 --- a/arkoala-arkts/libarkts/src/arkts-api/utilities/public.ts +++ b/arkoala-arkts/libarkts/src/arkts-api/utilities/public.ts @@ -97,8 +97,8 @@ export function getDecl(node: arkts.Node): arkts.Node | undefined { } export function getAnnotations(node: arkts.Node): readonly arkts.AnnotationUsageIr[] { - if (!arkts.isFunctionDeclaration(node) && !arkts.isScriptFunction(node)) { - throwError('for now annotations allowed only for: functionDeclaration, scriptFuncion') + if (!arkts.isFunctionDeclaration(node) && !arkts.isScriptFunction(node) && !arkts.isClassDefinition(node)) { + throwError('for now annotations allowed only for: functionDeclaration, scriptFuncion, classDefinition') } return arkts.unpackNodeArray(global.es2panda._AnnotationAllowedAnnotations(global.context, node.peer, arkts.nullptr)) } diff --git a/arkoala-arkts/libarkts/src/arkts-api/visitor.ts b/arkoala-arkts/libarkts/src/arkts-api/visitor.ts index ebf8a5a4c0e5725555d33a16fcbf5513703f587a..bef26b172dbe5d79ed42490b236a499fdcb4ca8c 100644 --- a/arkoala-arkts/libarkts/src/arkts-api/visitor.ts +++ b/arkoala-arkts/libarkts/src/arkts-api/visitor.ts @@ -78,6 +78,7 @@ export function visitEachChild( // TODO: pass through modifiers Es2pandaClassDefinitionModifiers.CLASS_DEFINITION_MODIFIERS_NONE, nodeVisitor(node.typeParamsDecl, visitor), + nodeVisitor(node.superClass, visitor), ) } if (node instanceof arkts.MethodDefinition) { diff --git a/arkoala-arkts/libarkts/src/es2panda.ts b/arkoala-arkts/libarkts/src/es2panda.ts index cc758a0329d5a7468578b83ea6b557469bf15607..f6809f9728e04959a61cc2e6df3e1cbbcc37e3c1 100644 --- a/arkoala-arkts/libarkts/src/es2panda.ts +++ b/arkoala-arkts/libarkts/src/es2panda.ts @@ -30,9 +30,9 @@ function insertPlugin(state: arkts.Es2pandaContextState): arkts.Node { if (script === undefined) { throwError(`Failed to receive ast from es2panda`) } + console.log(`BEFORE ${stateName(state)}:`) console.log(script.dumpSrc()) - // console.log(script.dumpJson()) const transform = pluginsByState.get(state) transform?.(script) @@ -53,12 +53,25 @@ function invokePlugins(configPath: string, filePath: string ): void { ]) global.context = arkts.createContextFromString(global.config, source, filePath) - // const _ = insertPlugin(arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED) - const checked = insertPlugin(arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED) + // ComponentTransformer + const parsedTransform = insertPlugin(arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED) + const afterParsedSrc = parsedTransform.dumpSrc() + + global.es2panda._DestroyContext(global.context) + const afterParsedScript = arkts.EtsScript.create( + afterParsedSrc, + arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED + ) - // TODO: doesn't work - // global.es2panda._AstNodeRecheck(global.context, checked.originalPeer) - // arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_BIN_GENERATED) + // BuilderLambdaTransformer + const checkedTransform = insertPlugin(arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED) + const afterCheckedSrc = checkedTransform.dumpSrc() + + global.es2panda._DestroyContext(global.context) + const afterCheckedScript = arkts.EtsScript.create( + afterParsedSrc, + arkts.Es2pandaContextState.ES2PANDA_STATE_BIN_GENERATED + ) } function loadPlugin(configDir: string, jsonPlugin: any) {