Skip to content

Commit fbd5d86

Browse files
committed
Render classifier capabilities in scaladoc
1 parent 3d3caf7 commit fbd5d86

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

scaladoc/src/dotty/tools/scaladoc/cc/CaptureOps.scala

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ object CaptureDefs:
3636
qctx.reflect.Symbol.requiredClass("scala.annotation.internal.readOnlyCapability")
3737
def RequiresCapabilityAnnot(using qctx: Quotes) =
3838
qctx.reflect.Symbol.requiredClass("scala.annotation.internal.requiresCapability")
39+
def OnlyCapabilityAnnot(using qctx: Quotes) =
40+
qctx.reflect.Symbol.requiredClass("scala.annotation.internal.onlyCapability")
3941

4042
def LanguageExperimental(using qctx: Quotes) =
4143
qctx.reflect.Symbol.requiredPackage("scala.language.experimental")
@@ -71,6 +73,9 @@ extension (using qctx: Quotes)(ann: qctx.reflect.Symbol)
7173

7274
def isReadOnlyCapabilityAnnot: Boolean =
7375
ann == CaptureDefs.ReadOnlyCapabilityAnnot
76+
77+
def isOnlyCapabilityAnnot: Boolean =
78+
ann == CaptureDefs.OnlyCapabilityAnnot
7479
end extension
7580

7681
extension (using qctx: Quotes)(tpe: qctx.reflect.TypeRepr) // FIXME clean up and have versions on Symbol for those
@@ -171,6 +176,17 @@ object ReadOnlyCapability:
171176
case _ => None
172177
end ReadOnlyCapability
173178

179+
object OnlyCapability:
180+
def unapply(using qctx: Quotes)(ty: qctx.reflect.TypeRepr): Option[(qctx.reflect.TypeRepr, qctx.reflect.Symbol)] =
181+
import qctx.reflect._
182+
ty match
183+
case AnnotatedType(base, app @ Apply(TypeApply(Select(New(annot), _), _), Nil)) if annot.tpe.typeSymbol.isOnlyCapabilityAnnot =>
184+
app.tpe.typeArgs.head.classSymbol.match
185+
case Some(clazzsym) => Some((base, clazzsym))
186+
case None => None
187+
case _ => None
188+
end OnlyCapability
189+
174190
/** Decompose capture sets in the union-type-encoding into the sequence of atomic `TypeRepr`s.
175191
* Returns `None` if the type is not a capture set.
176192
*/
@@ -187,8 +203,9 @@ def decomposeCaptureRefs(using qctx: Quotes)(typ0: qctx.reflect.TypeRepr): Optio
187203
case t @ ParamRef(_, _) => include(t)
188204
case t @ ReachCapability(_) => include(t)
189205
case t @ ReadOnlyCapability(_) => include(t)
190-
case t : TypeRef => include(t) // FIXME: does this need a more refined check?
191-
case _ => report.warning(s"Unexpected type tree $typ while trying to extract capture references from $typ0"); false // TODO remove warning eventually
206+
case t @ OnlyCapability(_, _) => include(t)
207+
case t : TypeRef => include(t)
208+
case _ => report.warning(s"Unexpected type tree $typ while trying to extract capture references from $typ0"); false
192209
if traverse(typ0) then Some(buffer.toList) else None
193210
end decomposeCaptureRefs
194211

scaladoc/src/dotty/tools/scaladoc/tasty/TypesSupport.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import dotty.tools.scaladoc.cc.*
1010

1111
import NameNormalizer._
1212
import SyntheticsSupport._
13+
import java.awt.RenderingHints.Key
1314

1415
trait TypesSupport:
1516
self: TastyParser =>
@@ -514,10 +515,11 @@ trait TypesSupport:
514515
private def emitCapability(using Quotes)(ref: reflect.TypeRepr, skipThisTypePrefix: Boolean)(using elideThis: reflect.ClassDef, originalOwner: reflect.Symbol): SSignature =
515516
import reflect._
516517
ref match
517-
case ReachCapability(c) => emitCapability(c, skipThisTypePrefix) :+ Keyword("*")
518-
case ReadOnlyCapability(c) => emitCapability(c, skipThisTypePrefix) :+ Keyword(".rd")
519-
case ThisType(_) => List(Keyword("this"))
520-
case t => inner(t, skipThisTypePrefix)(using skipTypeSuffix = true, inCC = Some(Nil))
518+
case ReachCapability(c) => emitCapability(c, skipThisTypePrefix) :+ Keyword("*")
519+
case ReadOnlyCapability(c) => emitCapability(c, skipThisTypePrefix) :+ Keyword(".rd")
520+
case OnlyCapability(c, cls) => emitCapability(c, skipThisTypePrefix) ++ List(Plain("."), Keyword("only"), Plain("[")) ++ inner(cls.typeRef, skipThisTypePrefix) :+ Plain("]")
521+
case ThisType(_) => List(Keyword("this"))
522+
case t => inner(t, skipThisTypePrefix)(using skipTypeSuffix = true, inCC = Some(Nil))
521523

522524
private def emitCaptureSet(using Quotes)(refs: List[reflect.TypeRepr], skipThisTypePrefix: Boolean, omitCap: Boolean = true)(using elideThis: reflect.ClassDef, originalOwner: reflect.Symbol): SSignature =
523525
import reflect._

0 commit comments

Comments
 (0)