From 759e518486a442caac9d59c949ea6a3232d2a781 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 27 Nov 2023 09:12:07 +0100 Subject: [PATCH] Add TASTyInfo abstraction This abstraction makes it clearer which fields of the `CompilationUnitInfo` are set when the symbol is loaded from TASTy. It also makes it trivial to add new attributes without the need to change the `CompilationUnitInfo` and possibly the `ClassSymbol` helper methods. --- .../tools/dotc/core/CompilationUnitInfo.scala | 29 +++++-------------- .../dotty/tools/dotc/core/SymbolLoaders.scala | 5 +--- .../src/dotty/tools/dotc/core/Symbols.scala | 21 ++------------ .../src/dotty/tools/dotc/core/TastyInfo.scala | 11 +++++++ .../src/dotty/tools/dotc/typer/Checking.scala | 4 +-- .../src/dotty/tools/dotc/typer/Namer.scala | 8 +---- 6 files changed, 26 insertions(+), 52 deletions(-) create mode 100644 compiler/src/dotty/tools/dotc/core/TastyInfo.scala diff --git a/compiler/src/dotty/tools/dotc/core/CompilationUnitInfo.scala b/compiler/src/dotty/tools/dotc/core/CompilationUnitInfo.scala index 19de54d478d7..d030182a5d7a 100644 --- a/compiler/src/dotty/tools/dotc/core/CompilationUnitInfo.scala +++ b/compiler/src/dotty/tools/dotc/core/CompilationUnitInfo.scala @@ -8,28 +8,15 @@ import dotty.tools.tasty.TastyVersion * @param associatedFile The source or class file from which this class or * the class containing this symbol was generated, * null if not applicable. - * @param tastyVersion The TASTy version (major, minor, experimental) - * @param explicitNulls This compilation unit has explicit nulls enabled? + * @param tastyInfo Information about the TASTy from which this class was loaded. + * None if not loaded from TASTy, */ -class CompilationUnitInfo( - val associatedFile: AbstractFile, - val tastyVersion: Option[TastyVersion], - val explicitNulls: Boolean, - val captureChecked: Boolean, - val withPureFuns: Boolean, -) { - - override def toString(): String = - s"CompilationUnitInfo($associatedFile, $tastyVersion, explicitNulls = $explicitNulls, captureChecked = $captureChecked, withPureFuns = $withPureFuns)" -} +case class CompilationUnitInfo( + associatedFile: AbstractFile, + tastyInfo: Option[TastyInfo], +) object CompilationUnitInfo: - def apply(assocFile: AbstractFile | Null, explicitNulls: Boolean = false, captureChecked: Boolean = false, withPureFuns: Boolean = false): CompilationUnitInfo | Null = + def apply(assocFile: AbstractFile | Null): CompilationUnitInfo | Null = if assocFile == null then null - else new CompilationUnitInfo( - assocFile, - tastyVersion = None, - explicitNulls = explicitNulls, - captureChecked = captureChecked, - withPureFuns = withPureFuns, - ) + else new CompilationUnitInfo(assocFile, tastyInfo = None) diff --git a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala index 3720ba844454..6319956e2a81 100644 --- a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -432,10 +432,7 @@ class TastyLoader(val tastyFile: AbstractFile) extends SymbolLoader { val attributes = unpickler.tastyAttributes new CompilationUnitInfo( tastyFile, - tastyVersion = Some(tastyVersion), - explicitNulls = attributes.explicitNulls, - captureChecked = attributes.captureChecked, - withPureFuns = attributes.withPureFuns, + tastyInfo = Some(TastyInfo(tastyVersion, attributes)), ) def description(using Context): String = "TASTy file " + tastyFile.toString diff --git a/compiler/src/dotty/tools/dotc/core/Symbols.scala b/compiler/src/dotty/tools/dotc/core/Symbols.scala index 8dd3912ae909..fa2dccf75f20 100644 --- a/compiler/src/dotty/tools/dotc/core/Symbols.scala +++ b/compiler/src/dotty/tools/dotc/core/Symbols.scala @@ -282,26 +282,11 @@ object Symbols { def compilationUnitInfo(using Context): CompilationUnitInfo | Null = lastDenot.topLevelClass.compilationUnitInfo - /** The version of TASTy from which the symbol was loaded, None if not applicable. */ - def tastyVersion(using Context): Option[TastyVersion] = + /** The info of the TASTy from which this symbol was loaded, None if not applicable. */ + def tastyInfo(using Context): Option[TastyInfo] = val compUnitInfo = compilationUnitInfo if compUnitInfo == null then None - else compUnitInfo.tastyVersion - - /** If this class has explicit nulls enabled */ - def explicitNulls(using Context): Boolean = - val compUnitInfo = compilationUnitInfo - compUnitInfo != null && compUnitInfo.explicitNulls - - /** If this class is capture checked */ - def captureChecked(using Context): Boolean = - val compUnitInfo = compilationUnitInfo - compUnitInfo != null && compUnitInfo.captureChecked - - /** If this class is uses pure functions */ - def withPureFuns(using Context): Boolean = - val compUnitInfo = compilationUnitInfo - compUnitInfo != null && compUnitInfo.withPureFuns + else compUnitInfo.tastyInfo /** The class file from which this class was generated, null if not applicable. */ final def binaryFile(using Context): AbstractFile | Null = { diff --git a/compiler/src/dotty/tools/dotc/core/TastyInfo.scala b/compiler/src/dotty/tools/dotc/core/TastyInfo.scala new file mode 100644 index 000000000000..0accd69f0adc --- /dev/null +++ b/compiler/src/dotty/tools/dotc/core/TastyInfo.scala @@ -0,0 +1,11 @@ +package dotty.tools.dotc.core + +import dotty.tools.io.AbstractFile +import dotty.tools.tasty.TastyVersion + +/** Information about the TASTy of a class symbol. + * + * @param version The TASTy version (major, minor, experimental) + * @param attributes Attributes of in the TASTy attributes section + */ +case class TastyInfo(version: TastyVersion, attributes: tasty.Attributes) diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 54898329fe0e..2768b7060cc5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -1080,8 +1080,8 @@ trait Checking { tree.op match { case id @ Ident(name: Name) => def methCompiledBeforeDeprecation = - meth.tastyVersion match - case Some(version) => version.major == 28 && version.minor < 4 // compiled before 3.4 + meth.tastyInfo match + case Some(info) => info.version.major == 28 && info.version.minor < 4 // compiled before 3.4 case _ => false // compiled with the current compiler name.toTermName match { case name: SimpleName diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 14b7fda452a8..7735104bc8ee 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -247,16 +247,10 @@ class Namer { typer: Typer => case tree: TypeDef if tree.isClassDef => val flags = checkFlags(tree.mods.flags) val name = checkNoConflict(tree.name, flags.is(Private), tree.span).asTypeName - val compilationUnitInfo = CompilationUnitInfo( - ctx.source.file, - explicitNulls = ctx.explicitNulls, - captureChecked = Feature.ccEnabled, - withPureFuns = Feature.pureFunsEnabled, - ) val cls = createOrRefine[ClassSymbol](tree, name, flags, ctx.owner, cls => adjustIfModule(new ClassCompleter(cls, tree)(ctx), tree), - newClassSymbol(ctx.owner, name, _, _, _, tree.nameSpan, compilationUnitInfo)) + newClassSymbol(ctx.owner, name, _, _, _, tree.nameSpan, CompilationUnitInfo(ctx.source.file))) cls.completer.asInstanceOf[ClassCompleter].init() cls case tree: MemberDef =>