Skip to content

Use quote context for in tasty inspector #9646

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
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,6 +1,6 @@
package scala.tasty.inspector

import scala.tasty.Reflection
import scala.quoted._

import dotty.tools.dotc.Compiler
import dotty.tools.dotc.Driver
Expand All @@ -18,7 +18,7 @@ trait TastyInspector:
self =>

/** Process a TASTy file using TASTy reflect */
protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit
protected def processCompilationUnit(using QuoteContext)(root: qctx.tasty.Tree): Unit

/** Load and process TASTy files using TASTy reflect
*
Expand Down Expand Up @@ -58,7 +58,7 @@ trait TastyInspector:

override def run(implicit ctx: Context): Unit =
val qctx = QuoteContextImpl()
self.processCompilationUnit(qctx.tasty)(ctx.compilationUnit.tpdTree.asInstanceOf[qctx.tasty.Tree])
self.processCompilationUnit(using qctx)(ctx.compilationUnit.tpdTree.asInstanceOf[qctx.tasty.Tree])

end TastyInspectorPhase

Expand Down
70 changes: 34 additions & 36 deletions tastydoc/src/dotty/tastydoc/TastyExtractor.scala
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package dotty.tastydoc

import scala.tasty.Reflection
import scala.quoted._
import dotty.tastydoc.comment.{CommentParser, CommentCleaner, Comment, WikiComment, MarkdownComment}
import dotty.tastydoc.references._
import dotty.tastydoc.representations._

/** A trait containing useful methods for extracting information from the reflect API */
trait TastyExtractor extends TastyTypeConverter with CommentParser with CommentCleaner{
def extractPath(reflect: Reflection)(symbol: reflect.Symbol) : List[String] = {
import reflect.{given _, _}
def extractPath(using QuoteContext)(symbol: qctx.tasty.Symbol) : List[String] = {
import qctx.tasty._

val pathArray = symbol.show.split("\\.") // NOTE: this should print w/o colors, inspect afterwards
pathArray.iterator.slice(0, pathArray.length - 1).toList
}

def extractModifiers(reflect: Reflection)(flags: reflect.Flags, privateWithin: Option[reflect.Type], protectedWithin: Option[reflect.Type]) : (List[String], Option[Reference], Option[Reference]) = {
import reflect.{given _, _}
def extractModifiers(using QuoteContext)(flags: qctx.tasty.Flags, privateWithin: Option[qctx.tasty.Type], protectedWithin: Option[qctx.tasty.Type]) : (List[String], Option[Reference], Option[Reference]) = {
import qctx.tasty._

(((if(flags.is(Flags.Override)) "override" else "") ::
(if(flags.is(Flags.Private)) "private" else "")::
Expand All @@ -30,18 +30,16 @@ trait TastyExtractor extends TastyTypeConverter with CommentParser with CommentC
Nil) filter (_ != ""),

privateWithin match {
case Some(t) => Some(convertTypeToReference(reflect)(t))
case Some(t) => Some(convertTypeToReference(t))
case None => None
},
protectedWithin match {
case Some(t) => Some(convertTypeToReference(reflect)(t))
case Some(t) => Some(convertTypeToReference(t))
case None => None
})
}

def extractComments(reflect: Reflection)(comment: Option[reflect.Comment], rep: Representation) : (Map[String, EmulatedPackageRepresentation], String) => Option[Comment] = {
import reflect.{given _, _}

def extractComments(using QuoteContext)(comment: Option[qctx.tasty.Comment], rep: Representation) : (Map[String, EmulatedPackageRepresentation], String) => Option[Comment] = {
comment match {
case Some(com) =>
(packages, userDocSyntax) => {
Expand All @@ -58,13 +56,13 @@ trait TastyExtractor extends TastyTypeConverter with CommentParser with CommentC
}
}

def extractClassMembers(reflect: Reflection)(body: List[reflect.Statement], symbol: reflect.Symbol, parentRepresentation: Some[Representation])(using mutablePackagesMap: scala.collection.mutable.HashMap[String, EmulatedPackageRepresentation]) : List[Representation with Modifiers] = {
import reflect.{given _, _}
def extractClassMembers(using QuoteContext)(body: List[qctx.tasty.Statement], symbol: qctx.tasty.Symbol, parentRepresentation: Some[Representation])(using mutablePackagesMap: scala.collection.mutable.HashMap[String, EmulatedPackageRepresentation]) : List[Representation with Modifiers] = {
import qctx.tasty._

/** Filter fields which shouldn't be displayed in the doc
*/
def filterSymbol(symbol: reflect.Symbol): Boolean = {
val ownerPath = extractPath(reflect)(symbol.owner)
def filterSymbol(symbol: Symbol): Boolean = {
val ownerPath = extractPath(symbol.owner)

!symbol.flags.is(Flags.Synthetic) &&
!symbol.flags.is(Flags.Artifact) &&
Expand All @@ -79,16 +77,16 @@ trait TastyExtractor extends TastyTypeConverter with CommentParser with CommentC
case _: ValDef => None //No val/var, they are appended with symbol.fields below
case _: Inlined => None //Inlined aren't desirable members
case x => Some(x)
}.filter(x => filterSymbol(x.symbol)).map(convertToRepresentation(reflect)(_, parentRepresentation)) ++
symbol.methods.filter(x => filterSymbol(x)).map{x => convertToRepresentation(reflect)(x.tree, parentRepresentation)} ++
}.filter(x => filterSymbol(x.symbol)).map(convertToRepresentation(_, parentRepresentation)) ++
symbol.methods.filter(x => filterSymbol(x)).map{x => convertToRepresentation(x.tree, parentRepresentation)} ++
symbol.fields.filter { x =>
filterSymbol(x)
}.flatMap {
case x if x.isValDef => Some(x)
// case reflect.IsValDefSymbol(x) => Some(x)
// case qctx.tasty.IsValDefSymbol(x) => Some(x)
case _ => None
}.map { x =>
convertToRepresentation(reflect)(x.tree, parentRepresentation)
convertToRepresentation(x.tree, parentRepresentation)
}
)
.flatMap{
Expand All @@ -98,12 +96,12 @@ trait TastyExtractor extends TastyTypeConverter with CommentParser with CommentC
.sortBy(_.name)
}

def extractParents(reflect: Reflection)(parents: List[reflect.Tree]): List[Reference] = {
import reflect.{given _, _}
def extractParents(using QuoteContext)(parents: List[qctx.tasty.Tree]): List[Reference] = {
import qctx.tasty._

val parentsReferences = parents.map{
case c: TypeTree => convertTypeToReference(reflect)(c.tpe)
case c: Term => convertTypeToReference(reflect)(c.tpe)
case c: TypeTree => convertTypeToReference(c.tpe)
case c: Term => convertTypeToReference(c.tpe)
case _ => throw Exception("Unhandeld case in parents. Please open an issue.")
}

Expand All @@ -117,12 +115,12 @@ trait TastyExtractor extends TastyTypeConverter with CommentParser with CommentC
*
* @return (is case, is a trait, is an object, the kind as a String)
*/
def extractKind(reflect: Reflection)(flags: reflect.Flags): (Boolean, Boolean, Boolean, String) = {
import reflect.{given _, _}
def extractKind(using QuoteContext)(flags: qctx.tasty.Flags): (Boolean, Boolean, Boolean, String) = {
import qctx.tasty._

val isCase = flags.is(reflect.Flags.Case)
val isTrait = flags.is(reflect.Flags.Trait)
val isObject = flags.is(reflect.Flags.Object)
val isCase = flags.is(Flags.Case)
val isTrait = flags.is(Flags.Trait)
val isObject = flags.is(Flags.Object)
val kind = {
if(isTrait){
"trait"
Expand All @@ -142,38 +140,38 @@ trait TastyExtractor extends TastyTypeConverter with CommentParser with CommentC
(isCase, isTrait, isObject, kind)
}

def extractCompanion(reflect: Reflection)(companionModule: Option[reflect.Symbol], companionClass: Option[reflect.Symbol], companionIsObject: Boolean): Option[CompanionReference] = {
import reflect.{given _, _}
def extractCompanion(using QuoteContext)(companionModule: Option[qctx.tasty.Symbol], companionClass: Option[qctx.tasty.Symbol], companionIsObject: Boolean): Option[CompanionReference] = {
import qctx.tasty._

if(companionIsObject){
companionModule match {
case Some(c) =>
val path = extractPath(reflect)(c)
val (_, _, _, kind) = extractKind(reflect)(c.flags)
val path = extractPath(c)
val (_, _, _, kind) = extractKind(c.flags)
Some(CompanionReference(c.name + "$", path.mkString("/", "/", ""), kind))
case None => None
}
}else{
companionClass match {
case Some(c) =>
val path = extractPath(reflect)(c)
val (_, _, _, kind) = extractKind(reflect)(c.flags)
val path = extractPath(c)
val (_, _, _, kind) = extractKind(c.flags)
Some(CompanionReference(c.name, path.mkString("/", "/", ""), kind))
case None => None
}
}
}

def extractAnnotations(reflect: Reflection)(annots: List[reflect.Term]): List[TypeReference] = {
import reflect.{given _, _}
def extractAnnotations(using QuoteContext)(annots: List[qctx.tasty.Term]): List[TypeReference] = {
import qctx.tasty._

def keepAnnot(label: String, link: String): Boolean = {
!(label == "SourceFile" && link == "/internal") &&
!(label == "Child" && link == "/internal")
}

annots.flatMap{a =>
convertTypeToReference(reflect)(a.tpe) match {
convertTypeToReference(a.tpe) match {
case ref@TypeReference(label, link, _, _) if keepAnnot(label, link) => Some(ref)
case _ => None
}
Expand Down
48 changes: 24 additions & 24 deletions tastydoc/src/dotty/tastydoc/TastyTypeConverter.scala
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package dotty.tastydoc

import scala.tasty.Reflection
import scala.quoted._
import dotty.tastydoc.references._

/** Trait containing methods for converting from Reflect types to References */
trait TastyTypeConverter {

def convertTypeOrBoundsToReference(reflect: Reflection)(typeOrBounds: reflect.TypeOrBounds): Reference = {
import reflect.{given _, _}
def convertTypeOrBoundsToReference(using QuoteContext)(typeOrBounds: qctx.tasty.TypeOrBounds): Reference = {
import qctx.tasty._

def anyOrNothing(reference: Reference): Boolean = reference match {
case TypeReference("Any", "/scala", _, _) => true
Expand All @@ -16,24 +16,24 @@ trait TastyTypeConverter {
}

typeOrBounds match {
case tpe: Type => convertTypeToReference(reflect)(tpe)
case tpe: Type => convertTypeToReference(tpe)
case TypeBounds(low, hi) =>
val lowRef = convertTypeToReference(reflect)(low)
val hiRef = convertTypeToReference(reflect)(hi)
val lowRef = convertTypeToReference(low)
val hiRef = convertTypeToReference(hi)
if(hiRef == lowRef){
hiRef
}else{
BoundsReference(lowRef, hiRef)
}
case reflect.NoPrefix() => EmptyReference
case NoPrefix() => EmptyReference
}
}

def convertTypeToReference(reflect: Reflection)(tp: reflect.Type): Reference = {
import reflect.{given _, _}
def convertTypeToReference(using QuoteContext)(tp: qctx.tasty.Type): Reference = {
import qctx.tasty._

//Inner method to avoid passing the reflection each time
def inner(tp: reflect.Type): Reference = tp match {
def inner(tp: Type): Reference = tp match {
case OrType(left, right) => OrTypeReference(inner(left), inner(right))
case AndType(left, right) => AndTypeReference(inner(left), inner(right))
case ByNameType(tpe) => ByNameReference(inner(tpe))
Expand All @@ -42,13 +42,13 @@ trait TastyTypeConverter {
case AnnotatedType(tpe, _) => inner(tpe)
case TypeLambda(paramNames, paramTypes, resType) => ConstantReference(tp.show) //TOFIX
case Refinement(parent, name, info) =>
val tuple = convertTypeOrBoundsToReference(reflect)(info) match {
val tuple = convertTypeOrBoundsToReference(info) match {
case r if (info match {case info: TypeBounds => true case _ => false}) => ("type", name, r)
case r@TypeReference(_, _, _, _) => ("val", name, r)
case ByNameReference(rChild) => ("def", name, rChild)
case r => throw new Exception("Match error in info of Refinement. This should not happen, please open an issue. " + r)
}
convertTypeToReference(reflect)(parent) match {
convertTypeToReference(parent) match {
case RefinedReference(p, ls) =>
RefinedReference(p, ls:+tuple)
case t => RefinedReference(t, List(tuple))
Expand All @@ -58,51 +58,51 @@ trait TastyTypeConverter {
case TypeReference(label, link, _, hasOwnFile) =>
if(link == "/scala"){
if(label.matches("Function[1-9]") || label.matches("Function[1-9][0-9]")){
val argsAndReturn = typeOrBoundsList.map(convertTypeOrBoundsToReference(reflect)(_))
val argsAndReturn = typeOrBoundsList.map(convertTypeOrBoundsToReference(_))
FunctionReference(argsAndReturn.take(argsAndReturn.size - 1), argsAndReturn.last, false)
}else if(label.matches("Tuple[1-9]") || label.matches("Tuple[1-9][0-9]")){
TupleReference(typeOrBoundsList.map(convertTypeOrBoundsToReference(reflect)(_)))
TupleReference(typeOrBoundsList.map(convertTypeOrBoundsToReference(_)))
}else{
TypeReference(label, link, typeOrBoundsList.map(convertTypeOrBoundsToReference(reflect)(_)), hasOwnFile)
TypeReference(label, link, typeOrBoundsList.map(convertTypeOrBoundsToReference(_)), hasOwnFile)
}
}else{
TypeReference(label, link, typeOrBoundsList.map(convertTypeOrBoundsToReference(reflect)(_)), hasOwnFile)
TypeReference(label, link, typeOrBoundsList.map(convertTypeOrBoundsToReference(_)), hasOwnFile)
}
case _ => throw Exception("Match error in AppliedType. This should not happen, please open an issue. " + tp)
}
case tp @ TypeRef(qual, typeName) =>
convertTypeOrBoundsToReference(reflect)(qual) match {
convertTypeOrBoundsToReference(qual) match {
case TypeReference(label, link, xs, _) => TypeReference(typeName, link + "/" + label, xs, true)
case EmptyReference => TypeReference(typeName, "", Nil, true)
case _ if tp.typeSymbol.exists =>
tp.typeSymbol match {
// NOTE: Only TypeRefs can reference ClassDefSymbols
case sym if sym.isClassDef => //Need to be split because these types have their own file
convertTypeOrBoundsToReference(reflect)(qual) match {
convertTypeOrBoundsToReference(qual) match {
case TypeReference(label, link, xs, _) => TypeReference(sym.name, link + "/" + label, xs, true)
case EmptyReference if sym.name == "<root>" | sym.name == "_root_" => EmptyReference
case EmptyReference => TypeReference(sym.name, "", Nil, true)
case _ => throw Exception("Match error in SymRef/TypeOrBounds/ClassDef. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(reflect)(qual))
case _ => throw Exception("Match error in SymRef/TypeOrBounds/ClassDef. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(qual))
}

// NOTE: This branch handles packages, which are now TypeRefs
case sym if sym.isTerm || sym.isTypeDef =>
convertTypeOrBoundsToReference(reflect)(qual) match {
convertTypeOrBoundsToReference(qual) match {
case TypeReference(label, link, xs, _) => TypeReference(sym.name, link + "/" + label, xs)
case EmptyReference if sym.name == "<root>" | sym.name == "_root_" => EmptyReference
case EmptyReference => TypeReference(sym.name, "", Nil)
case _ => throw Exception("Match error in SymRef/TypeOrBounds/Other. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(reflect)(qual))
case _ => throw Exception("Match error in SymRef/TypeOrBounds/Other. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(qual))
}
case sym => throw Exception("Match error in SymRef. This should not happen, please open an issue. " + sym)
}
case _ =>
throw Exception("Match error in TypeRef. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(reflect)(qual))
throw Exception("Match error in TypeRef. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(qual))
}
case TermRef(qual, typeName) =>
convertTypeOrBoundsToReference(reflect)(qual) match {
convertTypeOrBoundsToReference(qual) match {
case TypeReference(label, link, xs, _) => TypeReference(typeName + "$", link + "/" + label, xs)
case EmptyReference => TypeReference(typeName, "", Nil)
case _ => throw Exception("Match error in TermRef. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(reflect)(qual))
case _ => throw Exception("Match error in TermRef. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(qual))
}

// NOTE: old SymRefs are now either TypeRefs or TermRefs - the logic here needs to be moved into above branches
Expand Down
8 changes: 3 additions & 5 deletions tastydoc/src/dotty/tastydoc/TastydocInspector.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package dotty.tastydoc

import scala.tasty.Reflection
import scala.quoted._
import scala.tasty.inspector.TastyInspector

import dotty.tastydoc.representations._
Expand All @@ -11,9 +11,7 @@ import dotty.tastydoc.representations._
*/
class TastydocInspector(mutablePackagesMap: scala.collection.mutable.HashMap[String, EmulatedPackageRepresentation]) extends TastyInspector {

protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit = {
import reflect._

representations.convertToRepresentation(reflect)(root, None)(using mutablePackagesMap)
protected def processCompilationUnit(using QuoteContext)(root: qctx.tasty.Tree): Unit = {
representations.convertToRepresentation(root, None)(using mutablePackagesMap)
}
}
Loading