Skip to content

Add tastyreflect comment API #6028

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package dotty.tools.dotc.consumetasty

import dotty.tools.dotc.Run
import dotty.tools.dotc.core.Mode
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.Phases.Phase
import dotty.tools.dotc.fromtasty._

Expand All @@ -17,4 +20,9 @@ class TastyFromClass(consumer: TastyConsumer) extends TASTYCompiler {
override protected def backendPhases: List[List[Phase]] =
List(new TastyConsumerPhase(consumer)) :: // Print all loaded classes
Nil

override def newRun(implicit ctx: Context): Run = {
reset()
new TASTYRun(this, ctx.fresh.addMode(Mode.ReadPositions).addMode(Mode.ReadComments))
}
}
10 changes: 10 additions & 0 deletions compiler/src/dotty/tools/dotc/tastyreflect/CommentOpsImpl.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package dotty.tools.dotc.tastyreflect

trait CommentOpsImpl extends scala.tasty.reflect.CommentOps with CoreImpl {

implicit def CommentDeco(com: Comment): CommentAPI = new CommentAPI {
override def raw: String = com.raw
override def expanded: Option[String] = com.expanded
override def usecases: List[(String, Option[DefDef])] = com.usecases.map { uc => (uc.code, uc.tpdCode) }
}
}
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/tastyreflect/CoreImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ trait CoreImpl extends scala.tasty.reflect.Core {

type Position = util.SourcePosition

type Comment = core.Comments.Comment

type Constant = Constants.Constant

type Symbol = core.Symbols.Symbol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class ReflectionImpl(val rootContext: Contexts.Context)
with CaseDefOpsImpl
with ConstantOpsImpl
with ContextOpsImpl
with CommentOpsImpl
with FlagsOpsImpl
with IdOpsImpl
with ImportSelectorOpsImpl
Expand Down
10 changes: 10 additions & 0 deletions compiler/src/dotty/tools/dotc/tastyreflect/SymbolOpsImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ trait SymbolOpsImpl extends scala.tasty.reflect.SymbolOps with CoreImpl {

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

def comment(implicit ctx: Context): Option[Comment] = {
import dotty.tools.dotc.core.Comments.CommentsContext
val docCtx = ctx.docCtx.getOrElse {
throw new RuntimeException(
"DocCtx could not be found and comments are unavailable. This is a compiler-internal error."
)
}
docCtx.docstring(symbol)
}

def owner(implicit ctx: Context): Symbol = symbol.owner

def isLocalDummy(implicit ctx: Context): Boolean = symbol.isLocalDummy
Expand Down
1 change: 1 addition & 0 deletions library/src/scala/tasty/Reflection.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ abstract class Reflection
with CaseDefOps
with ConstantOps
with ContextOps
with CommentOps
with FlagsOps
with IdOps
with ImportSelectorOps
Expand Down
19 changes: 19 additions & 0 deletions library/src/scala/tasty/reflect/CommentOps.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package scala.tasty.reflect

trait CommentOps extends Core {

trait CommentAPI {

/** Raw comment string */
def raw: String

/** Expanded comment string, if any */
def expanded: Option[String]

/** List of usecases and their corresponding trees, if any */
def usecases: List[(String, Option[DefDef])]

}
implicit def CommentDeco(com: Comment): CommentAPI

}
3 changes: 3 additions & 0 deletions library/src/scala/tasty/reflect/Core.scala
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,9 @@ trait Core {
/** Source position */
type Position <: AnyRef

/** Comment */
type Comment <: AnyRef

/** Constant value represented as the constant itself */
type Constant <: AnyRef

Expand Down
3 changes: 3 additions & 0 deletions library/src/scala/tasty/reflect/SymbolOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ trait SymbolOps extends Core {
/** The position of this symbol */
def pos(implicit ctx: Context): Position

/** The comment for this symbol, if any */
def comment(implicit ctx: Context): Option[Comment]

def localContext(implicit ctx: Context): Context

/** Unsafe cast as to PackageSymbol. Use IsPackageSymbol to safly check and cast to PackageSymbol */
Expand Down
7 changes: 7 additions & 0 deletions tests/run-with-compiler/tasty-comment-consumer.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** Object with comment */
/** Object with comment */



/** Val with comment */

8 changes: 8 additions & 0 deletions tests/run-with-compiler/tasty-comment-consumer/Foo.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** Object with comment */
object Foo {

/** Val with comment */
val x = null

val y = null // val without comment
}
31 changes: 31 additions & 0 deletions tests/run-with-compiler/tasty-comment-consumer/Test.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import scala.tasty.Reflection
import scala.tasty.file._

object Test {
def main(args: Array[String]): Unit = {
ConsumeTasty("", List("Foo"), new CommentConsumer)
}
}

class CommentConsumer extends TastyConsumer {

final def apply(reflect: Reflection)(root: reflect.Tree): Unit = {
import reflect._
object Traverser extends TreeTraverser {

override def traverseTree(tree: Tree)(implicit ctx: Context): Unit = tree match {
case IsDefinition(tree) =>
tree.symbol.comment match {
case Some(com) => println(com.raw)
case None => println()
}
super.traverseTree(tree)
case tree =>
super.traverseTree(tree)
}

}
Traverser.traverseTree(root)(reflect.rootContext)
}

}
3 changes: 3 additions & 0 deletions tests/run/tasty-comments.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/** Object with a docstring */
/** Val with a docstring */

19 changes: 19 additions & 0 deletions tests/run/tasty-comments/quoted_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import scala.quoted._

import scala.tasty._

object Macros {

inline def printComment[T](t: => T): Unit =
${ impl('t) }

def impl[T](x: Expr[T])(implicit reflect: Reflection): Expr[Unit] = {
import reflect._

val tree = x.unseal
tree.symbol.comment.map(_.raw) match {
case Some(str) => '{ println(${str.toExpr}) }
case None => '{ println() }
}
}
}
18 changes: 18 additions & 0 deletions tests/run/tasty-comments/quoted_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Macros._

object Test {

/** Object with a docstring */
object Obj

/** Val with a docstring */
val x: Null = null

val y: Null = null // val without a docstring

def main(args: Array[String]): Unit = {
printComment(Obj)
printComment(x)
printComment(y)
}
}