Skip to content

Commit 1a7144a

Browse files
authored
Merge pull request #4579 from dotty-staging/tasty-decompiler
Implement decompiler on Tasty
2 parents 3ed7421 + 88cb137 commit 1a7144a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+984
-217
lines changed

compiler/src/dotty/tools/dotc/decompiler/DecompilationPrinter.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import dotty.tools.dotc.core.Contexts._
77
import dotty.tools.dotc.core.Phases.Phase
88
import dotty.tools.dotc.core.tasty.TastyPrinter
99
import dotty.tools.dotc.printing.DecompilerPrinter
10+
import dotty.tools.dotc.tastyreflect.TastyImpl
1011
import dotty.tools.io.{File, Path}
1112

1213
/** Phase that prints the trees in all loaded compilation units.
@@ -36,15 +37,11 @@ class DecompilationPrinter extends Phase {
3637

3738
private def printToOutput(out: PrintStream)(implicit ctx: Context): Unit = {
3839
val unit = ctx.compilationUnit
39-
val pageWidth = ctx.settings.pageWidth.value
40-
val printLines = ctx.settings.printLines.value
41-
4240
if (ctx.settings.printTasty.value) {
4341
new TastyPrinter(unit.pickled.head._2).printContents()
4442
} else {
4543
out.println(s"/** Decompiled from $unit */")
46-
val printer = new DecompilerPrinter(ctx)
47-
out.println(printer.toText(unit.tpdTree).mkString(pageWidth, printLines))
44+
out.print(TastyImpl.showSourceCode.showTree(unit.tpdTree)(ctx))
4845
}
4946
}
5047
}

compiler/src/dotty/tools/dotc/quoted/QuoteDriver.scala

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@ import dotty.tools.dotc.Driver
55
import dotty.tools.dotc.core.Contexts.Context
66
import dotty.tools.io.{AbstractFile, Directory, PlainDirectory, VirtualDirectory}
77
import dotty.tools.repl.AbstractFileClassLoader
8-
import dotty.tools.dotc.printing.DecompilerPrinter
98

109
import scala.quoted.{Expr, Type}
11-
1210
import java.net.URLClassLoader
1311

14-
import Toolbox.{Settings, Run, Show}
12+
import Toolbox.{Run, Settings, Show}
13+
import dotty.tools.dotc.tastyreflect.TastyImpl
1514

1615
class QuoteDriver extends Driver {
1716
import tpd._
@@ -42,10 +41,8 @@ class QuoteDriver extends Driver {
4241

4342
def show(expr: Expr[_], settings: Settings[Show]): String = {
4443
def show(tree: Tree, ctx: Context): String = {
45-
val printer = new DecompilerPrinter(ctx)
46-
val pageWidth = ctx.settings.pageWidth.value(ctx)
4744
val tree1 = if (settings.rawTree) tree else (new TreeCleaner).transform(tree)(ctx)
48-
printer.toText(tree1).mkString(pageWidth, false)
45+
TastyImpl.showSourceCode.showTree(tree1)(ctx)
4946
}
5047
withTree(expr, show, settings)
5148
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class FlagSet(flags: Flags.FlagSet) extends scala.tasty.FlagSet {
3131
def isScala2X: Boolean = flags.is(Scala2x)
3232
def isDefaultParameterized: Boolean = flags.is(DefaultParameterized)
3333
def isStable: Boolean = flags.is(Stable)
34+
def isParam: Boolean = flags.is(Param)
35+
def isParamAccessor: Boolean = flags.is(ParamAccessor)
3436

3537
override def toString: String = {
3638
val flags = List.newBuilder[String]
@@ -60,6 +62,8 @@ class FlagSet(flags: Flags.FlagSet) extends scala.tasty.FlagSet {
6062
if (isScala2X) flags += "scala2x"
6163
if (isDefaultParameterized) flags += "defaultParameterized"
6264
if (isStable) flags += "stable"
65+
if (isParam) flags += "param"
66+
if (isParamAccessor) flags += "paramAccessor"
6367
flags.result().mkString("<", ",", ">")
6468
}
6569

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ object FromSymbol {
2020
def packageDef(sym: Symbol)(implicit ctx: Context): PackageDefinition = PackageDefinitionImpl(sym)
2121

2222
def classDef(cls: ClassSymbol)(implicit ctx: Context): tpd.Tree = {
23-
val constr = tpd.DefDef(cls.unforcedDecls.find(_.isPrimaryConstructor).asTerm)
23+
val constrSym = cls.unforcedDecls.find(_.isPrimaryConstructor)
24+
if (!constrSym.exists) return tpd.EmptyTree
25+
val constr = tpd.DefDef(constrSym.asTerm)
2426
val body = cls.unforcedDecls.filter(!_.isPrimaryConstructor).map(s => definition(s))
2527
val superArgs = Nil // TODO
2628
tpd.ClassDef(cls, constr, body, superArgs)

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import dotty.tools.dotc.reporting.Reporter
1111
import dotty.tools.dotc.reporting.diagnostic.MessageContainer
1212
import dotty.tools.dotc.util.SourcePosition
1313

14-
import scala.quoted
14+
import scala.{quoted, tasty}
1515
import scala.reflect.ClassTag
16-
import scala.tasty.util.{Show, ShowExtractors}
16+
import scala.tasty.util.{Show, ShowExtractors, ShowSourceCode}
1717

1818
object TastyImpl extends scala.tasty.Tasty {
1919

@@ -33,8 +33,7 @@ object TastyImpl extends scala.tasty.Tasty {
3333

3434
def showExtractors: Show[this.type] = new ShowExtractors(this)
3535

36-
// TODO
37-
// def showSourceCode: Show[this.type] = ???
36+
def showSourceCode: Show[this.type] = new ShowSourceCode(this)
3837

3938
// ===== Contexts =================================================
4039

@@ -129,10 +128,18 @@ object TastyImpl extends scala.tasty.Tasty {
129128

130129
type Definition = tpd.Tree
131130

131+
object Definition extends DefinitionExtractor {
132+
def unapply(x: Definition)(implicit ctx: Context): Boolean =
133+
x.isInstanceOf[Trees.MemberDef[_]]
134+
}
135+
132136
def DefinitionDeco(x: Definition): AbstractDefinition = new AbstractDefinition {
133137

134138
def owner(implicit ctx: Context): Definition = FromSymbol.definition(x.symbol.owner)
135139

140+
def flags(implicit ctx: Contexts.Context): FlagSet =
141+
new FlagSet(x.symbol.flags)
142+
136143
def mods(implicit ctx: Context): List[Modifier] = {
137144
val privateWithin = x.symbol.privateWithin
138145
val isProtected = x.symbol.is(core.Flags.Protected)

compiler/test/dotty/tools/dotc/FromTastyTests.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ class FromTastyTests extends ParallelTesting {
3838
"t3612.scala",
3939
),
4040
recompilationBlacklist = Set(
41-
"simpleCaseObject"
41+
"simpleCaseObject",
42+
"annot-bootstrap.scala",
4243
)
4344
).checkCompile()
4445
}

library/src/scala/tasty/FlagSet.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ trait FlagSet {
2727
def isScala2X: Boolean // Imported from Scala2.x
2828
def isDefaultParameterized: Boolean // Method with default parameters
2929
def isStable: Boolean // Method that is assumed to be stable
30+
def isParam: Boolean
31+
def isParamAccessor: Boolean
3032
}

library/src/scala/tasty/Tasty.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ abstract class Tasty { tasty =>
2323

2424
def showExtractors: Show[tasty.type]
2525

26-
// TODO
27-
// def showSourceCode: Show[tasty.type]
26+
def showSourceCode: Show[tasty.type]
2827

2928
// ===== Contexts =================================================
3029

@@ -108,9 +107,15 @@ abstract class Tasty { tasty =>
108107

109108
type Definition <: Statement
110109

110+
val Definition: DefinitionExtractor
111+
abstract class DefinitionExtractor {
112+
def unapply(x: Definition)(implicit ctx: Context): Boolean
113+
}
114+
111115
implicit def definitionClassTag: ClassTag[Definition]
112116

113117
trait AbstractDefinition {
118+
def flags(implicit ctx: Context): FlagSet
114119
def mods(implicit ctx: Context): List[Modifier]
115120
def owner(implicit ctx: Context): Definition
116121
def localContext(implicit ctx: Context): Context

0 commit comments

Comments
 (0)