如何在Scaladoc子类中覆写@define宏定义?
问题解答:Scaladoc中跨类替换@define变量的实现
首先明确:这不是Scaladoc的bug,而是它的静态文本替换设计导致的——@define变量是在定义文档的类/特质内部完成替换的,基类中foo方法的$Word在生成基类Scaladoc时就已经被替换成base-word了,子类继承的是这个已经替换完成的文档文本,而非带占位符的模板,所以子类的@define Word无法影响基类方法的文档内容。
下面提供两种可行的解决方案:
方法1:使用Scaladoc宏(推荐,实现动态替换)
Scaladoc宏允许你在生成文档时动态读取当前类的注解信息,从而实现跨类的变量替换。你需要编写一个简单的宏来完成这个逻辑:
第一步:实现Scaladoc宏
创建一个宏类(注意需要放在单独的编译模块,或者作为编译时依赖):
import scala.reflect.macros._ import scala.language.experimental.macros class DocWordMacro(val c: blackbox.Context) { def getWord: c.Tree = { import c.universe._ // 从当前类的@define注解中提取Word的值 val wordValue = c.enclosingClass.annotations .find(_.tree.tpe =:= typeOf[scala.annotation.meta.Define]) .flatMap { ann => ann.tree.children.collectFirst { case Literal(Constant(s: String)) if s.startsWith("Word=") => s.substring(5) } } .getOrElse("base-word") // 基类默认值 q""" "Does a " + $wordValue """ } } object DocMacros { def wordPlaceholder: String = macro DocWordMacro.getWord }
第二步:在类中使用宏
修改你的基类和子类,用宏替换原来的$Word占位符:
/** * @define Word base-word */ class DocTestBase { /** ${DocMacros.wordPlaceholder} * * @return */ def foo = 1 } /** * @define Word subclass word! */ class DocTestSubclass extends DocTestBase
当生成Scaladoc时,宏会在子类的上下文执行,自动读取子类的@define Word值,替换到方法文档中,达到你预期的效果。
方法2:子类手动重写方法并替换文档
如果不想引入宏,也可以在子类中重写方法,手动替换文档内容:
/** * @define Word base-word */ class DocTestBase { /** Does a $Word * * @return */ def foo = 1 } /** * @define Word subclass word! */ class DocTestSubclass extends DocTestBase { /** Does a $Word * * @inheritdoc // 继承基类方法的其他文档内容 */ override def foo = super.foo }
这种方法的缺点是需要在每个子类中重复重写方法,适合子类数量较少的场景。
内容的提问来源于stack exchange,提问作者Dylan
相关产品推荐
相关产品推荐

