diff --git a/src/dotty/tools/dotc/Driver.scala b/src/dotty/tools/dotc/Driver.scala index 49e93e2204c9..bebc397144ac 100644 --- a/src/dotty/tools/dotc/Driver.scala +++ b/src/dotty/tools/dotc/Driver.scala @@ -29,14 +29,11 @@ abstract class Driver extends DotClass { try { doCompile(newCompiler(), fileNames) } catch { + case ex: FatalError => + ctx.error(ex.getMessage) // signals that we should fail compilation. + ctx.typerState.reporter case ex: Throwable => - ex match { - case ex: FatalError => - ctx.error(ex.getMessage) // signals that we should fail compilation. - ctx.typerState.reporter - case _ => - throw ex // unexpected error, tell the outside world. - } + throw ex // unexpected error, tell the outside world. } } diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala index 13f7d6f18a6e..ef5d23aafd6e 100644 --- a/src/dotty/tools/dotc/ast/Trees.scala +++ b/src/dotty/tools/dotc/ast/Trees.scala @@ -260,7 +260,7 @@ object Trees { case _ => NoType } - /** The denotation referred tno by this tree. + /** The denotation referred to by this tree. * Defined for `DenotingTree`s and `ProxyTree`s, NoDenotation for other * kinds of trees */ diff --git a/src/dotty/tools/dotc/backend/jvm/BCodeBodyBuilder.scala b/src/dotty/tools/dotc/backend/jvm/BCodeBodyBuilder.scala index 257cda03992a..72fe46a22231 100755 --- a/src/dotty/tools/dotc/backend/jvm/BCodeBodyBuilder.scala +++ b/src/dotty/tools/dotc/backend/jvm/BCodeBodyBuilder.scala @@ -18,7 +18,9 @@ import dotc.ast.Trees._ import core.Types.Type import core.StdNames import core.Symbols.{Symbol, NoSymbol} +import core.SymDenotations._ import core.Constants.Constant +import config.Printers.bcknd /* * @@ -33,7 +35,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { /* * Functionality to build the body of ASM MethodNode, except for `synchronized` and `try` expressions. */ - abstract class PlainBodyBuilder(cunit: CompilationUnit, + abstract class PlainBodyBuilder(cunit: CompilationUnit, implicit val ctx: dotc.core.Contexts.Context) extends PlainSkelBuilder(cunit) { import icodes.TestOp @@ -44,8 +46,8 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { * it is the host class; otherwise the symbol's owner. */ def findHostClass(selector: Type, sym: Symbol) = selector member sym.name match { - case NoSymbol => debuglog(s"Rejecting $selector as host class for $sym") ; sym.owner - case _ => selector.typeSymbol + case NoDenotation => bcknd.println(s"Rejecting $selector as host class for $sym") ; sym.owner + case _ => selector.typeSymbol } /* ---------------- helper utils for generating methods and code ---------------- */ diff --git a/src/dotty/tools/dotc/backend/jvm/BCodeHelpers.scala b/src/dotty/tools/dotc/backend/jvm/BCodeHelpers.scala index b81c64928c35..8dc825ae62e4 100755 --- a/src/dotty/tools/dotc/backend/jvm/BCodeHelpers.scala +++ b/src/dotty/tools/dotc/backend/jvm/BCodeHelpers.scala @@ -10,13 +10,16 @@ package backend.jvm import scala.tools.asm import scala.annotation.switch import scala.collection.{ immutable, mutable } -import scala.tools.nsc.io.AbstractFile +import dotty.tools.io.AbstractFile import dotc.ast.Trees._ import dotc.core.StdNames import dotc.core.Types.Type import dotc.core.Symbols.{Symbol, NoSymbol} +import dotc.core.SymDenotations._ +import dotc.core.Flags +import dotc.core.StdNames.{nme, tpnme} /* * Traits encapsulating functionality to convert Scala AST Trees into ASM ClassNodes. @@ -435,37 +438,36 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters { * Tracks (if needed) the inner class given by `t`. * * must-single-thread + * + * TODO(lry): check if `ctx` should be a paramter of the class instead. */ - final def toTypeKind(t: Type): BType = { + final def toTypeKind(t: Type)(implicit ctx: dotc.core.Contexts.Context): BType = { /* Interfaces have to be handled delicately to avoid introducing spurious errors, * but if we treat them all as AnyRef we lose too much information. */ - def newReference(sym0: Symbol): BType = { - assert(!primitiveTypeMap.contains(sym0), "Use primitiveTypeMap instead.") - assert(sym0 != definitions.ArrayClass, "Use arrayOf() instead.") - - if (sym0 == definitions.NullClass) return RT_NULL; - if (sym0 == definitions.NothingClass) return RT_NOTHING; - - val sym = ( - if (!sym0.isPackageClass) sym0 - else sym0.info.member(nme.PACKAGE) match { - case NoSymbol => abort(s"SI-5604: Cannot use package as value: ${sym0.fullName}") - case s => abort(s"SI-5604: found package class where package object expected: $s") + def newReference(sym: Symbol): BType = { + assert(!primitiveTypeMap.contains(sym), "Use primitiveTypeMap instead.") + assert(sym != ctx.definitions.ArrayClass, "Use arrayOf() instead.") + + if (sym == ctx.definitions.NullClass) return RT_NULL; + if (sym == ctx.definitions.NothingClass) return RT_NOTHING; + + if (sym is Flags.PackageClass) { + sym.info.member(nme.PACKAGE) match { + case NoDenotation => throw new FatalError(s"SI-5604: Cannot use package as value: ${sym.fullName}") + case s => throw new FatalError(s"SI-5604: found package class where package object expected: $s") } - ) + } - // Can't call .toInterface (at this phase) or we trip an assertion. - // See PackratParser#grow for a method which fails with an apparent mismatch - // between "object PackratParsers$class" and "trait PackratParsers" - if (sym.isImplClass) { - // pos/spec-List.scala is the sole failure if we don't check for NoSymbol - val traitSym = sym.owner.info.decl(tpnme.interfaceName(sym.name)) - if (traitSym != NoSymbol) { + if (sym is Flags.ImplClass) { + val traitDenot = sym.owner.info.decl(tpnme.interfaceName(sym.name)) + // scalac legacy: the `if` check below should not be needed. + // pos/spec-List.scala is the sole failure if we don't check for NoDenotation + // if (traitDenot != NoDenotation) { // this tracks the inner class in innerClassBufferASM, if needed. - return asmClassType(traitSym) - } + return asmClassType(traitDenot.symbol) + // } } assert(hasInternalName(sym), s"Invoked for a symbol lacking JVM internal name: ${sym.fullName}") diff --git a/src/dotty/tools/dotc/backend/jvm/BCodeTypes.scala b/src/dotty/tools/dotc/backend/jvm/BCodeTypes.scala index 498788a23b73..dcca155b7e54 100755 --- a/src/dotty/tools/dotc/backend/jvm/BCodeTypes.scala +++ b/src/dotty/tools/dotc/backend/jvm/BCodeTypes.scala @@ -14,8 +14,10 @@ import dotc.ast.Trees.Tree import dotc.core.Types.Type import dotc.core.StdNames import dotc.core.Symbols.{Symbol, NoSymbol} +import dotc.core.SymDenotations._ +import dotc.core.Flags -import StdNames.nme +import StdNames.{nme, tpnme} /* * Utilities to mediate between types as represented in Scala ASTs and ASM trees. @@ -378,13 +380,15 @@ abstract class BCodeTypes extends BCodeIdiomatic { * On the other hand, this method does record the inner-class status of the argument, via `buildExemplar()`. * * must-single-thread + * + * TODO(lry) check if ctx should be a class parameter */ - final def exemplar(csym0: Symbol): Tracked = { + final def exemplar(csym0: Symbol)(implicit ctx: dotc.core.Contexts.Context): Tracked = { assert(csym0 != NoSymbol, "NoSymbol can't be tracked") val csym = { - if (csym0.isJavaDefined && csym0.isModuleClass) csym0.linkedClassOfClass - else if (csym0.isModule) csym0.moduleClass + if ((csym0 is Flags.JavaDefined) && (csym0 is Flags.ModuleClass)) csym0.linkedClass + else if (csym0 is Flags.ModuleVal) csym0.moduleClass else csym0 // we track only module-classes and plain-classes } diff --git a/src/dotty/tools/dotc/backend/jvm/GenBCode.scala b/src/dotty/tools/dotc/backend/jvm/GenBCode.scala index e581919fcefc..572ac0ee0da0 100755 --- a/src/dotty/tools/dotc/backend/jvm/GenBCode.scala +++ b/src/dotty/tools/dotc/backend/jvm/GenBCode.scala @@ -50,7 +50,7 @@ import dotc.core.Symbols.{Symbol, NoSymbol} object GenBCode extends BCodeSyncAndTry { final class PlainClassBuilder(cunit: CompilationUnit, - ctx: dotc.core.Contexts.Context) extends SyncAndTryBuilder(cunit) + ctx: dotc.core.Contexts.Context) extends SyncAndTryBuilder(cunit, ctx) class BCodePhase extends dotc.core.Phases.Phase { @@ -64,7 +64,7 @@ object GenBCode extends BCodeSyncAndTry { /* ---------------- q1 ---------------- */ - case class Item1(arrivalPos: Int, cd: ast.Trees.TypeDef, cunit: CompilationUnit) { + case class Item1(arrivalPos: Int, cd: ast.tpd.TypeDef, cunit: CompilationUnit) { def isPoison = { arrivalPos == Int.MaxValue } } private val poison1 = Item1(Int.MaxValue, null, null) diff --git a/src/dotty/tools/dotc/config/Printers.scala b/src/dotty/tools/dotc/config/Printers.scala index 67f05c2e7fff..6cdf7ee61397 100644 --- a/src/dotty/tools/dotc/config/Printers.scala +++ b/src/dotty/tools/dotc/config/Printers.scala @@ -10,16 +10,17 @@ object Printers { override def println(msg: => String): Unit = () } - val default: Printer = new Printer - val core: Printer = noPrinter - val typr: Printer = noPrinter - val constr: Printer = noPrinter - val overload: Printer = noPrinter - val implicits: Printer = noPrinter + val default: Printer = new Printer + val core: Printer = noPrinter + val typr: Printer = noPrinter + val constr: Printer = noPrinter + val overload: Printer = noPrinter + val implicits: Printer = noPrinter val implicitsDetailed: Printer = noPrinter - val subtyping: Printer = noPrinter - val unapp: Printer = noPrinter - val completions = noPrinter - val gadts = noPrinter + val subtyping: Printer = noPrinter + val unapp: Printer = noPrinter + val completions: Printer = noPrinter + val gadts: Printer = noPrinter + val bcknd: Printer = noPrinter } \ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala index d7d30f438966..f30863e305f3 100644 --- a/src/dotty/tools/dotc/core/Flags.scala +++ b/src/dotty/tools/dotc/core/Flags.scala @@ -25,7 +25,9 @@ object Flags { FlagSet(tbits | ((this.bits | that.bits) & ~KINDFLAGS)) } - /** The intersection of this flag set and the given flag set */ + /** The intersection of this flag set and the given flag set + * TODO(lry): check if resulting flag set has a non-empty kind? + */ def & (that: FlagSet) = FlagSet(bits & that.bits) /** The intersection of this flag set with the complement of the given flag set */ @@ -89,7 +91,7 @@ object Flags { /** The lowest non-kind bit set in this flagset */ def firstBit: Int = java.lang.Long.numberOfTrailingZeros(bits & ~KINDFLAGS) - /** The list of non-empty names of flags with given index idx that are set in this FlagSet */ + /** The list of non-empty names of flags with given index idx that are set in this FlagSet */ private def flagString(idx: Int): List[String] = if ((bits & (1L << idx)) == 0) Nil else { @@ -112,6 +114,10 @@ object Flags { /** A class representing flag sets that should be tested * conjunctively. I.e. for a flag conjunction `fc`, * `x is fc` tests whether `x` contains all flags in `fc`. + * + * TODO(lry) cannot be a value class because its erause is the same as `FlagSet`, + * the overloaded `is` would not work. Maybe rename `is` to `isAny` and `isAll`, + * get rid of `FlagConjunction`? Code would also be more explicit. */ case class FlagConjunction(bits: Long) { override def toString = FlagSet(bits).toString @@ -249,7 +255,10 @@ object Flags { final val PackageVal = Package.toTermFlags final val PackageClass = Package.toTypeFlags - /** A case class or its companion object */ + /** A case class or its companion object + * TODO(lry): Is CaseVal set for the companion of a case class? Or for a `case object`? + * Or both? Is CaseClass set for the module class of a `case object`? + */ final val Case = commonFlag(17, "case") final val CaseClass = Case.toTypeFlags final val CaseVal = Case.toTermFlags diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala index e7c04e846503..65815524062f 100644 --- a/src/dotty/tools/dotc/core/StdNames.scala +++ b/src/dotty/tools/dotc/core/StdNames.scala @@ -644,6 +644,9 @@ object StdNames { def higherKindedTraitName(n: Int) = HigherKinded ++ n.toString def higherKindedParamName(n: Int) = HK_PARAM_PREFIX ++ n.toString + def implClassName(name: Name): TypeName = (name ++ IMPL_CLASS_SUFFIX).toTypeName + def interfaceName(implname: Name): TypeName = (implname dropRight IMPL_CLASS_SUFFIX.length).toTypeName + final val Conforms = encode("<:<") }