Skip to content

Commit 830cdb1

Browse files
committed
Get name by reading the TASTy tree
1 parent 4e6adcf commit 830cdb1

File tree

3 files changed

+79
-18
lines changed

3 files changed

+79
-18
lines changed

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,14 @@ class Driver {
142142
val (classPaths, classNames) = fileNames0.map { name =>
143143
val path = Paths.get(name)
144144
if (!name.endsWith(".tasty")) ("", name)
145-
else if (Files.exists(path)) TastyFileUtil.getClassName(path)
146-
else {
145+
else if (Files.exists(path)) {
146+
TastyFileUtil.getClassName(path) match {
147+
case Some(res) => res
148+
case _ =>
149+
ctx0.error(s"Could not load classname from $name.")
150+
("", name)
151+
}
152+
} else {
147153
ctx0.error(s"File $name does not exist.")
148154
("", name)
149155
}
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: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
package dotty.tools.dotc.fromtasty
1+
package dotty.tools.dotc
2+
package fromtasty
23

34
import java.nio.file.{Files, Path, Paths}
5+
import java.io
46

57
import dotty.tools.dotc.core.Contexts.Context
68
import dotty.tools.dotc.core.NameKinds
@@ -17,25 +19,20 @@ object TastyFileUtil {
1719
* package foo
1820
* class Foo
1921
* ```
20-
* then `getClassName("./out/foo/Foo.tasty") returns `("./out", "foo.Foo")`
22+
* then `getClassName("./out/foo/Foo.tasty") returns `Some(("./out", "foo.Foo"))`
2123
*/
22-
def getClassName(path: Path): (String, String) = {
24+
def getClassName(path: Path): Option[(String, String)] = {
2325
assert(path.toString.endsWith(".tasty"))
2426
assert(Files.exists(path))
2527
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("."))
28+
val names = new core.tasty.TastyClassName(bytes).readName()
29+
names.map { case (packName, className) =>
30+
val fullName = s"$packName.${className.lastPart}"
31+
val classInPath = fullName.replace(".", io.File.separator) + ".tasty"
32+
val classpath = path.toString.replace(classInPath, "")
33+
(classpath, fullName)
34+
}
35+
3936
}
4037

4138
}

0 commit comments

Comments
 (0)