From b18549438f01d5ea45caf557e7256364d6e60269 Mon Sep 17 00:00:00 2001 From: Igor Loginov Date: Fri, 28 Feb 2025 16:30:52 +0300 Subject: [PATCH] More info about errors --- .../memo-plugin/src/FunctionTransformer.ts | 72 ++++++++++++++++--- 1 file changed, 63 insertions(+), 9 deletions(-) diff --git a/arkoala-arkts/memo-plugin/src/FunctionTransformer.ts b/arkoala-arkts/memo-plugin/src/FunctionTransformer.ts index 349a2c5dcf..26d64c2a5c 100644 --- a/arkoala-arkts/memo-plugin/src/FunctionTransformer.ts +++ b/arkoala-arkts/memo-plugin/src/FunctionTransformer.ts @@ -69,6 +69,11 @@ function updateFunctionBody( ] } +type ScopeInfo = { + name?: string, + isMemo: boolean +} + export class FunctionTransformer extends AbstractVisitor { constructor( private positionalIdTracker: PositionalIdTracker, @@ -78,6 +83,49 @@ export class FunctionTransformer extends AbstractVisitor { super() } + private scopes: ScopeInfo[] = [] + + enter(node: arkts.AstNode) { + if (arkts.isMethodDefinition(node)) { + const name = node.name.name + const isMemo = hasMemoAnnotation(node.scriptFunction) || hasMemoIntrinsicAnnotation(node.scriptFunction) + this.scopes.push({ name , isMemo }) + } + return this + } + + exit(node: arkts.AstNode) { + if (arkts.isMethodDefinition(node)) { + this.scopes.pop() + } + return this + } + + enterAnonymousScope(node: arkts.ScriptFunction) { + const name = undefined + const isMemo = hasMemoAnnotation(node) || hasMemoIntrinsicAnnotation(node) + this.scopes.push({ name, isMemo }) + return this + } + + exitAnonymousScope() { + this.scopes.pop() + return this + } + + checkMemoCall(decl: arkts.MethodDefinition) { + if (this.scopes[this.scopes.length - 1].isMemo == false) { + if (this.scopes[this.scopes.length - 1].name) { + console.error(`Attempt to call @memo-method ${decl.name.name} from non-@memo-method ${this.scopes[this.scopes.length - 1].name}`) + throw "Invalid @memo usage" + } else { + console.error(`Attempt to call @memo-method ${decl.name.name} from anonymous non-@memo-method`) + throw "Invalid @memo usage" + } + } + return this + } + updateScriptFunction( scriptFunction: arkts.ScriptFunction, name: string = "", @@ -113,7 +161,13 @@ export class FunctionTransformer extends AbstractVisitor { }) ) } else { - throw "ETSFunctionType or ETSUnionType expected for @memo parameter of @memo function" + if (name) { + console.error(`ETSFunctionType or ETSUnionType expected for @memo-parameter ${param.identifier.name} of @memo-method ${name}`) + throw "Invalid @memo usage" + } else { + console.error(`ETSFunctionType or ETSUnionType expected for @memo-parameter ${param.identifier.name} of anonymous @memo-method`) + throw "Invalid @memo usage" + } } } return param @@ -132,15 +186,11 @@ export class FunctionTransformer extends AbstractVisitor { } visitor(beforeChildren: arkts.AstNode): arkts.AstNode { - // TODO: Remove (currently annotations are lost on visitor) - const methodDefinitionHasMemoAnnotation = - arkts.isMethodDefinition(beforeChildren) && hasMemoAnnotation(beforeChildren.scriptFunction) - const methodDefinitionHasMemoIntrinsicAnnotation = - arkts.isMethodDefinition(beforeChildren) && hasMemoIntrinsicAnnotation(beforeChildren.scriptFunction) - + this.enter(beforeChildren) const node = this.visitEachChild(beforeChildren) + this.exit(beforeChildren) if (arkts.isMethodDefinition(node) && node.scriptFunction.body) { - if (methodDefinitionHasMemoAnnotation || methodDefinitionHasMemoIntrinsicAnnotation) { + if (hasMemoAnnotation(node.scriptFunction) || hasMemoIntrinsicAnnotation(node.scriptFunction)) { return arkts.factory.updateMethodDefinition( node, arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_METHOD, @@ -157,6 +207,7 @@ export class FunctionTransformer extends AbstractVisitor { const expr = node.expression const decl = arkts.getDecl(expr) if (decl && arkts.isMethodDefinition(decl) && (hasMemoAnnotation(decl.scriptFunction) || hasMemoIntrinsicAnnotation(decl.scriptFunction))) { + this.checkMemoCall(decl) const updatedArguments = node.arguments.map((it, index) => { const type = decl.scriptFunction.parameters[index].type if (type && arkts.isETSFunctionType(type)) { @@ -164,7 +215,10 @@ export class FunctionTransformer extends AbstractVisitor { return factory.createComputeExpression(this.positionalIdTracker.id(decl.name.name), it) } if (arkts.isArrowFunctionExpression(it)) { - return this.updateScriptFunction(it.scriptFunction) + this.enterAnonymousScope(it.scriptFunction) + const res = this.updateScriptFunction(it.scriptFunction) + this.exitAnonymousScope() + return res } } return it -- Gitee