如何为Symbol.newMethod创建的方法添加注解(含@targetName)
给
newMethod创建的方法符号添加注解(含@targetName) 在Scala 3的编译时反射中,Symbol.newMethod生成的方法符号是不可变的,要添加注解(包括@targetName),需要通过Symbol.withAnnotations方法生成带注解的新符号。以下是具体实现步骤和示例:
实现步骤与代码示例
import scala.quoted.* def createAnnotatedMethod(using Quotes): Symbol = import Quotes.reflectModule.* // 1. 定义方法的所有者、名称和类型 val owner: Symbol = Symbol.spliceOwner // 方法所属的符号(比如当前类/对象) val methodName: String = "myMethod" // 定义无参、返回Unit的方法类型,可根据需求调整参数和返回值 val methodType: MethodType = MethodType(Nil)(_ => Nil, _ => TypeRepr.of[Unit]) // 2. 创建基础方法符号 val baseMethodSymbol: Symbol = Symbol.newMethod(owner, methodName, methodType) // 3. 构造@targetName注解实例 // 获取@targetName注解的类型符号 val targetNameAnnotSymbol: Symbol = TypeRepr.of[scala.annotation.targetName].typeSymbol // 注解参数:将字符串字面量转为Term类型 val targetNameArg: Term = Expr("my_method").asTerm // 创建Annotation实例 val targetNameAnnot: Annotation = Annotation(targetNameAnnotSymbol, List(targetNameArg)) // 4. 为方法符号添加注解(保留原有注解的话,拼接baseMethodSymbol.annotations) val annotatedMethodSymbol: Symbol = baseMethodSymbol.withAnnotations(List(targetNameAnnot)) annotatedMethodSymbol
关键细节说明
- 获取注解符号:通过
TypeRepr.of[注解类型].typeSymbol拿到对应注解的元数据符号,这是构造Annotation的核心。 - 处理注解参数:注解的参数需要是
Term类型,可通过Expr(参数值).asTerm将字面量或表达式转换为符合要求的Term实例。 - 保留原有注解:如果基础方法符号已经带有注解,想要追加而非覆盖,需要将原有注解列表与新注解拼接:
val annotatedMethodSymbol = baseMethodSymbol.withAnnotations( baseMethodSymbol.annotations :+ targetNameAnnot )
添加其他注解的通用方式
对于其他标准或自定义注解,流程完全一致,仅需修改注解类型和参数即可。例如添加@deprecated注解:
// 构造@deprecated注解(参数为提示信息和版本号) val deprecatedAnnotSymbol: Symbol = TypeRepr.of[scala.deprecated].typeSymbol val deprecatedArgs: List[Term] = List( Expr("此方法已废弃,请使用newMethod替代").asTerm, Expr("2.0").asTerm ) val deprecatedAnnot: Annotation = Annotation(deprecatedAnnotSymbol, deprecatedArgs) val methodWithDeprecation = baseMethodSymbol.withAnnotations(List(deprecatedAnnot))
内容的提问来源于stack exchange,提问作者Koosha
相关产品推荐
相关产品推荐

