Skip to content

started adapting backend to dotty symbols, denotations, etc #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 12, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions src/dotty/tools/dotc/Driver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
8 changes: 5 additions & 3 deletions src/dotty/tools/dotc/backend/jvm/BCodeBodyBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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

/*
*
Expand All @@ -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
Expand All @@ -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 ---------------- */
Expand Down
50 changes: 26 additions & 24 deletions src/dotty/tools/dotc/backend/jvm/BCodeHelpers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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}")
Expand Down
12 changes: 8 additions & 4 deletions src/dotty/tools/dotc/backend/jvm/BCodeTypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
}

Expand Down
4 changes: 2 additions & 2 deletions src/dotty/tools/dotc/backend/jvm/GenBCode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -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)
Expand Down
21 changes: 11 additions & 10 deletions src/dotty/tools/dotc/config/Printers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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

}
15 changes: 12 additions & 3 deletions src/dotty/tools/dotc/core/Flags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/dotty/tools/dotc/core/StdNames.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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("<:<")
}

Expand Down