Skip to content

Commit 5f5b5b0

Browse files
Merge pull request #6028 from dotty-staging/tasty-comment-api
Add tastyreflect comment API
2 parents 9362914 + 88bf54c commit 5f5b5b0

File tree

15 files changed

+143
-0
lines changed

15 files changed

+143
-0
lines changed

compiler/src/dotty/tools/dotc/consumetasty/TastyFromClass.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package dotty.tools.dotc.consumetasty
22

3+
import dotty.tools.dotc.Run
4+
import dotty.tools.dotc.core.Mode
5+
import dotty.tools.dotc.core.Contexts.Context
36
import dotty.tools.dotc.core.Phases.Phase
47
import dotty.tools.dotc.fromtasty._
58

@@ -17,4 +20,9 @@ class TastyFromClass(consumer: TastyConsumer) extends TASTYCompiler {
1720
override protected def backendPhases: List[List[Phase]] =
1821
List(new TastyConsumerPhase(consumer)) :: // Print all loaded classes
1922
Nil
23+
24+
override def newRun(implicit ctx: Context): Run = {
25+
reset()
26+
new TASTYRun(this, ctx.fresh.addMode(Mode.ReadPositions).addMode(Mode.ReadComments))
27+
}
2028
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package dotty.tools.dotc.tastyreflect
2+
3+
trait CommentOpsImpl extends scala.tasty.reflect.CommentOps with CoreImpl {
4+
5+
implicit def CommentDeco(com: Comment): CommentAPI = new CommentAPI {
6+
override def raw: String = com.raw
7+
override def expanded: Option[String] = com.expanded
8+
override def usecases: List[(String, Option[DefDef])] = com.usecases.map { uc => (uc.code, uc.tpdCode) }
9+
}
10+
}

compiler/src/dotty/tools/dotc/tastyreflect/CoreImpl.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ trait CoreImpl extends scala.tasty.reflect.Core {
115115

116116
type Position = util.SourcePosition
117117

118+
type Comment = core.Comments.Comment
119+
118120
type Constant = Constants.Constant
119121

120122
type Symbol = core.Symbols.Symbol

compiler/src/dotty/tools/dotc/tastyreflect/ReflectionImpl.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class ReflectionImpl(val rootContext: Contexts.Context)
88
with CaseDefOpsImpl
99
with ConstantOpsImpl
1010
with ContextOpsImpl
11+
with CommentOpsImpl
1112
with FlagsOpsImpl
1213
with IdOpsImpl
1314
with ImportSelectorOpsImpl

compiler/src/dotty/tools/dotc/tastyreflect/SymbolOpsImpl.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ trait SymbolOpsImpl extends scala.tasty.reflect.SymbolOps with CoreImpl {
2828

2929
def pos(implicit ctx: Context): Position = symbol.sourcePos
3030

31+
def comment(implicit ctx: Context): Option[Comment] = {
32+
import dotty.tools.dotc.core.Comments.CommentsContext
33+
val docCtx = ctx.docCtx.getOrElse {
34+
throw new RuntimeException(
35+
"DocCtx could not be found and comments are unavailable. This is a compiler-internal error."
36+
)
37+
}
38+
docCtx.docstring(symbol)
39+
}
40+
3141
def owner(implicit ctx: Context): Symbol = symbol.owner
3242

3343
def isLocalDummy(implicit ctx: Context): Boolean = symbol.isLocalDummy

library/src/scala/tasty/Reflection.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ abstract class Reflection
77
with CaseDefOps
88
with ConstantOps
99
with ContextOps
10+
with CommentOps
1011
with FlagsOps
1112
with IdOps
1213
with ImportSelectorOps
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package scala.tasty.reflect
2+
3+
trait CommentOps extends Core {
4+
5+
trait CommentAPI {
6+
7+
/** Raw comment string */
8+
def raw: String
9+
10+
/** Expanded comment string, if any */
11+
def expanded: Option[String]
12+
13+
/** List of usecases and their corresponding trees, if any */
14+
def usecases: List[(String, Option[DefDef])]
15+
16+
}
17+
implicit def CommentDeco(com: Comment): CommentAPI
18+
19+
}

library/src/scala/tasty/reflect/Core.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,9 @@ trait Core {
410410
/** Source position */
411411
type Position <: AnyRef
412412

413+
/** Comment */
414+
type Comment <: AnyRef
415+
413416
/** Constant value represented as the constant itself */
414417
type Constant <: AnyRef
415418

library/src/scala/tasty/reflect/SymbolOps.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ trait SymbolOps extends Core {
3737
/** The position of this symbol */
3838
def pos(implicit ctx: Context): Position
3939

40+
/** The comment for this symbol, if any */
41+
def comment(implicit ctx: Context): Option[Comment]
42+
4043
def localContext(implicit ctx: Context): Context
4144

4245
/** Unsafe cast as to PackageSymbol. Use IsPackageSymbol to safly check and cast to PackageSymbol */
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/** Object with comment */
2+
/** Object with comment */
3+
4+
5+
6+
/** Val with comment */
7+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/** Object with comment */
2+
object Foo {
3+
4+
/** Val with comment */
5+
val x = null
6+
7+
val y = null // val without comment
8+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import scala.tasty.Reflection
2+
import scala.tasty.file._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
ConsumeTasty("", List("Foo"), new CommentConsumer)
7+
}
8+
}
9+
10+
class CommentConsumer extends TastyConsumer {
11+
12+
final def apply(reflect: Reflection)(root: reflect.Tree): Unit = {
13+
import reflect._
14+
object Traverser extends TreeTraverser {
15+
16+
override def traverseTree(tree: Tree)(implicit ctx: Context): Unit = tree match {
17+
case IsDefinition(tree) =>
18+
tree.symbol.comment match {
19+
case Some(com) => println(com.raw)
20+
case None => println()
21+
}
22+
super.traverseTree(tree)
23+
case tree =>
24+
super.traverseTree(tree)
25+
}
26+
27+
}
28+
Traverser.traverseTree(root)(reflect.rootContext)
29+
}
30+
31+
}

tests/run/tasty-comments.check

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/** Object with a docstring */
2+
/** Val with a docstring */
3+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import scala.quoted._
2+
3+
import scala.tasty._
4+
5+
object Macros {
6+
7+
inline def printComment[T](t: => T): Unit =
8+
${ impl('t) }
9+
10+
def impl[T](x: Expr[T])(implicit reflect: Reflection): Expr[Unit] = {
11+
import reflect._
12+
13+
val tree = x.unseal
14+
tree.symbol.comment.map(_.raw) match {
15+
case Some(str) => '{ println(${str.toExpr}) }
16+
case None => '{ println() }
17+
}
18+
}
19+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import Macros._
2+
3+
object Test {
4+
5+
/** Object with a docstring */
6+
object Obj
7+
8+
/** Val with a docstring */
9+
val x: Null = null
10+
11+
val y: Null = null // val without a docstring
12+
13+
def main(args: Array[String]): Unit = {
14+
printComment(Obj)
15+
printComment(x)
16+
printComment(y)
17+
}
18+
}

0 commit comments

Comments
 (0)