diff --git a/compiler/src/pre_define.ts b/compiler/src/pre_define.ts index 3aa289c44d7c8ee7e2fc91735a385d9ef59196e6..f76c968671b5038af9f0fd54fd0d4762f703013e 100644 --- a/compiler/src/pre_define.ts +++ b/compiler/src/pre_define.ts @@ -73,6 +73,7 @@ export const COMPONENT_EXTEND_DECORATOR: string = '@Extend'; export const COMPONENT_STYLES_DECORATOR: string = '@Styles'; export const COMPONENT_ANIMATABLE_EXTEND_DECORATOR: string = '@AnimatableExtend'; export const COMPONENT_CONCURRENT_DECORATOR: string = '@Concurrent'; +export const COMPONENT_SENDABLE_DECORATOR: string = '@Sendable'; export const CHECK_COMPONENT_EXTEND_DECORATOR: string = 'Extend'; export const STRUCT_CONTEXT_METHOD_DECORATORS: Set = new Set([COMPONENT_BUILDER_DECORATOR, COMPONENT_STYLES_DECORATOR]); diff --git a/compiler/src/process_ui_syntax.ts b/compiler/src/process_ui_syntax.ts index 51b1c2c3d67967e65b9ae05b006f8b4cc3ff9f85..26bb32ca7c37b17c3251efbf42c4a07e27cae54f 100644 --- a/compiler/src/process_ui_syntax.ts +++ b/compiler/src/process_ui_syntax.ts @@ -26,6 +26,7 @@ import { BUILD_ON, COMPONENT_BUILDER_DECORATOR, COMPONENT_CONCURRENT_DECORATOR, + COMPONENT_SENDABLE_DECORATOR, COMPONENT_EXTEND_DECORATOR, COMPONENT_STYLES_DECORATOR, RESOURCE, @@ -332,6 +333,10 @@ export function processUISyntax(program: ts.Program, ut = false, parentEvent?: a pos: node.getStart() }); } + } else if (ts.isClassDeclaration(node)) { + if (hasDecorator(node, COMPONENT_SENDABLE_DECORATOR)) { + node = processClassSendable(node); + } } return ts.visitEachChild(node, processAllNodes, context); } @@ -861,6 +866,56 @@ function processConcurrent(node: ts.FunctionDeclaration): ts.FunctionDeclaration return node; } +function processClassSendable(node: ts.ClassDeclaration): ts.ClassDeclaration { + let hasConstructor = false; + let updatedMembers: ts.NodeArray = node.members; + let updatedModifiers: ts.NodeArray = node.modifiers; + + updatedModifiers = ts.factory.createNodeArray( + updatedModifiers.filter(decorator => { + const originalDecortor: string = decorator.getText().replace(/\(.*\)$/, '').trim(); + return originalDecortor !== COMPONENT_SENDABLE_DECORATOR; + }) + ); + + for (const member of node.members) { + if (ts.isConstructorDeclaration(member)) { + hasConstructor = true; + const constructor: ts.ConstructorDeclaration = member as ts.ConstructorDeclaration; + + const statementArray: ts.Statement[] = [ + ts.factory.createExpressionStatement(ts.factory.createStringLiteral('use sendable')), + ...constructor.body.statements + ]; + + const updatedConstructor: ts.ConstructorDeclaration = ts.factory.updateConstructorDeclaration(constructor, constructor.modifiers, + constructor.parameters, ts.factory.updateBlock(constructor.body, statementArray)); + + updatedMembers = ts.factory.createNodeArray( + updatedMembers.map(member => (member === constructor ? updatedConstructor : member)) + ); + break; + } + } + + if (!hasConstructor) { + const constructor: ts.ConstructorDeclaration = ts.factory.createConstructorDeclaration( + undefined, + [], + ts.factory.createBlock( + [ts.factory.createExpressionStatement(ts.factory.createStringLiteral('use sendable'))], + true + ) + ); + updatedMembers = ts.factory.createNodeArray([constructor, ...(updatedMembers || [])]); + } + + node = ts.factory.updateClassDeclaration(node, updatedModifiers, node.name, node.typeParameters, + node.heritageClauses, updatedMembers); + + return node; +} + export function isOriginalExtend(node: ts.Block): boolean { let innerNode: ts.Node = node.statements[0]; if (node.statements.length === 1 && ts.isExpressionStatement(innerNode)) {