Skip to content

Commit 1941191

Browse files
committed
refactor reading a member by name, enabling dotty java enums
1 parent ddc74b5 commit 1941191

File tree

11 files changed

+252
-256
lines changed

11 files changed

+252
-256
lines changed

src/compiler/scala/tools/nsc/tasty/Names.scala

Lines changed: 0 additions & 157 deletions
This file was deleted.

src/compiler/scala/tools/nsc/tasty/ScalacUnpickler.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package scala.tools.nsc.tasty
22

33
import TastyUnpickler.SectionUnpickler
44
import TastyRefs.NameRef
5-
import Names.TastyName
65

76
import scala.reflect.io.AbstractFile
87
import scala.util.control.NonFatal
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
package scala.tools.nsc.tasty
2+
3+
import scala.reflect.NameTransformer
4+
5+
object TastyName {
6+
7+
// TODO [tasty]: cache chars for Names. SimpleName acts as a cursor
8+
9+
final case class SimpleName(raw: String) extends TastyName
10+
final case class ModuleName(base: TastyName) extends TastyName
11+
final case class QualifiedName(qual: TastyName, sep: SimpleName, selector: SimpleName) extends TastyName
12+
final case class SignedName(qual: TastyName, sig: Signature.MethodSignature[TastyName]) extends TastyName
13+
final case class UniqueName(qual: TastyName, sep: SimpleName, num: Int) extends TastyName
14+
final case class DefaultName(qual: TastyName, num: Int) extends TastyName
15+
final case class PrefixName(prefix: SimpleName, qual: TastyName) extends TastyName
16+
17+
final val Empty: SimpleName = SimpleName("")
18+
final val PathSep: SimpleName = SimpleName(".")
19+
final val ExpandedSep: SimpleName = SimpleName("$$")
20+
final val ExpandPrefixSep: SimpleName = SimpleName("$")
21+
final val WildcardSep: SimpleName = SimpleName("_$")
22+
final val InlinePrefix: SimpleName = SimpleName("inline$")
23+
final val SuperPrefix: SimpleName = SimpleName("super$")
24+
final val Constructor: SimpleName = SimpleName("<init>")
25+
final val EmptyPkg: SimpleName = SimpleName("<empty>")
26+
final val RootClass: SimpleName = SimpleName("<root>")
27+
28+
object WildcardName {
29+
def unapply(name: TastyName): Boolean = name match {
30+
case UniqueName(Empty, WildcardSep, _) => true
31+
case _ => false
32+
}
33+
}
34+
35+
final val DefaultGetterStr = "$default$"
36+
final val DefaultGetterInitStr = NameTransformer.encode("<init>") + DefaultGetterStr
37+
38+
trait NameEncoder[U] {
39+
final def encode[O](name: TastyName)(init: => U, finish: U => O): O = finish(traverse(init, name))
40+
def traverse(u: U, name: TastyName): U
41+
}
42+
43+
trait StringBuilderEncoder extends NameEncoder[StringBuilder] {
44+
final def encode(name: TastyName): String = name match {
45+
case SimpleName(raw) => raw
46+
case _ => super.encode(name)(new StringBuilder(25), _.toString)
47+
}
48+
}
49+
50+
/** Converts a name to a representation closest to source code.
51+
*/
52+
object SourceEncoder extends StringBuilderEncoder {
53+
def traverse(sb: StringBuilder, name: TastyName): StringBuilder = name match {
54+
case name: SimpleName => sb.append(name.raw)
55+
case name: ModuleName => traverse(sb, name.base)
56+
case name: SignedName => traverse(sb, name.qual)
57+
case name: UniqueName => traverse(traverse(sb, name.qual), name.sep).append(name.num)
58+
case name: DefaultName => traverse(sb, name.qual).append(DefaultGetterStr).append(name.num + 1)
59+
case name: QualifiedName => traverse(traverse(traverse(sb, name.qual), name.sep), name.selector)
60+
case name: PrefixName => traverse(traverse(sb, name.prefix), name.qual)
61+
}
62+
}
63+
64+
/** Displays formatted information about the structure of the name
65+
*/
66+
object DebugEncoder extends StringBuilderEncoder {
67+
68+
def traverse(sb: StringBuilder, name: TastyName): StringBuilder = name match {
69+
70+
case SimpleName(raw) => sb.append(raw)
71+
case DefaultName(qual, num) => traverse(sb, qual).append("[Default ").append(num + 1).append(']')
72+
case PrefixName(prefix, qual) => traverse(traverse(sb, qual).append("[Prefix "), prefix).append(']')
73+
case ModuleName(name) => traverse(sb, name).append("[ModuleClass]")
74+
case SignedName(name,sig) => sig.map(_.debug).mergeShow(traverse(sb, name).append("[Signed ")).append(']')
75+
76+
case QualifiedName(qual, sep, name) =>
77+
traverse(traverse(traverse(sb, qual).append("[Qualified "), sep).append(' '), name).append(']')
78+
79+
case UniqueName(qual, sep, num) =>
80+
traverse(traverse(sb, qual).append("[Unique "), sep).append(' ').append(num).append(']')
81+
82+
}
83+
84+
}
85+
86+
/** Encodes names as expected by the Scala Reflect SymbolTable
87+
*/
88+
object ScalaNameEncoder extends NameEncoder[StringBuilder] {
89+
90+
final def encode(name: TastyName): String = name match {
91+
case SimpleName(raw) => escapeSimple(raw)
92+
case _ => super.encode(name)(new StringBuilder(25), _.toString)
93+
}
94+
95+
final def escapeSimple(raw: String) = raw match {
96+
case raw @ ("<init>" | "<empty>" | "<root>") => raw
97+
case raw => NameTransformer.encode(raw)
98+
}
99+
100+
def traverse(sb: StringBuilder, name: TastyName): StringBuilder = name match {
101+
case name: SimpleName => sb.append(escapeSimple(name.raw))
102+
case name: ModuleName => traverse(sb, name.base)
103+
case name: SignedName => traverse(sb, name.qual)
104+
case name: UniqueName => traverse(sb, name.qual).append(name.sep.raw).append(name.num)
105+
case name: QualifiedName => traverse(traverse(sb, name.qual).append(name.sep.raw), name.selector)
106+
case name: PrefixName => traverse(sb.append(name.prefix), name.qual)
107+
108+
case name: DefaultName if name.qual == Constructor => sb.append(DefaultGetterInitStr).append(name.num + 1)
109+
110+
case name: DefaultName => traverse(sb, name.qual).append(DefaultGetterStr).append(name.num + 1)
111+
}
112+
113+
}
114+
115+
}
116+
117+
/** class to represent Names as defined in TASTy, with methods to extract scala identifiers
118+
*/
119+
sealed trait TastyName extends Product with Serializable { self =>
120+
import TastyName._
121+
122+
final override def toString: String = source
123+
124+
final def isModuleName: Boolean = self.isInstanceOf[ModuleName]
125+
final def isDefaultName: Boolean = self.isInstanceOf[DefaultName]
126+
127+
final def asSimpleName: SimpleName = self match {
128+
case self: SimpleName => self
129+
case _ => throw new AssertionError(s"not simplename: ${self.debug}")
130+
}
131+
132+
/** The name as as expected by the Scala Reflect SymbolTable
133+
*/
134+
final def encoded: String = ScalaNameEncoder.encode(self)
135+
136+
/** The name as represented in source code
137+
*/
138+
final def source: String = SourceEncoder.encode(self)
139+
140+
/** Debug information about the structure of the name.
141+
*/
142+
final def debug: String = DebugEncoder.encode(self)
143+
144+
final def stripModulePart: TastyName = self match {
145+
case ModuleName(name) => name
146+
case name => name
147+
}
148+
149+
final def signature: Signature[TastyName] = self match {
150+
case SignedName(_, signature) => signature
151+
case _ => Signature.NotAMethod
152+
}
153+
154+
}

src/compiler/scala/tools/nsc/tasty/TastyUnpickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import scala.collection.mutable
44

55
import TastyFormat.NameTags._
66
import TastyRefs.NameRef
7-
import Names.TastyName, Names.TastyName._
7+
import TastyName._
88

99
object TastyUnpickler {
1010
class UnpickleException(msg: String) extends RuntimeException(msg)

0 commit comments

Comments
 (0)