@@ -24,10 +24,9 @@ import ast.desugar
24
24
25
25
import parsing .JavaParsers .OutlineJavaParser
26
26
import parsing .Parsers .OutlineParser
27
- import dotty .tools .tasty .{TastyHeaderUnpickler , UnpickleException , UnpicklerConfig }
27
+ import dotty .tools .tasty .{TastyHeaderUnpickler , UnpickleException , UnpicklerConfig , TastyVersion }
28
28
import dotty .tools .dotc .core .tasty .TastyUnpickler
29
29
30
-
31
30
object SymbolLoaders {
32
31
import ast .untpd .*
33
32
@@ -52,7 +51,7 @@ object SymbolLoaders {
52
51
def enterClass (
53
52
owner : Symbol , name : PreName , completer : SymbolLoader ,
54
53
flags : FlagSet = EmptyFlags , scope : Scope = EmptyScope )(using Context ): Symbol = {
55
- val cls = newClassSymbol(owner, name.toTypeName.unmangleClassName.decode, flags, completer, assocFile = completer.sourceFileOrNull )
54
+ val cls = newClassSymbol(owner, name.toTypeName.unmangleClassName.decode, flags, completer, compUnitInfo = completer.compilationUnitInfo )
56
55
enterNew(owner, cls, completer, scope)
57
56
}
58
57
@@ -64,7 +63,7 @@ object SymbolLoaders {
64
63
val module = newModuleSymbol(
65
64
owner, name.toTermName.decode, modFlags, clsFlags,
66
65
(module, _) => completer.proxy.withDecls(newScope).withSourceModule(module),
67
- assocFile = completer.sourceFileOrNull )
66
+ compUnitInfo = completer.compilationUnitInfo )
68
67
enterNew(owner, module, completer, scope)
69
68
enterNew(owner, module.moduleClass, completer, scope)
70
69
}
@@ -213,7 +212,7 @@ object SymbolLoaders {
213
212
/** Load contents of a package
214
213
*/
215
214
class PackageLoader (_sourceModule : TermSymbol , classPath : ClassPath ) extends SymbolLoader {
216
- override def sourceFileOrNull : AbstractFile | Null = null
215
+ def compilationUnitInfo : CompilationUnitInfo | Null = null
217
216
override def sourceModule (using Context ): TermSymbol = _sourceModule
218
217
def description (using Context ): String = " package loader " + sourceModule.fullName
219
218
@@ -317,7 +316,7 @@ abstract class SymbolLoader extends LazyType { self =>
317
316
/** Load source or class file for `root`, return */
318
317
def doComplete (root : SymDenotation )(using Context ): Unit
319
318
320
- def sourceFileOrNull : AbstractFile | Null
319
+ def compilationUnitInfo : CompilationUnitInfo | Null
321
320
322
321
/** Description of the resource (ClassPath, AbstractFile)
323
322
* being processed by this loader
@@ -328,7 +327,7 @@ abstract class SymbolLoader extends LazyType { self =>
328
327
* but provides fresh slots for scope/sourceModule/moduleClass
329
328
*/
330
329
def proxy : SymbolLoader = new SymbolLoader {
331
- export self .{doComplete , sourceFileOrNull }
330
+ export self .{doComplete , compilationUnitInfo }
332
331
def description (using Context ): String = s " proxy to ${self.description}"
333
332
}
334
333
@@ -405,7 +404,8 @@ abstract class SymbolLoader extends LazyType { self =>
405
404
406
405
class ClassfileLoader (val classfile : AbstractFile ) extends SymbolLoader {
407
406
408
- override def sourceFileOrNull : AbstractFile | Null = classfile
407
+ def compilationUnitInfo : CompilationUnitInfo | Null = CompilationUnitInfo (classfile)
408
+
409
409
410
410
def description (using Context ): String = " class file " + classfile.toString
411
411
@@ -417,38 +417,55 @@ class ClassfileLoader(val classfile: AbstractFile) extends SymbolLoader {
417
417
418
418
class TastyLoader (val tastyFile : AbstractFile ) extends SymbolLoader {
419
419
420
- override def sourceFileOrNull : AbstractFile | Null = tastyFile
420
+ private val unpickler : tasty.DottyUnpickler =
421
+ handleUnpicklingExceptions :
422
+ val tastyBytes = tastyFile.toByteArray
423
+ new tasty.DottyUnpickler (tastyBytes) // reads header and name table
424
+
425
+ val compilationUnitInfo : CompilationUnitInfo | Null =
426
+ val tastyHeader = unpickler.unpickler.header
427
+ val tastyVersion = TastyVersion (
428
+ tastyHeader.majorVersion,
429
+ tastyHeader.minorVersion,
430
+ tastyHeader.experimentalVersion,
431
+ )
432
+ val attributes = unpickler.tastyAttributes
433
+ new CompilationUnitInfo (
434
+ tastyFile,
435
+ tastyVersion = Some (tastyVersion),
436
+ explicitNulls = attributes.explicitNulls,
437
+ )
421
438
422
439
def description (using Context ): String = " TASTy file " + tastyFile.toString
423
440
424
441
override def doComplete (root : SymDenotation )(using Context ): Unit =
425
- try
442
+ handleUnpicklingExceptions :
443
+ checkTastyUUID()
426
444
val (classRoot, moduleRoot) = rootDenots(root.asClass)
427
- val tastyBytes = tastyFile.toByteArray
428
- val unpickler = new tasty.DottyUnpickler (tastyBytes)
429
445
unpickler.enter(roots = Set (classRoot, moduleRoot, moduleRoot.sourceModule))(using ctx.withSource(util.NoSource ))
430
446
if mayLoadTreesFromTasty then
431
447
classRoot.classSymbol.rootTreeOrProvider = unpickler
432
448
moduleRoot.classSymbol.rootTreeOrProvider = unpickler
433
- checkTastyUUID(tastyFile, tastyBytes)
449
+
450
+ private def handleUnpicklingExceptions [T ](thunk : => T ): T =
451
+ try thunk
434
452
catch case e : RuntimeException =>
435
453
val message = e match
436
454
case e : UnpickleException =>
437
- i """ TASTy file ${tastyFile.canonicalPath} could not be read, failing with:
438
- | ${Option (e.getMessage).getOrElse(" " )}"""
455
+ s """ TASTy file ${tastyFile.canonicalPath} could not be read, failing with:
456
+ | ${Option (e.getMessage).getOrElse(" " )}""" .stripMargin
439
457
case _ =>
440
- i """ TASTy file ${tastyFile.canonicalPath} is broken, reading aborted with ${e.getClass}
441
- | ${Option (e.getMessage).getOrElse(" " )}"""
442
- if (ctx.debug) e.printStackTrace()
443
- throw IOException (message)
458
+ s """ TASTy file ${tastyFile.canonicalPath} is broken, reading aborted with ${e.getClass}
459
+ | ${Option (e.getMessage).getOrElse(" " )}""" .stripMargin
460
+ throw IOException (message, e)
444
461
445
462
446
- private def checkTastyUUID (tastyFile : AbstractFile , tastyBytes : Array [ Byte ] )(using Context ): Unit =
463
+ private def checkTastyUUID ()(using Context ): Unit =
447
464
val classfile =
448
465
val className = tastyFile.name.stripSuffix(" .tasty" )
449
466
tastyFile.resolveSibling(className + " .class" )
450
467
if classfile != null then
451
- val tastyUUID = new TastyHeaderUnpickler ( TastyUnpickler .scala3CompilerConfig, tastyBytes).readHeader()
468
+ val tastyUUID = unpickler.unpickler.header.uuid
452
469
new ClassfileTastyUUIDParser (classfile)(ctx).checkTastyUUID(tastyUUID)
453
470
else
454
471
// This will be the case in any of our tests that compile with `-Youtput-only-tasty`
@@ -460,15 +477,15 @@ class TastyLoader(val tastyFile: AbstractFile) extends SymbolLoader {
460
477
461
478
class SourcefileLoader (val srcfile : AbstractFile ) extends SymbolLoader {
462
479
def description (using Context ): String = " source file " + srcfile.toString
463
- override def sourceFileOrNull : AbstractFile | Null = srcfile
480
+ def compilationUnitInfo : CompilationUnitInfo | Null = CompilationUnitInfo ( srcfile)
464
481
def doComplete (root : SymDenotation )(using Context ): Unit =
465
482
ctx.run.nn.lateCompile(srcfile, typeCheck = ctx.settings.YretainTrees .value)
466
483
}
467
484
468
485
/** A NoCompleter which is also a SymbolLoader. */
469
486
class NoLoader extends SymbolLoader with NoCompleter {
470
487
def description (using Context ): String = " NoLoader"
471
- override def sourceFileOrNull : AbstractFile | Null = null
488
+ def compilationUnitInfo : CompilationUnitInfo | Null = null
472
489
override def complete (root : SymDenotation )(using Context ): Unit =
473
490
super [NoCompleter ].complete(root)
474
491
def doComplete (root : SymDenotation )(using Context ): Unit =
0 commit comments