Skip to content

Commit f4ada7d

Browse files
committed
Get name by reading the TASTy tree
1 parent ffa2fe1 commit f4ada7d

File tree

3 files changed

+78
-18
lines changed

3 files changed

+78
-18
lines changed

compiler/src/dotty/tools/dotc/Driver.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,14 @@ class Driver {
139139
val (classPaths, classNames) = fileNames0.map { name =>
140140
val path = Paths.get(name)
141141
if (!name.endsWith(".tasty")) ("", name)
142-
else if (Files.exists(path)) TastyFileUtil.getClassName(path)
143-
else {
142+
else if (Files.exists(path)) {
143+
TastyFileUtil.getClassName(path) match {
144+
case Some(res) => res
145+
case _ =>
146+
ctx0.error(s"Could not load classname from $name.")
147+
("", name)
148+
}
149+
} else {
144150
ctx0.error(s"File $name does not exist.")
145151
("", name)
146152
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package dotty.tools.dotc
2+
package core
3+
package tasty
4+
5+
import Contexts._, Decorators._
6+
import Names.{Name, TermName}
7+
import StdNames.nme
8+
import TastyUnpickler._
9+
import TastyBuffer.NameRef
10+
import util.Positions.offsetToInt
11+
import printing.Highlighting._
12+
13+
/** Reads the package and class name of the class contained in this TASTy */
14+
class TastyClassName(bytes: Array[Byte]) {
15+
16+
val unpickler: TastyUnpickler = new TastyUnpickler(bytes)
17+
import unpickler.{nameAtRef, unpickle}
18+
19+
/** Returns a tuple with the package and class names */
20+
def readName(): Option[(TermName, TermName)] = unpickle(new TreeSectionUnpickler)
21+
22+
class TreeSectionUnpickler extends SectionUnpickler[(TermName, TermName)](TreePickler.sectionName) {
23+
import TastyFormat._
24+
def unpickle(reader: TastyReader, tastyName: NameTable): (TermName, TermName) = {
25+
import reader._
26+
def readName() = {
27+
val idx = readNat()
28+
nameAtRef(NameRef(idx))
29+
}
30+
def readNames(pack: TermName): (TermName, TermName) = {
31+
val tag = readByte()
32+
if (tag >= firstLengthTreeTag) {
33+
val len = readNat()
34+
val end = currentAddr + len
35+
tag match {
36+
case TYPEDEF =>
37+
val name = readName()
38+
goto(end)
39+
(pack, name)
40+
case IMPORT | VALDEF =>
41+
goto(end)
42+
readNames(pack)
43+
case PACKAGE =>
44+
readNames(pack)
45+
}
46+
}
47+
else tag match {
48+
case TERMREFpkg | TYPEREFpkg =>
49+
val packName = readName()
50+
readNames(packName)
51+
case _ =>
52+
readNames(pack)
53+
}
54+
}
55+
readNames(nme.EMPTY_PACKAGE)
56+
}
57+
}
58+
}
Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
package dotty.tools.dotc.fromtasty
1+
package dotty.tools.dotc
2+
package fromtasty
23

34
import java.nio.file.{Files, Path, Paths}
45

@@ -17,25 +18,20 @@ object TastyFileUtil {
1718
* package foo
1819
* class Foo
1920
* ```
20-
* then `getClassName("./out/foo/Foo.tasty") returns `("./out", "foo.Foo")`
21+
* then `getClassName("./out/foo/Foo.tasty") returns `Some(("./out", "foo.Foo"))`
2122
*/
22-
def getClassName(path: Path): (String, String) = {
23+
def getClassName(path: Path): Option[(String, String)] = {
2324
assert(path.toString.endsWith(".tasty"))
2425
assert(Files.exists(path))
2526
val bytes = Files.readAllBytes(path)
26-
val unpickler: TastyUnpickler = new TastyUnpickler(bytes)
27-
val className =
28-
unpickler.nameAtRef.contents.iterator.dropWhile {
29-
name => name.toString == TreePickler.sectionName || name == nme.EMPTY_PACKAGE
30-
}.takeWhile {
31-
case name: SimpleName => name != nme.CONSTRUCTOR
32-
case name => !name.is(NameKinds.ModuleClassName)
33-
}.collect {
34-
case name: SimpleName => name.toString
35-
}.toList
36-
val classInPath = className.mkString("", "/", ".tasty")
37-
val classpath = path.toString.replace(classInPath, "")
38-
(classpath, className.mkString("."))
27+
val names = new core.tasty.TastyClassName(bytes).readName()
28+
names.map { case (packName, className) =>
29+
val fullName = s"$packName.${className.lastPart}"
30+
val classInPath = fullName.replace(".", "/") + ".tasty"
31+
val classpath = path.toString.replace(classInPath, "")
32+
(classpath, fullName)
33+
}
34+
3935
}
4036

4137
}

0 commit comments

Comments
 (0)