diff options
author | Gilles Dubochet <gilles.dubochet@epfl.ch> | 2010-11-05 15:32:14 +0000 |
---|---|---|
committer | Gilles Dubochet <gilles.dubochet@epfl.ch> | 2010-11-05 15:32:14 +0000 |
commit | 4659d81554c1eb5bda6730d48e0dfed747679862 (patch) | |
tree | ae9472746643f8eb385fb5f8eb4a173bf74807bb /src | |
parent | e3b2ebcbcf15c3b5ae5d4f7655073698f890c2b8 (diff) | |
download | scala-4659d81554c1eb5bda6730d48e0dfed747679862.tar.gz scala-4659d81554c1eb5bda6730d48e0dfed747679862.tar.bz2 scala-4659d81554c1eb5bda6730d48e0dfed747679862.zip |
[scaladoc] Annotations are modeled and printed.
Diffstat (limited to 'src')
4 files changed, 103 insertions, 32 deletions
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala index 622d2cdc22..9132d8754d 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala @@ -219,7 +219,7 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage { def memberToInlineCommentHtml(mbr: MemberEntity, isSelf: Boolean): NodeSeq = <p class="comment cmt">{ inlineToHtml(mbr.comment.get.short) }</p> - def memberToCommentBodyHtml(mbr: MemberEntity, isSelf: Boolean, isReduced: Boolean = false): NodeSeq = + def memberToCommentBodyHtml(mbr: MemberEntity, isSelf: Boolean, isReduced: Boolean = false): NodeSeq = { NodeSeq.Empty ++ { if (mbr.comment.isEmpty) NodeSeq.Empty else <div class="comment cmt">{ commentToHtml(mbr.comment) }</div> @@ -310,6 +310,30 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage { case _ => NodeSeq.Empty } } ++ + { if (!mbr.annotations.isEmpty) { + <div class="block"> + annotations: { + mbr.annotations.map { annot => + <xml:group> + <span class="name">@{ templateToHtml(annot.annotationClass) }</span>{ + def paramsToHtml(vls: List[ValueArgument]): NodeSeq = + vls map { vl => + <span>{ + vl.parameter match { + case Some(p) => Text(p.name + " = ") + case None => NodeSeq.Empty + } + }{ treeToHtml(vl.value) }</span> + } + <span class="params">({ paramsToHtml(annot.arguments) })</span> + } + </xml:group> + } + } + </div> + } + else NodeSeq.Empty + } ++ { mbr match { case dtpl: DocTemplateEntity if (isSelf && dtpl.sourceUrl.isDefined && dtpl.inSource.isDefined && !isReduced) => val (absFile, line) = dtpl.inSource.get @@ -351,6 +375,7 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage { case None => NodeSeq.Empty } } + } def kindToString(mbr: MemberEntity): String = mbr match { case tpl: DocTemplateEntity => docEntityKindToString(tpl) @@ -418,33 +443,35 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage { tparamsToHtml(mbr) } { if (isReduced) NodeSeq.Empty else { - def paramsToHtml(vlsss: List[List[ValueParam]]): NodeSeq = { - def param0(vl: ValueParam): NodeSeq = - // notice the }{ in the next lines, they are necessary to avoid a undesired withspace in output - <span name={ vl.name }>{ Text(vl.name + ": ") }{ typeToHtml(vl.resultType, hasLinks) }{ - if(!vl.defaultValue.isEmpty) { - defaultValueToHtml(vl.defaultValue.get); - } - else NodeSeq.Empty - }</span> - def params0(vlss: List[ValueParam]): NodeSeq = vlss match { - case Nil => NodeSeq.Empty - case vl :: Nil => param0(vl) - case vl :: vls => param0(vl) ++ Text(", ") ++ params0(vls) + def paramsToHtml(vlsss: List[List[ValueParam]]): NodeSeq = { + def param0(vl: ValueParam): NodeSeq = + // notice the }{ in the next lines, they are necessary to avoid a undesired withspace in output + <span name={ vl.name }>{ Text(vl.name + ": ") }{ typeToHtml(vl.resultType, hasLinks) }{ + if(!vl.defaultValue.isEmpty) { + treeToHtml(vl.defaultValue.get); + } + else NodeSeq.Empty + }</span> + + def params0(vlss: List[ValueParam]): NodeSeq = vlss match { + case Nil => NodeSeq.Empty + case vl :: Nil => param0(vl) + case vl :: vls => param0(vl) ++ Text(", ") ++ params0(vls) + } + def implicitCheck(vlss: List[ValueParam]): NodeSeq = vlss match { + case vl :: vls => if(vl.isImplicit) { <span class="implicit">implicit </span> } else Text("") + case _ => Text("") + } + vlsss map { vlss => <span class="params">({implicitCheck(vlss) ++ params0(vlss) })</span> } } - def implicitCheck(vlss: List[ValueParam]): NodeSeq = vlss match { - case vl :: vls => if(vl.isImplicit) { <span class="implicit">implicit </span> } else Text("") - case _ => Text("") + mbr match { + case cls: Class => paramsToHtml(cls.valueParams) + case ctr: Constructor => paramsToHtml(ctr.valueParams) + case dfe: Def => paramsToHtml(dfe.valueParams) + case _ => NodeSeq.Empty } - vlsss map { vlss => <span class="params">({implicitCheck(vlss) ++ params0(vlss) })</span> } } - mbr match { - case cls: Class => paramsToHtml(cls.valueParams) - case ctr: Constructor => paramsToHtml(ctr.valueParams) - case dfe: Def => paramsToHtml(dfe.valueParams) - case _ => NodeSeq.Empty - } - }} + } { if (isReduced) NodeSeq.Empty else { mbr match { case tpl: DocTemplateEntity if (!tpl.isPackage) => @@ -477,7 +504,7 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage { } /** */ - def defaultValueToHtml(defVal:TreeEntity):NodeSeq = { + def treeToHtml(defVal:TreeEntity):NodeSeq = { var index = 0 val str = defVal.expression val length = str.length @@ -500,7 +527,6 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage { val anchor = "#" + mbr.name + defParamsString(mbr) + ":" + mbr.resultType.name val link = relativeLinkTo(mbr.inTemplate) myXml ++= <span class="name"><a href={link ++ anchor}>{str.substring(from, to)}</a></span> - case _ => assert(false, "unexpected case in defaultValueToHtml") } index = to } diff --git a/src/compiler/scala/tools/nsc/doc/model/Entity.scala b/src/compiler/scala/tools/nsc/doc/model/Entity.scala index 6d81b8271e..a042cf636a 100644 --- a/src/compiler/scala/tools/nsc/doc/model/Entity.scala +++ b/src/compiler/scala/tools/nsc/doc/model/Entity.scala @@ -18,6 +18,7 @@ trait Entity { def qualifiedName: String override def toString = qualifiedName def universe: Universe + def annotations: List[Annotation] } /** A class, trait, object or package. A package is represented as an instance @@ -158,6 +159,18 @@ trait ValueParam extends ParameterEntity { def isImplicit: Boolean } +/** An annotation, defined by its class and its constructor arguments. */ +trait Annotation extends Entity { + def annotationClass: TemplateEntity + def arguments: List[ValueArgument] +} + +/** A value that is passed as an argument to a value paramater. */ +trait ValueArgument { + def parameter: Option[ValueParam] + def value: TreeEntity +} + /** An type that represents visibility of members. */ sealed trait Visibility { def isProtected: Boolean = false diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala index 080af68d27..449fdca7b9 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala @@ -59,6 +59,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory def toRoot: List[EntityImpl] = this :: inTpl.toRoot def qualifiedName = name val universe = thisFactory.universe + def annotations = sym.annotations.map(makeAnnotation) } /** Provides a default implementation for instances of the `WeakTemplateEntity` type. It must be instantiated as a @@ -162,7 +163,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory templatesCache += (sym -> this) lazy val definitionName = optimize(inDefinitionTemplates.head.qualifiedName + "." + name) override def toRoot: List[DocTemplateImpl] = this :: inTpl.toRoot - def inSource = if (sym.sourceFile != null) Some(sym.sourceFile, sym.pos.line) else None + def inSource = if (sym.sourceFile != null) Some((sym.sourceFile, sym.pos.line)) else None def sourceUrl = { def fixPath(s: String) = s.replaceAll("\\" + java.io.File.separator, "/") val assumedSourceRoot: String = { @@ -376,6 +377,37 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory } /** */ + def makeAnnotation(annot: AnnotationInfo): Annotation = { + val aSym = annot.atp.typeSymbol + new EntityImpl(aSym, makeTemplate(aSym.owner)) with Annotation { + def annotationClass = + makeTemplate(annot.atp.typeSymbol) + def arguments = + annotationClass match { + case aClass: Class => + aClass.valueParams match { + case Nil => Nil + case vp :: vps => + (vp zip annot.args) map { case (param, arg) => + new ValueArgument { + def parameter = Some(param) + def value = makeTree(arg) + } + } + } + case _ => + annot.args map { arg => + new ValueArgument { + def parameter = None + def value = makeTree(arg) + } + } + } + + } + } + + /** */ def makeMember(aSym: Symbol, inTpl: => DocTemplateImpl): List[MemberImpl] = { def makeMember0(bSym: Symbol): Option[MemberImpl] = { @@ -457,17 +489,17 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { thisFactory def isTypeParam = false def isValueParam = true def defaultValue = - if (aSym.hasDefault) + if (aSym.hasDefault) { // units.filter should return only one element (currentRun.units filter (_.source.file == aSym.sourceFile)).toList match { case List(unit) => (unit.body find (_.symbol == aSym)) match { - case Some(ValDef(_,_,_,rhs)) => - Some(makeTree(rhs)) + case Some(ValDef(_,_,_,rhs)) => Some(makeTree(rhs)) case _ => None } case _ => None } + } else None def resultType = makeType(sym.tpe, inTpl, sym) diff --git a/src/compiler/scala/tools/nsc/doc/model/TreeEntity.scala b/src/compiler/scala/tools/nsc/doc/model/TreeEntity.scala index 7a0c8c7961..425a735a3a 100644 --- a/src/compiler/scala/tools/nsc/doc/model/TreeEntity.scala +++ b/src/compiler/scala/tools/nsc/doc/model/TreeEntity.scala @@ -13,4 +13,4 @@ import scala.collection.immutable.TreeMap class TreeEntity { var expression:String = "" var refs = new TreeMap[Int, (Entity, Int)] // start, (Entity to be linked to , end) -}
\ No newline at end of file +} |