Skip to content

Commit 9481cf9

Browse files
committed
Add attributes section to TASTy
The `Attributes` section contains a list of UTF-8 string that represent the attributes.
1 parent 982c91b commit 9481cf9

File tree

8 files changed

+99
-12
lines changed

8 files changed

+99
-12
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package dotty.tools.dotc.core.tasty
2+
3+
import dotty.tools.dotc.ast.{tpd, untpd}
4+
5+
import dotty.tools.tasty.TastyBuffer
6+
import dotty.tools.tasty.TastyFormat.AttributesSection
7+
8+
import java.nio.charset.StandardCharsets
9+
10+
object AttributePickler:
11+
12+
def pickleAttributes(
13+
attributes: List[String],
14+
pickler: TastyPickler,
15+
buf: TastyBuffer): Unit =
16+
if attributes != Nil then
17+
pickler.newSection(AttributesSection, buf)
18+
for attribute <- attributes do
19+
val bytes = attribute.getBytes(StandardCharsets.UTF_8).nn
20+
val length = bytes.length
21+
buf.writeNat(length)
22+
buf.writeBytes(bytes, length)
23+
end pickleAttributes
24+
25+
end AttributePickler
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package dotty.tools.dotc
2+
package core.tasty
3+
4+
import scala.language.unsafeNulls
5+
6+
import dotty.tools.tasty.{TastyReader, TastyBuffer}
7+
8+
import java.nio.charset.StandardCharsets
9+
10+
class AttributeUnpickler(reader: TastyReader):
11+
import reader._
12+
13+
private[tasty] lazy val attributes: List[String] = {
14+
val attributesBuilder = List.newBuilder[String]
15+
while (!isAtEnd) {
16+
val length = readNat()
17+
if (length > 0) {
18+
val bytes = readBytes(length)
19+
val attribute = new String(bytes, StandardCharsets.UTF_8)
20+
attributesBuilder += attribute
21+
}
22+
}
23+
attributesBuilder.result()
24+
}
25+
26+
end AttributeUnpickler

compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ import Names.SimpleName
1313
import TreeUnpickler.UnpickleMode
1414

1515
import dotty.tools.tasty.TastyReader
16-
import dotty.tools.tasty.TastyFormat.{ASTsSection, PositionsSection, CommentsSection}
16+
import dotty.tools.tasty.TastyFormat.{ASTsSection, PositionsSection, CommentsSection, AttributesSection}
1717

1818
object DottyUnpickler {
1919

2020
/** Exception thrown if classfile is corrupted */
2121
class BadSignature(msg: String) extends RuntimeException(msg)
2222

23-
class TreeSectionUnpickler(posUnpickler: Option[PositionUnpickler], commentUnpickler: Option[CommentUnpickler])
23+
class TreeSectionUnpickler(posUnpickler: Option[PositionUnpickler], commentUnpickler: Option[CommentUnpickler], attributeUnpickler: Option[AttributeUnpickler])
2424
extends SectionUnpickler[TreeUnpickler](ASTsSection) {
2525
def unpickle(reader: TastyReader, nameAtRef: NameTable): TreeUnpickler =
26-
new TreeUnpickler(reader, nameAtRef, posUnpickler, commentUnpickler)
26+
new TreeUnpickler(reader, nameAtRef, posUnpickler, commentUnpickler, attributeUnpickler)
2727
}
2828

2929
class PositionsSectionUnpickler extends SectionUnpickler[PositionUnpickler](PositionsSection) {
@@ -35,6 +35,10 @@ object DottyUnpickler {
3535
def unpickle(reader: TastyReader, nameAtRef: NameTable): CommentUnpickler =
3636
new CommentUnpickler(reader)
3737
}
38+
class AttributesSectionUnpickler extends SectionUnpickler[AttributeUnpickler](AttributesSection) {
39+
def unpickle(reader: TastyReader, nameAtRef: NameTable): AttributeUnpickler =
40+
new AttributeUnpickler(reader)
41+
}
3842
}
3943

4044
/** A class for unpickling Tasty trees and symbols.
@@ -48,16 +52,21 @@ class DottyUnpickler(bytes: Array[Byte], mode: UnpickleMode = UnpickleMode.TopLe
4852
val unpickler: TastyUnpickler = new TastyUnpickler(bytes)
4953
private val posUnpicklerOpt = unpickler.unpickle(new PositionsSectionUnpickler)
5054
private val commentUnpicklerOpt = unpickler.unpickle(new CommentsSectionUnpickler)
51-
private val treeUnpickler = unpickler.unpickle(treeSectionUnpickler(posUnpicklerOpt, commentUnpicklerOpt)).get
55+
private val attributeUnpicklerOpt = unpickler.unpickle(new AttributesSectionUnpickler)
56+
private val treeUnpickler = unpickler.unpickle(treeSectionUnpickler(posUnpicklerOpt, commentUnpicklerOpt, attributeUnpicklerOpt)).get
5257

5358
/** Enter all toplevel classes and objects into their scopes
5459
* @param roots a set of SymDenotations that should be overwritten by unpickling
5560
*/
5661
def enter(roots: Set[SymDenotation])(using Context): Unit =
5762
treeUnpickler.enter(roots)
5863

59-
protected def treeSectionUnpickler(posUnpicklerOpt: Option[PositionUnpickler], commentUnpicklerOpt: Option[CommentUnpickler]): TreeSectionUnpickler =
60-
new TreeSectionUnpickler(posUnpicklerOpt, commentUnpicklerOpt)
64+
protected def treeSectionUnpickler(
65+
posUnpicklerOpt: Option[PositionUnpickler],
66+
commentUnpicklerOpt: Option[CommentUnpickler],
67+
attributeUnpicklerOpt: Option[AttributeUnpickler]
68+
): TreeSectionUnpickler =
69+
new TreeSectionUnpickler(posUnpicklerOpt, commentUnpicklerOpt, attributeUnpicklerOpt)
6170

6271
protected def computeRootTrees(using Context): List[Tree] = treeUnpickler.unpickle(mode)
6372

compiler/src/dotty/tools/dotc/core/tasty/ScratchData.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ class ScratchData:
1010
val pickledIndices = new mutable.BitSet
1111

1212
val commentBuffer = new TastyBuffer(5000)
13+
val attributeBuffer = new TastyBuffer(128)
1314

1415
def reset() =
1516
assert(delta ne delta1)
1617
assert(delta.length == delta1.length)
1718
positionBuffer.reset()
1819
pickledIndices.clear()
1920
commentBuffer.reset()
21+
attributeBuffer.reset()
2022

compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Contexts._, Decorators._
99
import Names.Name
1010
import TastyUnpickler._
1111
import util.Spans.offsetToInt
12-
import dotty.tools.tasty.TastyFormat.{ASTsSection, PositionsSection, CommentsSection}
12+
import dotty.tools.tasty.TastyFormat.{ASTsSection, PositionsSection, CommentsSection, AttributesSection}
1313
import java.nio.file.{Files, Paths}
1414
import dotty.tools.io.{JarArchive, Path}
1515

@@ -84,14 +84,16 @@ class TastyPrinter(bytes: Array[Byte]) {
8484
case Some(s) => sb.append(s)
8585
case _ =>
8686
}
87-
sb.append("\n\n")
8887
unpickle(new PositionSectionUnpickler) match {
89-
case Some(s) => sb.append(s)
88+
case Some(s) => sb.append("\n\n").append(s)
9089
case _ =>
9190
}
92-
sb.append("\n\n")
9391
unpickle(new CommentSectionUnpickler) match {
94-
case Some(s) => sb.append(s)
92+
case Some(s) => sb.append("\n\n").append(s)
93+
case _ =>
94+
}
95+
unpickle(new AttributesSectionUnpickler) match {
96+
case Some(s) => sb.append("\n\n").append(s)
9597
case _ =>
9698
}
9799
sb.result
@@ -222,6 +224,20 @@ class TastyPrinter(bytes: Array[Byte]) {
222224
}
223225
}
224226

227+
class AttributesSectionUnpickler extends SectionUnpickler[String](AttributesSection) {
228+
229+
private val sb: StringBuilder = new StringBuilder
230+
231+
def unpickle(reader: TastyReader, tastyName: NameTable): String = {
232+
sb.append(s" ${reader.endAddr.index - reader.currentAddr.index}")
233+
val attributes = new AttributeUnpickler(reader).attributes
234+
sb.append(s" attributes bytes:\n")
235+
for attribute <- attributes do
236+
sb.append(" ").append(attribute).append("\n")
237+
sb.result
238+
}
239+
}
240+
225241
protected def nameStr(str: String): String = str
226242
protected def treeStr(str: String): String = str
227243
protected def lengthStr(str: String): String = str

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,13 @@ import scala.annotation.internal.sharable
5252
* @param reader the reader from which to unpickle
5353
* @param posUnpicklerOpt the unpickler for positions, if it exists
5454
* @param commentUnpicklerOpt the unpickler for comments, if it exists
55+
* @param attributeUnpicklerOpt the unpickler for attributes, if it exists
5556
*/
5657
class TreeUnpickler(reader: TastyReader,
5758
nameAtRef: NameTable,
5859
posUnpicklerOpt: Option[PositionUnpickler],
59-
commentUnpicklerOpt: Option[CommentUnpickler]) {
60+
commentUnpicklerOpt: Option[CommentUnpickler],
61+
attributeUnpicklerOpt: Option[AttributeUnpickler]) {
6062
import TreeUnpickler._
6163
import tpd._
6264

compiler/src/dotty/tools/dotc/transform/Pickler.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ class Pickler extends Phase {
108108
pickler, treePkl.buf.addrOfTree, treePkl.docString, tree,
109109
scratch.commentBuffer)
110110

111+
val attributes = Nil // TODO add attributes here
112+
AttributePickler.pickleAttributes(attributes, pickler, scratch.attributeBuffer)
113+
111114
val pickled = pickler.assembleParts()
112115

113116
def rawBytes = // not needed right now, but useful to print raw format.

tasty/src/dotty/tools/tasty/TastyFormat.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,9 @@ Standard Section: "Comments" Comment*
267267
```none
268268
Comment = Length Bytes LongInt // Raw comment's bytes encoded as UTF-8, followed by the comment's coordinates.
269269
```
270+
271+
Standard Section: "Attributes" UTF8*
272+
270273
**************************************************************************************/
271274

272275
object TastyFormat {
@@ -361,6 +364,7 @@ object TastyFormat {
361364
final val ASTsSection = "ASTs"
362365
final val PositionsSection = "Positions"
363366
final val CommentsSection = "Comments"
367+
final val AttributesSection = "Attributes"
364368

365369
/** Tags used to serialize names, should update [[TastyFormat$.nameTagToString]] if a new constant is added */
366370
class NameTags {

0 commit comments

Comments
 (0)