@@ -24,10 +24,9 @@ import ast.desugar
2424
2525import parsing .JavaParsers .OutlineJavaParser
2626import parsing .Parsers .OutlineParser
27- import dotty .tools .tasty .{TastyHeaderUnpickler , UnpickleException , UnpicklerConfig }
27+ import dotty .tools .tasty .{TastyHeaderUnpickler , UnpickleException , UnpicklerConfig , TastyVersion }
2828import dotty .tools .dotc .core .tasty .TastyUnpickler
2929
30-
3130object SymbolLoaders {
3231 import ast .untpd .*
3332
@@ -52,7 +51,7 @@ object SymbolLoaders {
5251 def enterClass (
5352 owner : Symbol , name : PreName , completer : SymbolLoader ,
5453 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 )
5655 enterNew(owner, cls, completer, scope)
5756 }
5857
@@ -64,7 +63,7 @@ object SymbolLoaders {
6463 val module = newModuleSymbol(
6564 owner, name.toTermName.decode, modFlags, clsFlags,
6665 (module, _) => completer.proxy.withDecls(newScope).withSourceModule(module),
67- assocFile = completer.sourceFileOrNull )
66+ compUnitInfo = completer.compilationUnitInfo )
6867 enterNew(owner, module, completer, scope)
6968 enterNew(owner, module.moduleClass, completer, scope)
7069 }
@@ -213,7 +212,7 @@ object SymbolLoaders {
213212 /** Load contents of a package
214213 */
215214 class PackageLoader (_sourceModule : TermSymbol , classPath : ClassPath ) extends SymbolLoader {
216- override def sourceFileOrNull : AbstractFile | Null = null
215+ def compilationUnitInfo : CompilationUnitInfo | Null = null
217216 override def sourceModule (using Context ): TermSymbol = _sourceModule
218217 def description (using Context ): String = " package loader " + sourceModule.fullName
219218
@@ -317,7 +316,7 @@ abstract class SymbolLoader extends LazyType { self =>
317316 /** Load source or class file for `root`, return */
318317 def doComplete (root : SymDenotation )(using Context ): Unit
319318
320- def sourceFileOrNull : AbstractFile | Null
319+ def compilationUnitInfo : CompilationUnitInfo | Null
321320
322321 /** Description of the resource (ClassPath, AbstractFile)
323322 * being processed by this loader
@@ -328,7 +327,7 @@ abstract class SymbolLoader extends LazyType { self =>
328327 * but provides fresh slots for scope/sourceModule/moduleClass
329328 */
330329 def proxy : SymbolLoader = new SymbolLoader {
331- export self .{doComplete , sourceFileOrNull }
330+ export self .{doComplete , compilationUnitInfo }
332331 def description (using Context ): String = s " proxy to ${self.description}"
333332 }
334333
@@ -405,7 +404,8 @@ abstract class SymbolLoader extends LazyType { self =>
405404
406405class ClassfileLoader (val classfile : AbstractFile ) extends SymbolLoader {
407406
408- override def sourceFileOrNull : AbstractFile | Null = classfile
407+ def compilationUnitInfo : CompilationUnitInfo | Null = CompilationUnitInfo (classfile)
408+
409409
410410 def description (using Context ): String = " class file " + classfile.toString
411411
@@ -417,38 +417,55 @@ class ClassfileLoader(val classfile: AbstractFile) extends SymbolLoader {
417417
418418class TastyLoader (val tastyFile : AbstractFile ) extends SymbolLoader {
419419
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+ )
421438
422439 def description (using Context ): String = " TASTy file " + tastyFile.toString
423440
424441 override def doComplete (root : SymDenotation )(using Context ): Unit =
425- try
442+ handleUnpicklingExceptions :
443+ checkTastyUUID()
426444 val (classRoot, moduleRoot) = rootDenots(root.asClass)
427- val tastyBytes = tastyFile.toByteArray
428- val unpickler = new tasty.DottyUnpickler (tastyBytes)
429445 unpickler.enter(roots = Set (classRoot, moduleRoot, moduleRoot.sourceModule))(using ctx.withSource(util.NoSource ))
430446 if mayLoadTreesFromTasty then
431447 classRoot.classSymbol.rootTreeOrProvider = unpickler
432448 moduleRoot.classSymbol.rootTreeOrProvider = unpickler
433- checkTastyUUID(tastyFile, tastyBytes)
449+
450+ private def handleUnpicklingExceptions [T ](thunk : => T ): T =
451+ try thunk
434452 catch case e : RuntimeException =>
435453 val message = e match
436454 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
439457 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)
444461
445462
446- private def checkTastyUUID (tastyFile : AbstractFile , tastyBytes : Array [ Byte ] )(using Context ): Unit =
463+ private def checkTastyUUID ()(using Context ): Unit =
447464 val classfile =
448465 val className = tastyFile.name.stripSuffix(" .tasty" )
449466 tastyFile.resolveSibling(className + " .class" )
450467 if classfile != null then
451- val tastyUUID = new TastyHeaderUnpickler ( TastyUnpickler .scala3CompilerConfig, tastyBytes).readHeader()
468+ val tastyUUID = unpickler.unpickler.header.uuid
452469 new ClassfileTastyUUIDParser (classfile)(ctx).checkTastyUUID(tastyUUID)
453470 else
454471 // 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 {
460477
461478class SourcefileLoader (val srcfile : AbstractFile ) extends SymbolLoader {
462479 def description (using Context ): String = " source file " + srcfile.toString
463- override def sourceFileOrNull : AbstractFile | Null = srcfile
480+ def compilationUnitInfo : CompilationUnitInfo | Null = CompilationUnitInfo ( srcfile)
464481 def doComplete (root : SymDenotation )(using Context ): Unit =
465482 ctx.run.nn.lateCompile(srcfile, typeCheck = ctx.settings.YretainTrees .value)
466483}
467484
468485/** A NoCompleter which is also a SymbolLoader. */
469486class NoLoader extends SymbolLoader with NoCompleter {
470487 def description (using Context ): String = " NoLoader"
471- override def sourceFileOrNull : AbstractFile | Null = null
488+ def compilationUnitInfo : CompilationUnitInfo | Null = null
472489 override def complete (root : SymDenotation )(using Context ): Unit =
473490 super [NoCompleter ].complete(root)
474491 def doComplete (root : SymDenotation )(using Context ): Unit =
0 commit comments